Reading Registry keys and values

Welcome Forums General PowerShell Q&A Reading Registry keys and values

Viewing 5 reply threads
  • Author
    Posts
    • #163911
      Participant
      Topics: 3
      Replies: 43
      Points: 78
      Rank: Member

      I am trying to use PS to find if a server has a particular GPO applied, and retrieve the display name and link values.

      This is the root I am searching:
      Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\

      Under History are a lot of keys in the format of {0ACAF40C-75BDC-47ba-BBC0-BF6DE7C7DA63}
      Under each of these history keys are a key named 0 (zero)
      So it looks like this:
      Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\{0ACAF40C-75BDC-47ba-BBC0-BF6DE7C7DA63}\0
      Under each of these 0 keys are values, I would like to get two values from each of these registry keys, DisplayName and Link in a neat table listing.

      This is the code that works

      $x = ((GET-ITEM -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\*").Name) | % {$_.Split("\")[7]} 
      $x | % {Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\$_\0" -name DisplayName, Link} | Ft -AutoSize
      

      However the output is two lines for each DisplayName and Link value.

      GPOw_Windows_10_PNC_Config
      LDAP://OU=OUc_Workstations,OU=OUc_Computers,DC=pncbank,DC=com

      My questions are
      1) is there a more efficient way to get these values?
      2) How can I get the Link and DisplayName to show up on one line together?

      GPOw_Windows_10_PNC_Config       LDAP://OU=OUc_Workstations,OU=OUc_Computers,DC=pncbank,DC=com

      Every time I think I finally understand how to work with the registry in PS, something like this always comes up. Any ideas or suggestions are welcome. Thanks

    • #164004
      Participant
      Topics: 2
      Replies: 31
      Points: 71
      Rank: Member

      What you have works, and that is important. I took a slightly different take, but it mostly does the same as what you are doing, but in the end, this produces a group of objects you could manipulate further if needed. It may not be useful, but I thought I would throw it out there.

       

      $f = get-childitem -Path ‘HKLM:\software\Microsoft\Windows\CurrentVersion\Group Policy\History\’
      $results = @()
      foreach($key in $f.pschildname){
      $data=Get-ItemPropertyValue-Path “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\$key\0”-Name DisplayName, link
      $results+=[PSCustomObject]@{
      ‘Key’=$key
      ‘DisplayName’=$data[0]
      ‘Link’=$data[1]
      }
      }
      $results
    • #164016
      Senior Moderator
      Topics: 9
      Replies: 1236
      Points: 4,443
      Helping Hand
      Rank: Community Hero

      Do you have access to DC ? there are gpo cmdlets which can do this from that server.

      Get-GPO
      Get-GPInheritance # this will have GP link information
      
    • #164022
      js
      Participant
      Topics: 30
      Replies: 828
      Points: 2,554
      Helping Hand
      Rank: Community Hero

      This will get you somewhere. That other answer by Will Prather needs a space before -Path. You can use convert-path on PSPath to make it look more normal.

      get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\*\0' displayname,link
      
      DisplayName  : Local Group Policy
      Link         : Local
      PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}\0
      PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\{35378EAC-683F-11D2-A89A-00C04FBBCFA2}
      PSChildName  : 0
      PSDrive      : HKLM
      PSProvider   : Microsoft.PowerShell.Core\Registry
      

      For some reason, without -name, get-itemporperty errors with “Specified cast is not valid.”. Wow, the 1Param names all have invalid dword values. I can see it in regedit. I thought only Netbeans made those invalid dwords in the uninstall registry area. Get-itemproperty is not robust in this case. Any script scanning the properties in this area will have a terminating error for get-itemproperty.

      get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\*\0' lParam
      
      get-itemproperty : Specified cast is not valid.
      At line:1 char:1
      + get-itemproperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Gro ...
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : NotSpecified: (:) [Get-ItemProperty], InvalidCastException
          + FullyQualifiedErrorId : System.InvalidCastException,Microsoft.PowerShell.Commands.GetItemPropertyCommand
      
    • #164025
      Senior Moderator
      Topics: 3
      Replies: 123
      Points: 653
      Helping Hand
      Rank: Major Contributor

      Instead of doing the Format-Table after retrieving all of the values, try putting it inside your ForEach-Object statement like this:

      $x | % {Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\History\$_\0" -name DisplayName, Link | Ft -AutoSize}

      Each DisplayName and Link pair should be printed as its own table that way.

      As far as improving the efficiency goes, it seems that having this functionality down to just two lines of code is pretty efficient already. What is it that you think needs improving? does it operate slowly?

      There is another method for getting registry values from a remote system using .NET classes, which looks like this:

      [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', "<computername>").OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Group Policy\History\").GetValue("<value name>")

      I like this because it doesn’t rely on PSRemoting, it only requires that the Remote Registry service is running on the system whose registry you want to query. You can also use this technique to create or edit registry keys. I don’t know if it is actually any more efficient than using the PowerShell commandlets for registry handling.

    • #164034
      Participant
      Topics: 2
      Replies: 1013
      Points: 2,093
      Helping Hand
      Rank: Community Hero

      we all love PowerShell, but it is not always the right tool for the job. well, it can be, but always leverage what is purpose built first.

      Such as RSoP or why not just use the GPO cmdlets and parse the XML for the value vs mining the registry?

      It’s a choice, I know, but just saying.

       

Viewing 5 reply threads
  • The topic ‘Reading Registry keys and values’ is closed to new replies.