Read hundreds of unique registry key to satisfy the Autodesk audit

Hello community,

I hope you can help. I have been tasked to read the hundreds of registry key values to satisfy the Autodesk audit. Of course it is very urgent as the audit is in progress.
We all know this.

The attached is the file we got from the Auditors. The keys have some pattern but they are unique at the same time.
For example.

{
AutoCAD LT 2012
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\ProductName
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\Release
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\SerialNumber
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\AdLM\Type}

As the first attempt using mass find and replace technic I have come up with something like:

{
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property ProductName
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property Release
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property SerialNumber
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\AdLM' | Select-Object -property Type
}

The problem I am facing is. It seem to work if I run it line by line. When executed all of them only the first value is displayed. In console it seems to work though.
Second attached files.

Second chalenge I am facing I can I output all this queries in nice formatted way per client.
With current approach I have one line per property.

Thank you in advance for your ideas how to handle it.
Tomasz

If you’re allowing that whole script block to be displayed at the console, you may run into a quirk with the formatting system where only the first object’s properties are displayed. You can pipe each line to Out-String in order to address this, if console / text output is what you need, and you don’t care about working with the objects any more. This way, what goes to the formatting system is just a collection of strings, and they’ll all be displayed properly.

{
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property ProductName | Out-String
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property Release | Out-String
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409' | Select-Object -Property SerialNumber | Out-String
Get-ItemProperty 'HKLM:Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\AdLM' | Select-Object -property Type | Out-String
}

You could try this, the only manual effort is to copy all paths to the script, or put them in a text file and use Get-Content to read them.

# Define output path:
$OutputPath = "$env:TEMP\AuditReport.csv"

# Create a list of registry values (list from auditors)
$Regpaths = @'
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\ProductName
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\Release
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\SerialNumber
HKEY_LOCAL_MACHINE\Software\Autodesk\AutoCAD LT\R17\ACADLT-A001:409\AdLM\Type
'@ -split "`n"

# Create a hashtable used to translate hive names på PSDrives
$Hives = @{
    HKEY_LOCAL_MACHINE = 'HKLM:'
    HKEY_CURRENT_USER  = 'HKCU:'
}

$Result = $Regpaths | Foreach{
   # User a Regular expression to split hive, path and property in three groups, ignoring any trailing spaces.
    if($_ -match '^(HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER)(.+)\\([^\\]+?)\s*$')
    {
        $Hive = $Hives[$Matches[1]]
        $Path = $Matches[2]
        $Property = $Matches[3]

        # Get ItemProperty and select the correct property
        $Value = Get-ItemProperty -Path (Join-Path $Hive $Path) -ErrorAction SilentlyContinue | 
                Select-Object -ExpandProperty $Property

        # Create a custom object that is written to the pipeline (and stored in $Result)
        [pscustomobject]@{
            Entry        = $_
            Value        = $Value
            ComputerName = $env:COMPUTERNAME
        }
    }
    else
    {
        # Failed to parse property path, returning an object indicating that this registry value wasnt inventoried
        [pscustomobject]@{
            Entry        = $_
            Value        = !!FAILED!!
            ComputerName = $env:COMPUTERNAME
        }
    }
} 

# Export the result to a CSV file
$Result | Export-Csv -Path $OutputPath -NoTypeInformation

Thank you Dave and Simon.
Both solutions work for me ! Likely I will use Simon’s one.
I like how he handled and converted the results in one custom ps object for all entries present per the client.