Reading Registry keys and values

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

This topic contains 5 replies, has 6 voices, and was last updated by

 
Participant
2 months, 2 weeks ago.

  • Author
    Posts
  • #163911

    Participant
    Topics: 2
    Replies: 41
    Points: 60
    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: 68
    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: 8
    Replies: 1041
    Points: 3,440
    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: 25
    Replies: 678
    Points: 1,629
    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

    Participant
    Topics: 2
    Replies: 54
    Points: 278
    Helping Hand
    Rank: 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', "").OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Group Policy\History\").GetValue("")

    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: 999
    Points: 1,946
    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.

     

You must be logged in to reply to this topic.