Verify presence of registry subkey on multiple servers

I’m trying to write a short script that will load a list of remote Windows servers from a csv into a variable and then verify the presence of a registry subkey on each. What I have appears to work except that it returns “Does not Exist” for every server row in the export csv when I’ve visually confirmed the subkey on two of the servers. I think the issue is with how I’m handling the wildcard for the end of the “Source OS” subkey where I have “…\Source OS[*]”. It may be something else I haven’t considered but regardless, any assistance would be appreciated. Script below. (The csv contains one column titled ComputerName with the server names in the column.)

# Import the list of computers from the CSV file

$computers = Import-Csv -Path "C:\Users\<profile>\Documents\Output\webapp.csv"

# Specify the registry subkey to check for

$registrySubKey = 'HKLM:Computer\HKEY_LOCAL_MACHINE\SYSTEM\Setup\Source[*]'

# Create an empty array to store the results

$results = @()

# Loop through each computer in the CSV

foreach ($computer in $computers) {

$computerName = $computer.ComputerName

# Check if the computer is reachable

if (Test-Connection -ComputerName $computerName -Quiet -Count 1) {

# Check if the registry subkey exists on the remote computer

if (Test-Path -Path $registrySubKey) {

$status = "Exists"

} else {

$status = "Not Exists"

}

} else {

$status = "Unreachable"

}

# Create a custom object to store the results

$result = [PSCustomObject]@{

ComputerName = $computerName

RegistrySubKey = $registrySubKey

Status = $status

}

# Add the result to the results array

$results += $result

}

# Export the results to a CSV file

$results | Export-Csv -Path "C:\Users\<profile>\Documents\Output\webapp_os_upgraded.csv" -NoTypeInformation

Natataka2112,
Welcome to the forum. :wave:t3:

hmmmm … where to start? :smirking_face:

There are several issues with your code.

First of all the commenting:
Please only add comments when there’s really something hard to understand. Even someone NOT knowing PowerShell code at all may figure out that Test-Connection -ComputerName $computerName is the # Check if the computer is reachable

Then the formatting:
Adding an empty line after each line of code makes your code very hard to read and not using indentation does the same. I’d recommend using VSCode. There you can use the automatic formatter and it will look something like the code I post here.

It helps following some best practices and guide lines. Here you can read more about:

The Unofficial PowerShell Best Practices and Style Guide

Now your code. You actually got the path for your registry path wrong and you’re not querying remote computers. Instead you query your local computer as many times as you have computernames in your CSV file. :point_up: :wink:

Regardless of that - I don’t have any key with the name Source in it in this path in my registry. So I don’t have an idea what you’re actually looking for. I used the path REGISTRY::HKEY_LOCAL_MACHINE\SYSTEM\Setup\Setup* because I have a key with the name SetupCI. You should adapt the path to what you’re really looking for.

$computerList = Import-Csv -Path 'C:\Users\<profile>\Documents\Output\webapp.csv'
$registrySubKey = 'REGISTRY::HKEY_LOCAL_MACHINE\SYSTEM\Setup\Setup*'

$resultList = 
foreach ($computerName in $computerList.ComputerName) {
    if (Test-Connection -ComputerName $computerName -Quiet -Count 1) {
        [PSCustomObject]@{
            ComputerName   = $computerName
            RegistrySubKey = $registrySubKey
            PathExists     = Invoke-Command -ComputerName $computerName -ScriptBlock { Test-Path -Path $USING:registrySubKey }
        }
    }
    else {
        [PSCustomObject]@{
            ComputerName   = $computerName
            RegistrySubKey = $registrySubKey
            PathExists     = 'n/a' 
        }
    }
}

$resultList | 
    Export-Csv -Path 'C:\Users\<profile>\Documents\Output\webapp_os_upgraded.csv' -NoTypeInformation

Of course as always there’s still a lot of room for improvements but I think it should get you going in the right direction.
Have fun! :+1:

2 Likes

Thanks for replying, Olaf. The critiques you already provided are appreciated. When you upgrade Windows Server 2012 to 2019, for instance, there will be a key named “Source OS()” in ‘REGISTRY::HKEY_LOCAL_MACHINE\SYSTEM\Setup’. I’m trying to verify if the “Source OS{…)” key is present in the \Setup key using a wildcard (because the date and time in parenthesis at the end of “Source OS(..)” will be different on each server. This way I can have a csv containing which of the servers have been upgraded from a previous version of Windows Server and which have not.

Olaf, thank you very much for your help. I will start making use of VScode. I just wanted to let you know that between your recommendation and me finally remembering that PS5 doesn’t work very well with wildcards in registry paths, I was able to get the correct output by running the updated script in PS7. Your assistance is greatly appreciated.

1 Like