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. If you want to list pending updates, including updates considered Optional, add a $true parameter.

Update 12 November 2015

The script now lists hidden updates as well as updates that are waiting to be installed.

Update 4 August 2016

  • The script now defaults to $false, i.e. it will not list pending updates unless you run it with $true. This allows it to complete very quickly by default.
  • If the machine is configured to gets updates from and report status to WSUS, the relevant servers are listed.
  • Windows 8/8.1/2012/2012R2 machines show task trigger information for the Regular Maintenance task (during which updates are installed).
  • If you choose to list pending updates (run with $true), the full Title will now be shown, and UpdateID and RevisionNumber are included. This means each row can be up to 200 characters long. For best results, stretch your PowerShell window to make it wide enough.

Update 26 February 2018

Retrieve and display all WindowsUpdate registry values to cover Windows 10 as well.

The Results

You can run this script directly in PowerShell, but if you deploy it as a Daily Script Check in MaxRM, 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.)

Note Listing updates can take 30 seconds or longer, so if you are running this from MaxRM, set the script timeout to 60 or even 120 seconds. On slow machines, you may have to run it as a scheduled task rather than as a DSC check.

Once deployed through MaxRM, you’ll see output like this in the dashboard:

Show Windows Updates 1

If you ran the script with a $true parameter, scroll down to see the pending updates:

Show Windows Updates 2

Note that the pending updates are actually listed in a multi-column table (Severity, Title, etc.). MaxRM 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) 2018 by MCB Systems. All rights reserved.
  Free for personal or commercial use.  May not be sold.
  No warranties.  Use at your own risk.

.Notes 
    Name:       MCB.WindowsUpdate.ShowSettings.ps1
    Author:     Mark Berry, MCB Systems
    Created:    10/03/2014
    Last Edit:  02/26/2018

    Adapted from http://fixitscripts.com/problems/windows-update-settings.
    Also see https://technet.microsoft.com/en-us/library/ee692834.aspx
             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.
                 
    04/08/2015 - When listing updates, include optional updates (remove "BrowseOnly=0" criterion).
                 Add BrowseOnly and IsDownloaded columns to update list. 
                 
                 Note that Windows Defender updates include bundled updates for the base engine etc.
                 so total size will be 400MB+.  Most of the "sub-updates" show IsInstalled=True but 
                 are still included in total size.  Getting true size would require looping through 
                 bundled updates, which I won't try to do now.
                 
    04/17/2015 - Edit note about optional updates.  Add note about Microsoft anti-virus update size.           

    11/12/2015 - Also list hidden updates if ShowPendingUpdates = $true.    
    
    02/17/2016 - Change default for $ShowPendingUpdates to $false. This lets script execute quickly
                 when run with no params.
               - For Windows 8/8.1/2012/2012R2, show start trigger of the Regular Maintenance task,
                 which controls when updates are installed.  No longer used in Windows 10.
                 
    08/04/2016 - When displaying pending updates, use Format-Table -AutoSize to show entire Title.
                 Add a column for UpdateID with RevisionNumber.
                 Output may now be up to 200 characters wide--you may want to copy to a text 
                 editor without line wrapping.
                 
    08/04/2016 - If the machine is configured to get updates from WSUS, identify the WUServer and 
                 WUStatusServer.  Otherwise indicated that WSUS is not configured.
								 
    02/26/2018 - Retrieve and display all WindowsUpdate registy values to cover Windows 10 as well.
#>

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

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

[Boolean]$ErrFound = $false

function ListRegKeyValues {
  param(
    [Parameter(Mandatory=$true)]
    [string]$path)

	"Hive: $path`n"
		
  $RegKey = (Get-ItemProperty $path)
  $RegKey.PSObject.Properties | ForEach-Object {
	  $Name = $_.Name
		$Value = $_.Value
	  switch ($Name) {
		  # Don't print the PowerShell properties that are apparently present in every PSObject
		  "PSPath" { break }
			"PSParentPath" { break }
			"PSChildName" { break }
			"PSDrive" { break }
			"PSProvider" { break }
			default { Write-Host $Name ': ' $Value }
    }
  }	
}
	
"Computer Name: " + $env:COMPUTERNAME
""
"Microsoft AutoUpdate settings (from the Microsoft.Update COM object)"
"--------------------------------------------------------------------"

try {
  $objAutoUpdateSettings = (New-Object -ComObject "Microsoft.Update.AutoUpdate").Settings
  $objSysInfo = New-Object -ComObject "Microsoft.Update.SystemInfo"
	# See https://stackoverflow.com/a/32253197/550712 for the Out-String.Trim() trick to trim blank lines
  ($objAutoUpdateSettings | Out-String).Trim()
  "Reboot required           : " + $objSysInfo.RebootRequired
  ""
  "Registry values (set by Group Policy or manually)"
  Write-Host -NoNewLine ("-------------------------------------------------`n")
	$path = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"
	ListRegKeyValues $path
  ""
	$path = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU"
	ListRegKeyValues $path
	
  # WSUS server info, if available
  # Reference: https://technet.microsoft.com/en-us/library/dd939844(v=ws.10).aspx
  ""
  Write-Host -NoNewLine ("WSUS Server               : ")
  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 -Name WUServer -ErrorAction Stop
    $output.WUServer
  }
  catch { 
    "WSUS not configured. The machine must be contacting Windows Update directly." 
  }
  Write-Host -NoNewLine ("WSUS Status Server        : ")
  try { 
    $output = Get-ItemProperty -Path HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate -Name WUStatusServer -ErrorAction Stop
    $output.WUStatusServer
  }
  catch { 
    "WSUS not configured. The machine must be contacting Windows Update directly." 
  }

  # Static info on the meaning of various Settings.
  ""
  "Key to Notification Values"
  "--------------------------"
  "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"
  ""
  "For Windows 10, you should also see 'ScheduledInstallEveryWeek = 1 and/or ScheduledInstallFirstWeek = 1, etc."
  ""

# For Windows 8 and later, show start trigger of the Regular Maintenance task
  
# Per http://stackoverflow.com/a/26003354/550712 .NET OS Version is inaccurate on an 
# upgraded Windows 8.1 machine, so use Get-CimInstance if available, else fall back to .NET.
# Cast as [Version] to allow accurate comparisons even when Version.Major is two digits (Windows 10).
[Version]$OSVersion = $null
try {
  $OSVersion = (Get-CimInstance Win32_OperatingSystem).Version
}
catch {
  # Get-CimInstance requires PowerShell 3. Fall back to .NET if Get-CimInstance doesn't work.
  $OSVersion = [System.Environment]::OSVersion.Version
}

# List of Windows versions:  http://www.robvanderwoude.com/ver.php
if ( ($OSVersion -ge [Version]"6.2.9200") ) {
  "Windows 8 and Later Scheduled Maintenance, If Any"
  "-------------------------------------------------"
  try {
    """\Microsoft\Windows\TaskScheduler\Regular Maintenance"" task trigger:"
    $task = Get-ScheduledTask -TaskName "Regular Maintenance" -TaskPath "\Microsoft\Windows\TaskScheduler\" -ErrorAction Stop
    $task.Triggers    
  }
  catch { 
    "Error:  Could not retrieve \Microsoft\Windows\TaskScheduler\Regular Maintenance task"
    ""
  }

# To change, use 
# $TaskTime = New-ScheduledTaskTrigger -At 12:00 -Daily  
# Set-ScheduledTask -TaskName "Regular Maintenance" -TaskPath "\Microsoft\Windows\TaskScheduler\" -Trigger $TaskTime -ErrorAction Stop
}

"Pending Software Updates including Hidden Updates"
"-------------------------------------------------"
  if ($ShowPendingUpdates) {
    #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).
    # As of 4/8/2015, omit "BrowseOnly=0" so we'll see all available updates.
    # Include "IsAssigned=1" to only see updates intended for deployment by Automatic Updates:
    #   $SearchResult = $UpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0")
    # Omit "IsAssigned=1" to also see Recommended updates:
    $SearchResult = $UpdateSearcher.Search("IsInstalled=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)"
    ""
    "Notes:  ""BrowseOnly"" updates are considered optional."
    "         Microsoft anti-virus updates include sub-updates"
    "         that are already installed, so size is inaccurate."
    # "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
    # Available update properties (IUpdate interface):  https://msdn.microsoft.com/en-us/library/windows/desktop/aa386099(v=vs.85).aspx
    # Use Out-String to keep AutoSize from truncating columns based on screen size:
    #   https://poshoholic.com/2010/11/11/powershell-quick-tip-creating-wide-tables-with-powershell/
    
    ""
    "Ready to Install"
    "----------------"
    $NotHiddenUpdates = $SearchResult.updates | Where-Object {$_.IsHidden -eq $false}
    If ($NotHiddenUpdates -eq $null) { 
      "None" 
    } else {
      $NotHiddenUpdates | Sort-Object MsrcSeverity, Title | `
        Format-Table -AutoSize @{Expression={if ($_.MsrcSeverity -eq $null) {"Other"} else {$_.MsrcSeverity} };Label="Severity"}, `
        @{Expression={$_.Title};Label="Title"}, `
        @{Expression={"{" + $_.Identity.UpdateID + "}." + $_.Identity.RevisionNumber};Label="UpdateID and RevisionNumber"}, `
        @{Expression={$_.BrowseOnly};Label="BrowseOnly"}, `
        @{Expression={$_.IsDownloaded};Label="IsDownloaded"}, `
        @{Expression={"{0:N1} MB" -f ($_.MaxDownloadSize / 1MB) };Label="MaxDownload";align="right"} | `
        Out-String -Width 200 
    }
    ""
    "Hidden Updates"
    "--------------"
    $HiddenUpdates = $SearchResult.updates | Where-Object {$_.IsHidden -eq $true}
    If ($HiddenUpdates -eq $null) { 
      "None" 
    } else {
      $HiddenUpdates | Sort-Object MsrcSeverity, Title | `
        Format-Table -AutoSize @{Expression={if ($_.MsrcSeverity -eq $null) {"Other"} else {$_.MsrcSeverity} };Label="Severity"}, `
        @{Expression={$_.Title};Label="Title"}, `
        @{Expression={"{" + $_.Identity.UpdateID + "}." + $_.Identity.RevisionNumber};Label="UpdateID and RevisionNumber"}, `
        @{Expression={$_.BrowseOnly};Label="BrowseOnly"}, `
        @{Expression={$_.IsDownloaded};Label="IsDownloaded"}, `
        @{Expression={"{0:N1} MB" -f ($_.MaxDownloadSize / 1MB) };Label="MaxDownload";align="right"} | `
        Out-String -Width 200
    }
  } else {
    "The ShowPendingUpdates parameter is `$false, so pending updates not listed."
    ""
  } # if $ShowPendingUpdates
	
  "Script execution succeeded"
  $ExitCode = 0
} # try
catch {
  ""
  $error[0]
  ""
  "Script execution failed"
  $ExitCode = 1001 # Cause script to report failure in MaxFocus RM dashboard
}

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

11 thoughts on “Updated PowerShell Script to Show Windows Update Settings

  1. Pingback: PowerShell Script to Change Windows Update Settings | MCB Systems

  2. Pingback: Print Detailed Windows Update Information | MCB Systems

  3. Brachus

    This does not work correctly for any domain joined machines. It does not show any of the GPO based settings.

  4. Mark Berry Post author

    Brachus, thanks for the feedback. What OS are you using? The results should be accurate if not complete for domain machines. For example, if your GPO sets Windows Update to “2 – Notify…”, you should see that in this script, but you won’t see that the user is blocked from changing that setting. What exactly where you hoping to see?

  5. david

    how to you run this for a list of computers,
    I keep getting pipeline failures.

  6. Mark Berry Post author

    David, the script only shows information about the machine where it is run. I use a monitoring tool to deploy it on multiple machines.

  7. Pingback: Windows 10 Does Not Show or Install Optional Updates | MCB Systems

  8. Andres Correa

    Hi Mark!

    Your script reference a $LogFile parameter, but that is not really used.
    Do you have a version that includes its usage?
    It would be very usefull.

    Thanks in advance for your attention.

  9. Mark Berry Post author

    Andres – you’re right, I don’t use the $LogFile parameter.. That parameter is only used when the script is deployed and called from MaxRM. Per https://dashboard.systemmonitor.us/dashboard/helpcontents/script_guide_parse.htm, “When the Agent runs the script two arguments are always appended to the command line (for debug) and the -logfile logname can be ignored.” Put another way, if you DON’T have the $LogFile param and you call it from MaxRM, it will pass the unexpected param and the script will fail.

  10. Bruce E. Kriebel

    Mark,

    Nice piece of code. I did a little work on it to fit it to my needs to output a single string to return to another program. I thought you might find some of the changes useful.

    -------- Code  --------
    Function WinUpdSettings {
    
    
    
      
      param(
        [Parameter(Mandatory = $false,
                          Position = 0,
                          ValueFromPipelineByPropertyName = $true)]
        [Boolean]$ShowPendingUpdates=$True
      )
      
      function ListRegKeyValues {
        param(
          [Parameter(Mandatory=$true)]
          [string]$path)
      
        $RegStr = "Hive: $path`n" 
      		
        $RegKey = (Get-ItemProperty $path)
        $RegKey.PSObject.Properties | ForEach-Object {
      	  $Name = $_.Name
      		$Value = $_.Value
      	  switch ($Name) {
      		  # Don't print the PowerShell properties that are 
                # apparently present in every PSObject
      		    "PSPath"       { break }
      			"PSParentPath" { break }
      			"PSChildName"  { break }
      			"PSDrive"      { break }
      			"PSProvider"   { break }
      			default {$RegStr +=  "$Name :  $Value"}
          }
        }	
      
        "$RegStr"
      
      }  #End Function ListRegKeyValues
      
      #---------------   Main Program -------------------
      
      Clear-Host	
      
      [Boolean]$ErrFound = $false
      
      $TStr = @"
    Computer Name: $env:COMPUTERNAME
      
    Microsoft AutoUpdate settings (from the Microsoft.Update COM object)
    --------------------------------------------------------------------
    "@ | Out-String
      
      Try {
        $objAutoUpdateSettings = 
        (New-Object -ComObject "Microsoft.Update.AutoUpdate").Settings
        $objSysInfo = 
          New-Object -ComObject "Microsoft.Update.SystemInfo"
      
      	# See https://stackoverflow.com/a/32253197/550712 for the 
          # Out-String.Trim() trick to trim blank lines
         $TStr += ($objAutoUpdateSettings | Out-String).Trim()
         $TStr += "`nReboot required           : " +
                  "$($objSysInfo.RebootRequired)" | Out-String
      
          $path1 = "HKLM:\Software\Policies\Microsoft\Windows" +
                   "\WindowsUpdate"
          $Key1  =  ListRegKeyValues "$path1"
          $Key2  =  ListRegKeyValues "$path1\AU"
      
      $TStr += @"
      
    Registry values (set by Group Policy or manually)
    -------------------------------------------------
    $key1
      
    $Key2
      
    "@ | Out-String
      	
      
      
        $Title = "WSUS Server       : "
      
        Try { 
          
      
          $GIPArgs = @{Path        = "HKLM:\Software\Policies\" + 
                                     "Microsoft\Windows\WindowsUpdate"
                       Name        = "WUServer" 
                       ErrorAction = "Stop"}
          $output = Get-ItemProperty @GIPArgs
      
          $WsusStr = "$Title" + $output.WUServer
        }
        Catch { 
          $WsusStr ="$Title" + 
          "WSUS not configured.`n`t`t`t`t`tThe machine" +
          " must be contacting `n`t`t`t`t`tWindows Update directly." 
        }
      
        $Title ="`n`nWSUS Status Server: "
      
        Try { 
          $GIPArgs = @{Path        = "HKLM:\Software\Policies\" +
                                     "Microsoft\Windows\WindowsUpdate"
                       Name        = "WUStatusServer" 
                       ErrorAction = "Stop"}
          $output = Get-ItemProperty @GIPArgs
          $WsusStr += "$Title" + $output.WUStatusServer
        }
        Catch { 
          $WsusStr += "$Title" + 
          "WSUS not configured.`n`t`t`t`t`tThe machine " +
          "must be contacting `n`t`t`t`t`tWindows Update directly." 
        }
      
        $TStr += $WsusStr | Out-String
      
        # Static info on the meaning of various Settings.
      $TStr += @"
        
        Key to NotIfication Values
        --------------------------
        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
        
        For Windows 10, you should also see: 
           ScheduledInstallEveryWeek = 1 and/or 
           ScheduledInstallFirstWeek = 1, etc.
        
    "@ | Out-String
      
      
      
      [Version]$OSVersion = $null
      
      Try {
        $OSVersion = (Get-CimInstance Win32_OperatingSystem).Version
      }
      Catch {
        # Get-CimInstance requires PowerShell 3. 
        # Fall back to .NET If Get-CimInstance doesn't work.
      
        $OSVersion = [System.Environment]::OSVersion.Version
      }
      
      # List of Windows versions:  http://www.robvanderwoude.com/ver.php
      
      If ( ($OSVersion -ge [Version]"6.2.9200") ) {
      
      $TStr += @"  
    Windows 8 and Later Scheduled Maintenance, If Any
    -------------------------------------------------
    \Microsoft\Windows\TaskScheduler\Regular Maintenance task trigger:
    "@ | Out-String
      
        Try {
          $GSTArgs - @{TaskName = "Regular Maintenance" 
                       TaskPath = "\Microsoft\Windows\TaskScheduler\" 
                       ErrorAction =  "Stop"}
          $task = Get-ScheduledTask 
          $TStr =+ $task.Triggers  | Out-String 
        }
      
        Catch { 
          $TStr += "Error: Could not retrieve`n`t`t\Microsoft\" +
                   "\Windows\TaskSchedulerRegular Maintenance task`n"
        }
      
      # To change, use 
      # $TaskTime = New-ScheduledTaskTrigger -At 12:00 -Daily  
      # Set-ScheduledTask -TaskName "Regular Maintenance" -TaskPath "\Microsoft\Windows\TaskScheduler\" -Trigger $TaskTime -ErrorAction Stop
      
      } #End If( $OSVersion
      
      $TStr += @"
      
    Pending Software Updates including Hidden Updates
    -------------------------------------------------
    "@ | Out-String
      
        If ($ShowPendingUpdates) {
          #Get All Assigned updates in $SearchResult.
          $UpdateSession  = 
                New-Object  -ComObject Microsoft.Update.Session
          $UpdateSearcher = $UpdateSession.CreateUpdateSearcher()
          $SearchResult   = $UpdateSearcher.Search("IsInstalled=0")
      
      
          $Sev = "Critical","Important","Moderate","Low",
                 "Unspecified",$null
          $a   = $null,$null,$null,$null,$null,$null
      
          For ($cnt = 0; $cnt -lt $Sev.Count; $cnt++) {
      
             [Object[]] $a[$cnt] = $SearchResult.updates | 
                     Where { $_.MsrcSeverity -eq $($Sev[$cnt]) }
             
          } #End For ($cnt...
      
          #Write Results
          $updTotal = 0
          #Fix $Sev $Null Severity to Other for output!
          $Sev[$Sev.Count -1] = "Other"
      
          For ($cnt = 0; $cnt -lt $Sev.Count; $cnt++) {
             If ($Null -ne $a[$cnt]) {
               $TStr += "{0,-11} : {1,2}" -f 
                        $($Sev[$cnt]),$($a[$cnt].count) | Out-String
               $UpdTotal += $a[$cnt].count
             }
             Else {$TStr += "{0,-11} : {1,2}" -f $($Sev[$cnt]),0 |
                   Out-String}
          } 
                         
          $TStr += "{0,-11} : {1,2}" -f "Total",$updTotal  | Out-String
                               
      $TStr += @"
      
      Notes:  BrowseOnly updates are considered optional.
              Microsoft anti-virus updates include sub-updates
              that are already installed, so size is inaccurate.
      
    Ready to Install
    ---------------- 
    "@ | Out-String
      
          # "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
          # Available update properties (IUpdate interface):  https://msdn.microsoft.com/en-us/library/windows/desktop/aa386099(v=vs.85).aspx
          # Use Out-String to keep AutoSize from truncating columns based on screen size:
          #   https://poshoholic.com/2010/11/11/powershell-quick-tip-creating-wide-tables-with-powershell/
      
          $NotHiddenUpdates = $SearchResult.updates | 
              Where-Object {$_.IsHidden -eq $false}
      
          If ($null -eq $NotHiddenUpdates) { 
            $TStr += "None" | Out-String
          } 
          Else {
            $FmtUpdts = 
              @{Expression={If ($_.MsrcSeverity -eq $null) {"Other"} 
                            Else {$_.MsrcSeverity} };
                            Label="`nSeverity";Width=8}, 
              @{Expression={$_.BrowseOnly};Label="Browse`nOnly";
                            Width=6;Align="Left"},
              @{Expression={$_.IsDownloaded};Label="IsDown`nloaded";
                            Width=6;Align="Left"}, 
              @{Expression={"{0:N1} MB" -f ($_.MaxDownloadSize / 1MB) };
                            Label="Max D/L`nSize";
                            Width=8;Align="Right"},
              @{Expression={$_.Title};Label="`nTitle";Width=45}
       
            $TStr += $NotHiddenUpdates | 
                     Sort-Object MsrcSeverity, Title | 
                     Format-Table -Property $FmtUpdts -Wrap | 
                     Out-String -Width 80
      
          } #End Else
      
      $TStr += @"
      
    Hidden Updates
    --------------
    "@ | Out-String
      
          $HiddenUpdates = $SearchResult.updates | 
               Where-Object {$_.IsHidden -eq $true}
      
          If ($HiddenUpdates -eq $null) { 
            $TStr += "None"  | Out-String
          } 
          Else {
            $TStr += $HiddenUpdates | 
                    Sort-Object MsrcSeverity, Title | 
                    Format-Table -Property $FmtUpdts -Wrap | 
                    Out-String -Width 80
          }
        }  #End If ($ShowPendingUpdates) 
      
        Else {
          $TStr += "The ShowPendingUpdates parameter is `$false," +
                   " so pending updates not listed.`n" | Out-String
         
        } # End Else $ShowPendingUpdates
      	
        $TStr += "`nScript execution succeeded" | Out-String
        $ExitCode = 0
      
      } # Try
      
      Catch {
        
        $TStr += "$error[0]" | Out-String
        $TStr += "`nScript execution failed" | Out-String
        $ExitCode = 1001 # Cause script to report failure in MaxFocus RM dashboard
      }
      
      
      $TStr += "`nLocal Machine Time:  " + (Get-Date -Format G) +
               "`nExit Code: " + $ExitCode | Out-String
      
      "$TStr"
    
    } #End WinUpdSettings
    -------End Code------
  11. Mark Berry Post author

    Thanks Bruce. I wrapped the code in a “pre” tag. Not pretty in the comment but I think if anyone wants to cut and paste, it will retain spacing.

Leave a Reply

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.