Search code examples
windowspowershellregistry

Connect to Remote Registry and report either i) the value ii) offline or iii) access denied


I am trying to connect to the registry of remote servers to check if some applications are installed and export the results to a csv. I need the script to report which servers have the application installed, which servers are online but deny access, and servers that are not on the network.

I have tried various approaches including using a try and catch block and using the exception errors, using a test-connection to identify offline servers, various loops etc. The code below identifies the servers that are offline successfully but reports the applications as not installed on servers I am denied access to even though they are online

$servers = "Server1","Server2","Server3"
$date = get-date
$domain = ([system.environment]::UserDomainName).tolower() 
$i = 0
$report = "App Audit {0} {1:HHmm_dd-MM-yyyy}.csv" -f $domain,$date

# reg path for uninstall of 32 bit version of the various applications
$pk32App1 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\App1"
$pk32App2 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\App2"

# reg path for uninstall of 64 bit version of the various applications
$pk64app1 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\App1"
$pk64app2 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\App2"

foreach ($server in $servers) {
    $i++
    write-host "($i/$($servers.count))`t$server"
    $obj = New-Object PSObject
    $obj1 = New-Object PSObject
    $array = @()
    $array1 = @()
    $app1 = ""
    $app2 = ""
    $error.Clear()

    if (-not (Test-Connection $server -Count 2 -Quiet)){
        $app1 = "Offline"
        $app2 = "Offline"
    } else {

        $reg = [microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$server)
        if (-not ($reg)){
            $app1 = "Access Denied"
            $app1 = "Access Denied"
            $app2 = "Access Denied"
        } 
        else {

            # open subkey for 32 bit version of the various applications
            $regpk32app1 = $reg.OpenSubKey($pk32app1)
            $regpk32app2 = $reg.OpenSubKey($pk32app2) 

            # open subkey for 64 bit version of the various applications
            $regpk64app1 = $reg.OpenSubKey($pk64app1)
            $regpk64app2 = $reg.OpenSubKey($pk64app2) 

            $app1 = $($regpk32app1.GetValue("publisher")) 2>> $null
            $app12 = $($regpk64app1.GetValue("publisher")) 2>> $null
            if ($app1){$app1 = $app1}elseif ($app12){$app1 = $app12}else {$app1 = "Not Installed"} 

            $app21 = $($regpk32app2.GetValue("publisher")) 2>> $null
            $app2 = $($regpk64app2.GetValue("publisher")) 2>> $null
            if ($app21){$app2 = $app21}elseif ($app2){$app2 = $app2}else {$app2 = "Not Installed"}
        }

    }

    $obj | Add-Member -MemberType NoteProperty -Name "Server" -Value $Server
    $obj | Add-Member -MemberType NoteProperty -Name "app1" -Value $app1
    $obj | Add-Member -MemberType NoteProperty -Name "app2" -Value $app2
    $array += $obj

    $array | select Server,app1,app2 | export-csv "$PWD\Output\$report" -NoTypeInformation -Append
} 

Solution

  • Instead of the if (-not ($reg)){ code block, try the below code block:

    $reg.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
    if(-not $?){
        $app1 = "Access Denied"
        $app2 = "Access Denied"
    }
    

    Full code:

    $servers = "Server1", "Server2", "Server3"
    $date = get-date
    $domain = ([system.environment]::UserDomainName).tolower()
    $i = 0
    $report = "App Audit {0} {1:HHmm_dd-MM-yyyy}.csv" -f $domain, $date
    
    # Registry path for uninstall of 32-bit version of the various applications
    $pk32App1 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\App1"
    $pk32App2 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\App2"
    
    # Registry path for uninstall of 64 bit version of the various applications
    $pk64app1 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\App1"
    $pk64app2 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\App2"
    
    foreach ($server in $servers) {
        $i++
        write-host "($i/$($servers.count))`t$server"
        $obj = New-Object PSObject
        $obj1 = New-Object PSObject
        $array = @()
        $array1 = @()
        $app1 = ""
        $app2 = ""
        $error.Clear()
    
        if (-not (Test-Connection $server -Count 2 -Quiet)){
            $app1 = "Offline"
            $app2 = "Offline"
        }
        else {
    
            $reg = [microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine', $server)
            $reg.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
            if(-not $?){
                $app1 = "Access Denied"
                $app2 = "Access Denied"
            }
            else {
    
                # Open subkey for 32-bit version of the various applications
                $regpk32app1 = $reg.OpenSubKey($pk32app1)
                $regpk32app2 = $reg.OpenSubKey($pk32app2)
    
                # Open subkey for 64-bit version of the various applications
                $regpk64app1 = $reg.OpenSubKey($pk64app1)
                $regpk64app2 = $reg.OpenSubKey($pk64app2)
    
                $app1 = $($regpk32app1.GetValue("publisher")) 2>> $null
                $app12 = $($regpk64app1.GetValue("publisher")) 2>> $null
                if ($app1) {
                    $app1 = $app1
                }
                elseif ($app12) {
                    $app1 = $app12}
                else {
                    $app1 = "Not Installed"
                }
    
                $app21 = $($regpk32app2.GetValue("publisher")) 2>> $null
                $app2 = $($regpk64app2.GetValue("publisher")) 2>> $null
                if ($app21) {
                    $app2 = $app21
                }
                elseif ($app2) {
                    $app2 = $app2
                }
                else {
                    $app2 = "Not Installed"
                }
            }
        }
    
        $obj | Add-Member -MemberType NoteProperty -Name "Server" -Value $Server
        $obj | Add-Member -MemberType NoteProperty -Name "app1" -Value $app1
        $obj | Add-Member -MemberType NoteProperty -Name "app2" -Value $app2
        $array += $obj
    
        $array | select Server,app1,app2 | export-csv "$PWD\Output\$report" -NoTypeInformation -Append
    }