Update CustomSettings.ini file remotely!

Got on a discussion this week with someone how to use PowerShell to update an MDT CustomSettings.ini file over the network. Well a *lot* of CS.ini files.. 🙂

My manager is the Global Ops Manager and now he is asking me to find a way to run [update of customsettings.ini] on about 50 servers worldwide so the other MDT admins don’t have to log onto each server just to add one line.

The example given was to update the AdminPassword in CS.ini. I hope this company is following best practices, and disabling the local Administrator account and/or changing the Password once joined to the domain or connected to SCCM.

Anywho, INI files are a tad bit difficult to modify in Powershell because there are no native PowerShell or .NET functions to perform the action. So instead we need to do some ugly Pinvoke calls to the appropriate Win32 API.

-k


<#
.SYNOPSIS
Update CustomSettings.ini file.
.DESCRIPTION
Updates one or more CUstomSettings.ini files with a common value.
Calling powershell.exe instance must have read/write privelages to the share.
.PARAMETER DeployShares
The full path to the share. Can be input from the pipeline
Example:
c:\DeploymentShare
\\localhost\DeploymentShare$
.PARAMETER Section
The section name to update.
.PARAMETER Name
THe name to update
.PARAMETER Value
The value to write
.EXAMPLE
C:\PS> .\Update-INIFiles -DeployShares c:\DeploymentShare -Section Default -Name AdminPassword -value 'P@ssw0rd'
set a new password in an MDT deployment share
.EXAMPLE
C:\PS> "\\localhost\DeploymentShare$" | .\Update-INIFiles -Section Default -Name AdminPassword -value 'P@ssw0rd'
set a new password in an MDT deployment share, get the file from the pipeline.
C:\PS> type .\MyMDTServerList.txt | .\Update-INIFiles -Section Default -Name AdminPassword -value 'P@ssw0rd'
set a new password in an MDT deployment share, get the list of files from a list of servers passed in through the cmdline.
.EXAMPLE
C:\PS> [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null
C:\PS> $NewPassword = [System.Web.Security.Membership]::GeneratePassword(10,2)
C:\PS> "The new password will be: $NewPassword"
The new password will be: F{nK:*[L}H
C:\PS> type .\MyMDTServerList.txt | .\Update-INIFiles -Section Default -Name AdminPassword -value $NewPassword
Generate a new random password with powershell, then update all Cs.ini files from a list of servers passed in through the command line.
.LINK
https://foxdeploy.com/2014/09/04/adding-whatif-support-to-your-scripts-the-right-way-and-how-you-shouldnt-do-it/
#>
[cmdletbinding(SupportsShouldProcess=$true)]
param(
[parameter(Mandatory=$true, ValueFromPipeline=$true)]
$DeployShares,
[parameter(Mandatory=$true)]
[string] $Section,
[parameter(Mandatory=$true)]
[string] $Name,
[parameter(Mandatory=$true)]
[string] $Value
)
begin {
## The signature of the Windows API that retrieves INI settings
$signature = @'
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern bool WritePrivateProfileString(
string lpAppName,
string lpKeyName,
string lpString,
string lpFileName);
[DllImport("Kernel32.dll")]
public static extern uint GetLastError();
'@
## Create a new type that lets us access the Windows API function
$type = Add-Type MemberDefinition $signature Name API Namespace Win32 PassThru
}
process {
foreach ( $DPShare in $DeployShares ) {
if ($pscmdlet.ShouldProcess("$DPShare", "CustomSettings.ini write")){
$result = [Win32.API]::WritePrivateProfileString($Section, $Name, $Value, "$DPShare\control\customsettings.ini")
if ( -not $result ) {
$err = [Win32.API]::GetLastError()
throw ( New-Object ComponentModel.Win32Exception ($err -as [int]) )
}
}
}
}

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s