Create a PowerShell Grid Widget dashboard to display Pending Restart status

Category: SCOM

I needed a way to display the health state of the Server Pending Restart Monitor from the Server Pending Restart management pack in a SCOM dashboard. SCOM does not have a native method to display the health state of all instances of a specific monitor, so fortunately Hugh Scott pointed me to PowerShell Grid Widgets as a possible solution. This article discusses how I approached the problem and how I ended up at this PowerShell Grid Widget dashboard solution.

Server Pending Restart Monitor Status

Before creating the dashboard we need to collect the information we want to display in it. The following steps show how to get the status of a specific monitor across all of the objects which it monitors.

  1. Get the Server Pending Restart Monitor object.

     $rebootRequiredMonitor = Get-SCOMMonitor -DisplayName 'Server Pending Restart Monitor'
    
  2. Get the class which is targeted by the reboot required monitor. In this case it is an Operating System object.

     $operatingSystemClass = Get-SCOMClass -Id $rebootRequiredMonitor.Target.Id
    
  3. Get all instances of the Operating System class.

     $operatingSystems = Get-SCOMClassInstance -Class $operatingSystemClass
    
  4. Create a collection to use when searching for the state of the monitor in the context of the operating system. This a requirement when using the GetMonitoringStates() method.

     $monitorCollection = New-Object -TypeName 'System.Collections.Generic.List[Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitor]'
     $monitorCollection.Add($rebootRequiredMonitor)
    
  5. Get one of the operating system objects to work with

     $operatingSystem = $operatingSystems[0]
    
  6. Get the first state of the monitor in the context of the specified operating system.

     $rebootState = $operatingSystem.GetMonitoringStates($monitorCollection)[0]
    
  7. Get the context of the last state change events and cast it as an XML object.

     [xml]$context = $rebootState.GetStateChangeEvents()[-1].Context
    
  8. From here all of the properties which are available in the Server Pending Restart Monitor can be listed.

     $context.DataItem.Property
    

SCOM PowerShell Widget Data Object

Now that the data to display is collected, a data object must be created so the PowerShell Grid Widget can display the data.

  1. Create a hashtable to translate between the HealthState value and alphabetical characters. This will be used as part of the Id field which is used to sort the table.

     $sortTable = @{
         0 = 'd'
         1 = 'c'
         2 = 'b'
         3 = 'a'
     }
    
  2. Create a data object with a dummy namespace. The namespace name does not appear to be important.

     $dataObject = $ScriptContext.CreateInstance('xsd://foo!bar/baz')
    
  3. Get the numeric value of the health state.

     $healthStateValue = $rebootState[0].HealthState.value__
    
  4. Translate the health state value to the alphabetic character which will be used to sort the grid.

     $sortId = $sortTable[$healthStateValue]
    
  5. Create an Id field with both the health state and operating system ID. There are a couple points which can be gotchas in this process:
    • The Id field must be a string.
    • The Id field is the only field which is used to sort the grid.
     $dataObject['Id'] = "$sortId $($operatingSystem.Id.ToString())"
    
  6. Add the rest of the data properties as desired.

     $dataObject['Health State'] = $ScriptContext.CreateWellKnownType('xsd://Microsoft.SystemCenter.Visualization.Library!Microsoft.SystemCenter.Visualization.OperationalDataTypes/MonitoringObjectHealthStateType',$rebootState[0].HealthState.value__)
     $dataObject['Maintenance Mode'] = $ScriptContext.CreateWellKnownType('xsd://Microsoft.SystemCenter.Visualization.Library!Microsoft.SystemCenter.Visualization.OperationalDataTypes/MonitoringObjectInMaintenanceModeType',$operatingSystem.InMaintenanceMode)
     $dataObject['Computer'] = [System.String]($operatingSystem.'[Microsoft.Windows.Computer].PrincipalName'.Value)
     $dataObject['Last BootUp Time'] = $context.DataItem.Property | Where-Object -FilterScript { $_.Name -eq 'LastBootUpTime' } | Select-Object -ExpandProperty '#text'
     $dataObject['Windows Update'] = $context.DataItem.Property | Where-Object -FilterScript { $_.Name -eq 'WindowsUpdateAutoUpdate' } | Select-Object -ExpandProperty '#text'
     $dataObject['Component Based Servicing'] = $context.DataItem.Property | Where-Object -FilterScript { $_.Name -eq 'ComponentBasedServicing' } | Select-Object -ExpandProperty '#text'
     $dataObject['Pending File Rename Operations'] = $pendingFileRenameOperations
     $dataObject['Pending File Renames'] = $pendingFileRenames
    
  7. Add the data object to the collection which is returned to the PowerShell Grid Widget.

     $ScriptContext.ReturnCollection.Add($dataObject)
    

Create the PowerShell Grid Widget

Many others have already blogged about this, so I will point you to Stefan Stranger’s blog in which he wrote walk through using the PowerShell Grid Widget.

Full Script

The full script described in this article is available on GitHub.

Written on May 24, 2019