PowerShell Script to Find Out Patch Installation Status on Remote Computers

3
Patch Installation Status PowerShell Script

Microsoft patch Tuesday for the month of May 2019 brought us with some critical updates one of which highly discussed is CVE-2019-0708 vulnerability. More details on this post about the Patch Installation Status on remote computers.

CVE-2019-0708 | Remote Desktop Services  Remote Code Execution Vulnerability (KB4499175)

OSes Effected by Vulnerability

More details about Patch Installation Status can be found in the following sections of this post. The above mentioned patch was an emergency situation.

NOTE! – Some of SCCM features like Run a Script might not work on Windows 7 or Windows 2008.

KB4499180 (for Windows Server 2008 SP2)
KB4499175 (for Windows Server 2008 R2 x64 SP1)
KB4499175 (for Windows 7 SP1)
KB4500705/KB4500331 (for Windows XP SP3)
KB4500705/KB4500331 (for Windows Server 2003 SP2)

Requirement of PowerShell Script

This particular vulnerability is rated as emergency in many organisations and patching\SCCM teams are busy in deploying the fix for this vulnerability.

It is easy to deploy the fix for this vulnerability as it is direct security only update from Microsoft from the list of May month patches. But, it is little challenging to get the accurate details after patch installation if any system\server is still missing this patch or not.

NOTE! – We can do the patch reporting with SCCM reports but in some cases we might not get exact details with SCCM reports.

Post patch deployment I was also in need to get the report to see if all the servers got the required patch installed or any of the servers are still missing this patch.

Fetching Patch Details via PowerShell Script

In this case PowerShell can able to help us with more accurate details, I wrote a PowerShell script and it worked perfectly to get the details of KB number (KB4499175 or KB4499180) and installed date with computer name from remote server. I have exported these details to excel file to review the results at later point.

In this script I have used win32_quickfixengineering rather than Get-hotfix, get-hotfix will also give us the same results but it has its pro’s and con’s, I have read and tested that Get-hotfix is not working after it finds any not online computer.

NOTE! – Read more about cons of using QuickFixEngineering in the following post. SCCM How to find the list of Software Updates patches installed Via Quick Fix Engineering

Patch Installation Status PowerShell Script

As part of this PowerShell script I have created a PowerShell function get-installedpatch with error handling, this script will check if the computer is pingable if pingable connect to the remote computer to get the patch details, results are getting exported to CSV file, not online and exception computers are recorded in different text files.

NOTE! – There are other methods which you can use to run the PowerShell script using SCCM Run Script method. Or you can use SCCM CMPivot to get the details of Patch Installation Status.

The input is computer name or the file which contains the list of computer names.

SCCM Patch Installation Status with PowerShell Script
Patch Installation Status with PowerShell Script

Download PowerShell Script

Please find the actual code of this script from Github below link https://raw.githubusercontent.com/jampaniharish/OnlineScripts/master/Get-installedPatch.ps1

<#
.Synopsis
   This script will get details of perticular patch installed on remote computer.
.DESCRIPTION
   This script will get details of perticular patch installed on remote computer, in this case I am trying to get recent emergency patch installed on remote computer.
.EXAMPLE
   get-content "C:\temp\Hareesh\Script\Computers.txt" | get-installedpatch
.EXAMPLE
   get-installedpatch -computers computer1,computer2
.INPUTS
   computername
.FUNCTIONALITY
   This cmdlet is useful to check the recent emergency patch (KB4499175 or KB4499180) is installed on remote computer or not.
#>

I have found that this script is bit slow to get these details but I could not find any other better way than this to get these details at this point. I would welcome any suggestions on this.

Resources

3 COMMENTS

  1. Hi Haresh,

    You can try this version and see if its faster:

    list all device names with carriage returns
    tip: use cmtrace log viewer to monitor the csv/txt files

    < # Assumptions: winrm has been enabled on these devices 1. specify output network share path 2. specify failed network share path 3. in 'machines.txt' file -> list all device names with carriage returns
    tip: use cmtrace log viewer to monitor the csv/txt files
    #>

    $output = “C:\Patching\machine_updates.csv”
    $failed = “C:\Patching\machine_failed.txt”
    $machines = “C:\Patching\machines.txt”
    $machines_to_sweep = “C:\Patching\machines2sweep.txt”
    $ErrorActionPreference = ‘SilentlyContinue’
    $dev = 0
    $error.clear()

    Get-Content $machines | ForEach-Object {

    Write-Progress “Collecting update info from: $_”

    Invoke-Command -ComputerName $_ -ScriptBlock {
    Get-WmiObject -Class win32_quickfixengineering
    } | Select-Object -Property PSComputerName,Description,HotFixID,InstalledOn | Export-Csv -Path $output -Append -NoTypeInformation
    $dev++
    $error | Out-File $failed -Append
    }
    # grab the machines that have failed and save them for next run sweep
    [Regex]::Matches($Error, ‘(?<=\[)(.*?)(?=\])' ) | ? {$_ -notlike "*TInput,TOutput*" -and $_ -notlike ")(.*?)(?=\" } | Select -ExpandProperty Value | Out-File $machines_to_sweep# add stats to final csv $totalfailed = (gc $machines_to_sweep).count $totalpassed = $dev - $totalfailed "Total devices: $dev" | Out-File $output -Append "Total devices passed: $totalpassed" | Out-File $output -Append "Total devices failed: $totalfailed" | Out-File $output -AppendLet me know how this works for you! 🙂

    • Thanks Matt for your updated script, your script is little faster than mine when I tested with just few machines that will help, what I liked the most in your script is the way you handled the errors and the way you added the stats to the final CSV.

      I just added the where clause to your script to match my requirement.

      Invoke-Command -ComputerName $_ -ScriptBlock {
      Get-WmiObject -Class win32_quickfixengineering | where {$_.hotfixid -eq “KB4499175” -or $_.hotfixid -eq “KB4499180”}
      }

      I did not create any projects in GitHub that could be the reason you are not able to upload it to GitHub. I am new to GitHub I will find out how can I add you as contributor.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.