Scripting. Powershell, VMware, Windows, Active Directory & Exchange. All that kind of stuff…..
RSS icon Email icon Home icon
  • Putting Shay’s Powershell Registry Functions To Use

    Posted on April 7th, 2009 Jonathan Medd No comments

    Recently I needed to check some registry key values on a bunch of servers. There were far too many servers to make this a manual task and in addition if they weren’t what I was expecting then I needed to change them.

    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{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);} 

    Then we specify the list of servers to query. You could either use something like:

    $servers = Get-Content servers.txt

    or 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 CenterConnect-VIServer  vc
    
    # Get a list of all the powered on 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.

    Leave a reply