Shay Levy has very helpfully published a Stand Alone Registry Functions Library which I made use of. It allows you to query and set registry values for things such as DWords, Strings, Binary Values on remote machines very easily. In my case I was particularly interested in some configuration settings for the ICA protocol, HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\ICA-tcp, all of them DWords.
First of all we use Shay's Get-RegDWord function at the top of the script which contains some .NET code to query a remote registry
function Get-RegDWord{Then we specify the list of servers to query. You could either use something like:
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[object]$defaultValue="Your default value"
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$subKey.GetValue($valueName,$defaultValue);
}
$servers = Get-Content servers.txtor in my case they were all virtual servers in VMware so I used a couple of VI Toolkit commands to specify the list
# Connect to Virtual Center
Connect-VIServer vc
# Get a list of all the powered on APP servers
$servers = Get-Folder 'Servers' | Get-VM | Where-Object {$_.Powerstate -eq 'PoweredOn'}
Then we loop through each server, call Shay's Get-RegDWord function for each of the DWords we are interested in and store the results in the $myCOl variable. At the end we export the $myCol variable into a CSV file for handy viewing.
# Create an empty array to store the results in
$myCol = @()
foreach ($server in $servers){
$hive = 'LocalMachine'
$keyname = 'System\CurrentControlSet\Control\Terminal Server\WinStations\ICA-tcp'
# Find MaxIdleTime
$valuename = 'MaxIdleTime'
$MaxIdleTime = Get-RegDWord $server $hive $keyName $valueName
# Find fInheritMaxIdleTime
$valueName = 'fInheritMaxIdleTime'
$fInheritMaxIdleTime = Get-RegDWord $server $hive $keyName $valueName
# Find MaxDisconnectionTime
$valueName = 'MaxDisconnectionTime'
$MaxDisconnectionTime = Get-RegDWord $server $hive $keyName $valueName
# Find fInheritMaxDisconnectionTime
$valueName = 'fInheritMaxDisconnectionTime'
$fInheritMaxDisconnectionTime = Get-RegDWord $server $hive $keyName $valueName
# Add the results to the $MYInfo variable, then $myCol
$MYInfo = "" | select-Object Name,MaxIdleTime,fInheritMaxIdleTime,MaxDisconnectionTime,fInheritMaxDisconnectionTime
$MYInfo.Name = $server
$MYInfo.MaxIdleTime = $MaxIdleTime
$MYInfo.fInheritMaxIdleTime = $fInheritMaxIdleTime
$MYInfo.MaxDisconnectionTime = $MaxDisconnectionTime
$MYInfo.fInheritMaxDisconnectionTime = $fInheritMaxDisconnectionTime
$myCol += $MYInfo
}
# Export the results to a csv file
$myCol | Export-Csv citrixservers.csv -NoTypeInformation
Now that we can view the results I was able to see that I needed to set a lot of these values to something new. Using Shay's Set-RegDWord function it is a pretty straightfoward task to extend the above to do that. First of all add the function to the top of the script.
function Set-RegDWord{
param(
[string]$server = ".",
[string]$hive,
[string]$keyName,
[string]$valueName,
[double]$value
)
$hives = [enum]::getnames([Microsoft.Win32.RegistryHive])
if($hives -notcontains $hive){
write-error "Invalid hive value";
return;
}
$regHive = [Microsoft.Win32.RegistryHive]$hive;
$regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($regHive,$server);
$subKey = $regKey.OpenSubKey($keyName,$true);
if(!$subKey){
write-error "The specified registry key does not exist.";
return;
}
$subKey.SetValue($valueName, $value,[Microsoft.Win32.RegistryValueKind]::DWord);
if($?) {$true} else {$false}
}
Then for each of the values you want to change use an if statement to check whether it needs changing and if so call Shay's Set-RegDword to make the necessary changes.
# Find fInheritMaxIdleTime
$valueName = 'fInheritMaxIdleTime'
$fInheritMaxIdleTime = Get-RegDWord $server $hive $keyName $valueName
# Check the value and change if necessary
if ($fInheritMaxIdleTime -eq 1){
$value = '0'
Set-RegDWord $server $hive $keyName $valueName $value
}
Thanks again to Shay for publishing these functions, it made this particular task very easy to complete and I'm sure I'll be using them again in the future.
2 comments:
Hi Jonathan.
I've referenced your page for serveral helpful things, but I'm currrently stuck.
The value I need to query in the registry is the (default) value of a key, yet I cannot get a return.
the GetValueNames displays only a carriage return.
Anyhelp would be excellent!
Have you tried the Get-RegDefault function over on Shay's blog?
http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/2007/10/30/stand-alone-registry-functions-library.aspx
Post a Comment