Quantcast
Viewing latest article 18
Browse Latest Browse All 78

Updated PowerShell Script to Show Windows Update Settings

Last year in this article, I posted a PowerShell script to display Windows Update settings. I’ve enhanced that script to show two additional values and to optionally list all pending updates.

By default, the script will now list pending updates. Updates considered Optional (e.g. Silverlight, hardware drivers, etc.) are excluded. Listing updates can take 30 seconds or longer, so set the script timeout to 60 or even 120 seconds. If you do not want to list pending updates, simply add a single parameter “0” to suppress that list.

The Results

You can run this script directly in PowerShell, but if you deploy it as a daily Script Check in MAXfocus, you’ll be able to quickly see the Windows Update settings and pending updates on any of your machines. (Tip:  use the Re-run Checks option to re-run the daily checks at any time.) Once deployed through MAXfocus, you’ll see output like this in the dashboard:

Image may be NSFW.
Clik here to view.
Show Windows Updates 1

Scroll down to see the pending updates:

Image may be NSFW.
Clik here to view.
Show Windows Updates 2

Note that the pending updates are actually listed in a three-column table (Severity, Title, MaxDownload size in MB). MAXfocus apparently removes extra white space when copying the output to the dashboard, but you can still read the output pretty easily.

The Script

And here is the script.

<#
.Synopsis
  Print the Microsoft auto-update settings for the local computer
  and optionally list pending updates.

  Copyright (c) 2015 by MCB Systems. All rights reserved.
  Free for personal or commerical use.  May not be sold.
  No warranties.  Use at your own risk.

.Notes 
    Name:       MCB.AutoUpdate.ShowSettings.ps1
    Author:     Mark Berry, MCB Systems
    Created:    10/03/2014
    Last Edit:  03/12/2015

    Adapted from http://fixitscripts.com/problems/windows-update-settings.
    Also see https://technet.microsoft.com/en-us/library/ee692834.aspx#EEAA

http://powershellautomation.blogspot.com/2013/05/list-installed-pending-updates.html

    Changes:
    10/10/2014 - Reformat fixed output to be narrower.
    
    03/12/2015 - Rename script.  
                 Add RebootRequired and NoAutoRebootWithLoggedOnUsers info.
                 Add optional list of pending updates.  This takes 30+ seconds, so allow
                 suppressing by setting new $ShowPendingUpdates param to $false or 0.
#>

param(
  [Parameter(Mandatory = $false,
                    Position = 0,
                    ValueFromPipelineByPropertyName = $true)]
  [Boolean]$ShowPendingUpdates=$true,

  [Parameter(Mandatory = $false,
                    Position = 1,
                    ValueFromPipelineByPropertyName = $true)]
  [String]$LogFile=""
)

[Boolean]$ErrFound = $false

"Computer Name: " + $env:COMPUTERNAME
""
"Microsoft AutoUpdate settings"
# The output below starts with two line breaks, so omit the newline here
Write-Host -NoNewLine ("-----------------------------")

try {
  $objAutoUpdateSettings = (New-Object -ComObject "Microsoft.Update.AutoUpdate").Settings
  $objSysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"
  $objAutoUpdateSettings
  "Reboot required               : " + $objSysInfo.RebootRequired
  
  # NoAutoReboot can apparently only be set by policy, so report that here.
  # Reference: https://technet.microsoft.com/en-us/library/cc720464%28v=ws.10%29.aspx.
  Write-Host -NoNewLine ("NoAutoRebootWithLoggedOnUsers : ")
  try { 
    # If Get-ItemProperty fails, value is not in registry. Do not fail entire script. 
    # "-ErrorAction Stop" forces it to catch even a non-terminating error.
    $output = Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU -Name NoAutoRebootWithLoggedOnUsers -ErrorAction Stop
    switch ($output.NoAutoRebootWithLoggedOnUsers)
    {
      0 {"False (set in registry)"}
      1 {"True (set in registry)"}
    }
  }
  catch { 
    "Unknown (local policy registry value not found)" 
  }

  # Static info on the meaning of various Settings.
  ""
  "NotificationLevel:"
  "1 - Never check for updates"
  "2 - Check for updates but let me choose whether to download and install them"
  "3 - Download updates but let me choose whether to install them"
  "4 - Install updates automatically"
  ""
  "ScheduledInstallationDay"
  "0 - Every day"
  "1-7 - Sunday through Saturday"
  "Note:  On Windows 8/2012 and later, ScheduledInstallationDay and"
  "       ScheduledInstallationTime are only reliable if the values" 
  "       are set through Group Policy."
  ""

  if ($ShowPendingUpdates) {
    "Pending Software Updates"
    "------------------------"

    #Get All Assigned updates in $SearchResult.
    $UpdateSession = New-Object -ComObject Microsoft.Update.Session
    $UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
    # Available search criteria:  https://msdn.microsoft.com/en-us/library/windows/desktop/aa386526%28v=vs.85%29.aspx
    # "BrowseOnly=0" omits updates that are considered "Optional" (e.g. Silverlight, hardware drivers).
    # Include "IsAssigned=1" to only see updates intended for deployment by Automatic Updates:
    #   $SearchResult = $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0 and BrowseOnly=0")
    # Omit "IsAssigned=1" to also see Recommended updates:
    $SearchResult = $UpdateSearcher.Search("IsHidden=0 and IsInstalled=0 and BrowseOnly=0")

    #Extract Results for type of updates that are needed.  For to be arrays so we can .count them.
    [Object[]] $Critical = $SearchResult.updates | where { $_.MsrcSeverity -eq "Critical" }
    [Object[]] $Important = $SearchResult.updates | where { $_.MsrcSeverity -eq "Important" }
    [Object[]] $Moderate = $SearchResult.updates | where { $_.MsrcSeverity -eq "Moderate" }
    [Object[]] $Low = $SearchResult.updates | where { $_.MsrcSeverity -eq "Low" }
    [Object[]] $Unspecified = $SearchResult.updates | where { $_.MsrcSeverity -eq "Unspecified" }
    [Object[]] $Other = $SearchResult.updates | where { $_.MsrcSeverity -eq $null }

    #Write Results
    "Critical    : $($Critical.count)"
    "Important   : $($Important.count)"
    "Moderate    : $($Moderate.count)"
    "Low         : $($Low.count)"
    "Unspecified : $($Unspecified.count)"
    "Other       : $($Other.count)"  
    "Total       : $($SearchResult.updates.count)"
    ""
    "Note:  Updates considered Optional are not counted or listed."
    # "If" statement in Expression:  http://blogs.technet.com/b/josebda/archive/2014/04/19/powershell-tips-for-building-objects-with-custom-properties-and-special-formatting.aspx
    # Formatting number as MB:  https://technet.microsoft.com/en-us/library/ff730948.aspx
    $SearchResult.updates | Sort-Object MsrcSeverity, Title | `
      Format-Table @{Expression={if ($_.MsrcSeverity -eq $null) {"Other"} else {$_.MsrcSeverity} };Label="Severity";width=11}, `
      @{Expression={$_.Title};Label="Title";width=72}, `
      @{Expression={"{0:N1} MB" -f ($_.MaxDownloadSize / 1Mb) };Label="MaxDownload";width=13;align="right"} | `
      Out-String -Width 120

  } else {
    "The ShowPendingUpdates parameter is False, so pending updates not listed."
    ""
  }
  
  "Script execution succeeded"
  $ExitCode = 0
}
catch {
  ""
  $error[0]
  ""
  "Script execution failed"
  $ExitCode = 1001 # Cause script to report failure in GFI dashboard
}

""
"Local Machine Time:  " + (Get-Date -Format G)
"Exit Code: " + $ExitCode
Exit $ExitCode

Viewing latest article 18
Browse Latest Browse All 78

Trending Articles