Script for windws server validation post patching

Avinash Kumar 1 Reputation point

Hi All,

I have a requirement to validate the windows servers post patching. it is basically customized requirement to verify the following components post patching (only windows servers)

1)Last windows patch installation date and status of patch (Filed, installed ..etc)
2)Server pending reboot because of patching
3)Server reboot timing
4)All automatic service status.

It would be great help if anyone can share their idea. Close to this requirement will be also fine.

Windows Server
Windows Server
A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.
9,538 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Dave Patrick 354.1K Reputation points MVP

    1, 2 you may be able to get from WSUS. 3, 4 you could possibly query the system event log.

    --please don't forget to upvote and Accept as answer if the reply is helpful--

    0 comments No comments

  2. MotoX80 25,676 Reputation points

    Years ago I built a status report tool using VB script and HTA's. (Powershell had not been born yet.) We enhanced/tweaked it over time and ultimately build an HTML report that was emailed to the entire team.

    I hacked together some scripts that I had laying around and mostly replicated that in Powershell. This assumes that you have an Active Directory environment and the account running the script has admin access to the servers. It requires that you have set up WinRM on each machine and Invoke-Command works. (Winrm quickconfig)

    This should give you a starting point that you can build on to customize for your environment. Adding in code to report on disk space usage would be a good next step.

    # ShowStatus.ps1 courtesy of MotoX80.   
    $servers = @("win10home","test10")       # or use get-content to read a list of names from a file.   
    $Results = @()  
    Get-Job | Remove-job               # clear out jobs for when testing in ISE   
    $script =   
        # This code runs on each server to analyze it's health.   
        "<tr bgcolor=lightgreen><td>--------  {0}  ----------</td></tr>" -f $env:COMPUTERNAME   
        "<tr><td>Last boot: {0}</td></tr>" -f (Get-CimInstance win32_operatingsystem).LastBootUpTime   
        "<tr><td>Services not running.<pre>"  
        get-service | where-object -property Status -eq  Stopped | where-object -property StartType -eq  Automatic | Format-Table -Property Name, DisplayName  
        $wur = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"  
        if ($wur) {  
            "<tr><td>Windows update requires a reboot.</td></tr>"           
        } else {  
            "<tr><td>Windows update does not require a reboot.</td></tr>"  
        # This does not detect optional updates.   
        $objSession = new-object -comobject "Microsoft.Update.Session"  
        $objSearcher = $objSession.CreateUpdateSearcher()  
        $objResults = $objSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0 and Type='Software'")    
        $colUpdates = $objResults.Updates  
        "<tr><td>There are {0} updates that need installed.</td></tr>" -f $colUpdates.Count  
    # Launch the script for all machines using PS's job functionality  
    $Results += '<html><body><h3>Server Status Report</h3><table  style="font-family:Verdana">'  
    foreach ($computer in $servers) {  
        While($true) {  
            if ((Get-Job -State 'Running').Count -ge 5) {     # number of concurrent jobs to run  
                "Max concurrent job limit reached."    
                Start-Sleep -Seconds 10                       # don't overload this machine   
            } else {  
        Invoke-Command -ComputerName $computer  -ScriptBlock $script -AsJob   
    # Now wait until all jobs have stopped running.  
    $limit = 0  
    While($true) {  
        if ((Get-Job -State 'Running').Count -ne 0) {  
            Start-Sleep -Seconds 30                     # wait a bit   
            if ($limit -gt 10) {                        # they should finish within 5 minutes   
                Get-Job -State 'Running' | foreach {  
                     $Results += "<tr><td bgcolor=red>{0} appears to be hung.." -f $_.Location  
                "Time limit exceeded."  
        } else {  
            break           # exit the infinite while statement because no jobs are running.    
    # Read the output from all jobs and add that to the report.   
    $Alljobs = Get-Job  
    foreach ($Job in $Alljobs) {  
        if ($job.State -eq "Failed") {  
            $Results += "<tr><td bgcolor=#eea0e8>{0} is not accessible.</td></tr><tr><td>&nbsp;</td></tr>" -f $job.location  
            "--------- Error for {0} ---------" -f $job.location      
            Receive-Job -Id $job.Id   
        } else {  
            $Results += Receive-Job -Id $job.Id      
    $Results += "</table></body></html>"  
    $Results | out-file C:\temp\results.htm  
    Start-Process  C:\temp\results.htm  
    0 comments No comments