0

I have a problem with my script to check multiple hotfixes on multiple servers. Sometimes I don't have a rpc connection to a server, in this case I want to log this information to the same output file. Can someone please help me? thanks

$computers =  Get-Content -path C:\00-Scripts\printer\server.txt
$Patch = Get-Content -path C:\00-Scripts\printer\kb.txt
  
foreach ($computer in $computers) {
    foreach ($patch1 in $patch) {
        Try {
            if (get-hotfix -id $patch1 -ComputerName $computer -ErrorAction stop) {
                Add-content "$patch1 is Present in $computer" -path C:\00-Scripts\printer\Hotfix.txt
             }
             Else {
                 Add-content "$patch1 is not Present in $computer" -path C:\00-Scripts\printer\Hotfix.txt
             }
         }
         catch {
             Add-content "can not check $computer" -path C:\00-Scripts\printer\Hotfix.txt
         }
     }
}
Otter
  • 1,086
  • 7
  • 18
vespavbb
  • 27
  • 2
  • 9

4 Answers4

0

In this case, you need to first check if the computer can be reached. If so, loop over the patches to report if they can be found or not. In you cannot reach the machine, write just one failure line in the log and proceed with the next computer.

$computers = Get-Content -path 'C:\00-Scripts\printer\server.txt'
$Patch     = Get-Content -path 'C:\00-Scripts\printer\kb.txt'
$logFile   = 'C:\00-Scripts\printer\Hotfix.txt'
foreach ($computer in $computers) {
    if (Test-Connection -ComputerName $computer -Count 1 -Quiet) {
        foreach ($patch1 in $patch) {
            # use -ErrorAction SilentlyContinue here so $hotfix will either become $null or an object
            $hotfix = Get-HotFix -Id $patch1 -ComputerName $computer -ErrorAction SilentlyContinue
            if ($hotfix) {
                "$patch1 is Present in $computer" | Add-Content -Path $logFile
            }
            else {
                "$patch1 is not Present in $computer" | Add-Content -Path $logFile
            }
        }
    }
    else {
        "Can not check $computer" | Add-Content -Path $logFile
    }
}
Theo
  • 57,719
  • 8
  • 24
  • 41
0

With the above answer, script is not scanning the next computer and the results are not getting generated for the rest of computers

for example

Get-HotFix -ComputerName PC1,PC2 -ErrorAction SilentlyContinue

In above command if PC1 is not available or access denied. The command stops wihtout checking PC2 and generating output

Karan
  • 1
  • Please use answer section for answers only. If you wish to point out why another answer might be incorrect, please do so by commenting on that answer instead. This way the original answerers can also see your comment and correct/defend their answer. – aulven Sep 13 '22 at 14:42
0

I tried this solution for myself and it is slightly flawed. My goal was to prevent the big error message from showing up on the screen. But the option to use the Get-Hotfix will always come back with an error message even if you say silently continue for the error action. At least it does for me. Specifically when trying to connect. If the OS is found but the patch is not there then the silently continue works as expected. Instead I had a previously done a check for the OS and that always comes back with the value or null. Additional the method above using $hotfix will only work once, since the value is not removed if the check fails. I proved this with using Write-Host $hotfix This is my solution that uses a different value

$computers = Get-Content -path 'C:\00-Scripts\printer\server.txt'
$patch     = Get-Content -path 'C:\00-Scripts\printer\kb.txt'
$logFile   = 'C:\00-Scripts\printer\Hotfix.txt'
foreach ($computer in $computers) {
$ver = (Get-WmiObject -ComputerName $computer -class win32_OperatingSystem -ErrorAction SilentlyContinue).caption
if ($ver -ne $null) {
    foreach ($patch1 in $patch) {
        # use -ErrorAction SilentlyContinue here so $hotfix will either become $null or an object
        if (Get-HotFix -Id $patch1 -ComputerName $computer -ErrorAction SilentlyContinue) {
            "$patch1 is Present in $computer" | Add-Content -Path $logFile
        }
        else {
            "$patch1 is not Present in $computer" | Add-Content -Path $logFile
        }
    }
}
else {
    "Can not check $computer" | Add-Content -Path $logFile
}
}
0

I tried this solution for myself and it is slightly flawed. My goal was to prevent the big error message from showing up on the screen. But the option to use the Get-Hotfix will always come back with an error message even if you say silently continue for the error action. At least it does for me. Specifically when trying to connect. If the OS is found but the patch is not there then the silently continue works as expected. Instead I had a previously done a check for the OS and that always comes back with the value or null. Additional the method above using $hotfix will only work once, since the value is not removed if the check fails. I proved this with using Write-Host $hotfix This is my solution that uses a different value

$computers = Get-Content -path 'C:\00-Scripts\printer\server.txt'
$patch     = Get-Content -path 'C:\00-Scripts\printer\kb.txt'
$logFile   = 'C:\00-Scripts\printer\Hotfix.txt'
foreach ($computer in $computers) {
$ver = (Get-WmiObject -ComputerName $computer -class win32_OperatingSystem -ErrorAction SilentlyContinue).caption
if ($ver -ne $null) {
    foreach ($patch1 in $patch) {
        # use -ErrorAction SilentlyContinue here so $hotfix will either become $null or an object
        if (Get-HotFix -Id $patch1 -ComputerName $computer -ErrorAction SilentlyContinue) {
            "$patch1 is Present in $computer" | Add-Content -Path $logFile
        }
        else {
            "$patch1 is not Present in $computer" | Add-Content -Path $logFile
        }
    }
}
else {
    "Can not check $computer" | Add-Content -Path $logFile
}
}