Public/Get-SCOMRelatedMonitoringObjects.ps1

Function Get-SCOMRelatedMonitoringObjects {
  <#
  .SYNOPSIS
      Recursively retrieves all related monitoring objects from a SCOM monitoring object hierarchy.
 
  .DESCRIPTION
      The Get-SCOMRelatedMonitoringObjects function performs a recursive traversal of the SCOM monitoring object
      hierarchy starting from a specified monitoring object. It discovers and returns all monitoring objects that
      are related to the initial object, including nested relationships at any depth.
 
      Unlike the built-in SCOM method GetRelatedMonitoringObjects() which only returns directly related objects,
      this function recursively explores the entire relationship tree. This is particularly useful when you need
      to discover all components and dependencies associated with a computer or service, including:
 
      - Computer objects and their hosted components (services, processes, applications)
      - Logical disk drives, network adapters, and other hardware components
      - Application dependencies and their related monitoring objects
      - Nested service relationships and component hierarchies
 
      The function is essential for comprehensive monitoring scenarios where you need to understand the complete
      scope of monitoring objects related to a specific entity, such as:
      - Performance data collection across all related components
      - Health state analysis for complex applications
      - Impact analysis for maintenance and troubleshooting
      - Comprehensive reporting and inventory management
 
  .PARAMETER ClassInstance
      Specifies the SCOM monitoring object that serves as the starting point for the recursive relationship
      traversal. This must be a valid MonitoringObject instance obtained from SCOM cmdlets.
 
      Type: Microsoft.EnterpriseManagement.Monitoring.MonitoringObject
      Required: True
      Pipeline Support: No
 
  .EXAMPLE
      $computer = Get-SCOMClassInstance -Class (Get-SCOMClass -Name "Microsoft.Windows.Computer") | Where-Object {$_.DisplayName -eq "SQL01.contoso.com"}
      $allRelatedObjects = Get-SCOMRelatedMonitoringObjects -ClassInstance $computer
      Write-Host "Found $($allRelatedObjects.Count) related monitoring objects for $($computer.DisplayName)"
      $allRelatedObjects | Select-Object DisplayName, HealthState, Path | Format-Table -AutoSize
 
      Description:
      Retrieves all monitoring objects related to a specific computer, including all services, processes,
      logical disks, network adapters, and other components monitored on that system. This provides a
      complete inventory of all monitored components associated with the server.
 
      Output:
      Console output showing the count of related objects and a formatted table displaying the display name,
      health state, and path of each related monitoring object. This typically includes dozens or hundreds
      of objects for a fully monitored server.
 
  .EXAMPLE
      $sqlService = Get-SCOMClassInstance -Class (Get-SCOMClass -Name "Microsoft.SQLServer.Database") | Where-Object {$_.DisplayName -like "*AdventureWorks*"}
      $relatedObjects = Get-SCOMRelatedMonitoringObjects -ClassInstance $sqlService
 
      # Group related objects by class to understand the monitoring scope
      $objectsByClass = $relatedObjects | Group-Object {$_.GetLeastDerivedNonAbstractClass().DisplayName} | Sort-Object Count -Descending
      foreach ($group in $objectsByClass) {
          Write-Host "$($group.Name): $($group.Count) objects"
      }
 
      # Find any unhealthy related objects
      $unhealthyObjects = $relatedObjects | Where-Object {$_.HealthState -ne "Success"}
      if ($unhealthyObjects) {
          Write-Warning "Found $($unhealthyObjects.Count) unhealthy related objects:"
          $unhealthyObjects | Select-Object DisplayName, HealthState | Format-Table -AutoSize
      }
 
      Description:
      Advanced example that retrieves all objects related to a SQL Server database and provides detailed
      analysis of the monitoring scope. This includes grouping objects by class type and identifying
      any health issues in the related component hierarchy.
 
      Output:
      Console output showing the count of related objects grouped by monitoring class, followed by
      a table of any unhealthy objects in the related hierarchy. This helps understand both the
      monitoring coverage and any current issues affecting the database and its dependencies.
 
  .EXAMPLE
      # Performance monitoring scenario - get all objects for comprehensive performance collection
      $webServer = Get-SCOMClassInstance -DisplayName "WEB01.contoso.com"
      $allComponents = Get-SCOMRelatedMonitoringObjects -ClassInstance $webServer
 
      # Filter for objects that have performance data
      $perfObjects = $allComponents | Where-Object {
          $_.GetMonitoringPerformanceData().Count -gt 0
      }
 
      Write-Host "Performance monitoring scope for $($webServer.DisplayName):"
      Write-Host "Total related objects: $($allComponents.Count)"
      Write-Host "Objects with performance data: $($perfObjects.Count)"
 
      # Show performance object types
      $perfObjects | Group-Object {$_.GetLeastDerivedNonAbstractClass().DisplayName} |
          Sort-Object Count -Descending |
          Select-Object Name, Count |
          Format-Table -AutoSize
 
      Description:
      Performance monitoring example that identifies all related objects capable of providing performance
      data. This is useful for understanding the complete performance monitoring scope available for a
      server and planning comprehensive performance data collection strategies.
 
      Output:
      Console summary showing total related objects vs objects with performance capabilities, followed
      by a table grouping performance-capable objects by their monitoring class type and count.
 
  .INPUTS
      Microsoft.EnterpriseManagement.Monitoring.MonitoringObject
      You can pipe a SCOM monitoring object to this function.
 
  .OUTPUTS
      Microsoft.EnterpriseManagement.Monitoring.MonitoringObject[]
      Returns an array of MonitoringObject instances representing all monitoring objects related to the
      input object, including the original object itself. The array includes:
      - The original monitoring object passed as input
      - All directly related monitoring objects
      - All recursively discovered related objects at any depth in the hierarchy
 
      Each object contains standard SCOM monitoring object properties such as:
      - DisplayName: The friendly name of the monitoring object
      - Id: The unique GUID identifier
      - HealthState: Current health status (Success, Warning, Critical, etc.)
      - Path: The hierarchical path showing object relationships
      - LastModified: Timestamp of the last modification
 
  .NOTES
      ====================================================================
      Created with: Visual Studio Code
      Author: Tyson Paul
      Created: 2025.09.19
      Last Modified: 2025.09.19
      Version: 1.0
      Blog: https://monitoringguys.com
      ====================================================================
 
      Requirements:
      - System Center Operations Manager PowerShell module (OperationsManager)
      - Appropriate permissions to read SCOM monitoring objects
      - Active connection to a SCOM Management Group
 
      Performance Considerations:
      - Recursive traversal can be resource-intensive for objects with many relationships
      - Large environments may have thousands of related objects for a single computer
      - Consider filtering results or using specific object types when possible
      - Function may take longer to execute for complex application hierarchies
 
      Error Handling:
      - Validates input parameter is a valid MonitoringObject
      - Handles circular references through SCOM's built-in relationship management
      - Gracefully handles objects with no related monitoring objects
 
      Common Use Cases:
      - Comprehensive health monitoring across related components
      - Performance data collection planning and scope analysis
      - Impact analysis for maintenance planning
      - Inventory and discovery of monitored components
      - Dependency mapping for complex applications
 
      Related Functions:
      - Get-SCOMClassInstance: Retrieves SCOM monitoring objects
      - Get-SCOMClass: Gets SCOM monitoring classes
      - Get-SCOMDWPerformanceDataSignature: Uses this function for comprehensive performance discovery
 
  .LINK
      https://docs.microsoft.com/en-us/powershell/module/operationsmanager/
 
  .LINK
      https://monitoringguys.com
 
  .LINK
      https://docs.microsoft.com/en-us/system-center/scom/
  #>


  [CmdletBinding()]
  Param (
    # Easy way to incorporate recursion level for formatting verbose output statements
    [int]$Level = 0,

    [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
    [Microsoft.EnterpriseManagement.Monitoring.MonitoringObject]$ClassInstance
    )
    Begin{}

    #region Process
    Process{
      $arr = [System.Collections.ArrayList]::new()
      $arr.Add($ClassInstance) | Out-Null
      # Get all related monitoring objects recursively
      $relatedObjects = $ClassInstance.GetRelatedMonitoringObjects()
      $space=" "*3*$Level

      If ($ClassInstance.Name.Length -gt 0) {
        Write-Verbose "$($Space)- $($ClassInstance.Name) [$($ClassInstance.Id.Guid)]"
      }
      else{
        Write-Verbose "$($Space)- $($ClassInstance.Path) [$($ClassInstance.Id.Guid)]"
      }

      ForEach ($relatedObject in $relatedObjects) {
        # Recursively get related monitoring objects for this object
        $recursiveObjects = Get-SCOMRelatedMonitoringObjects -ClassInstance $relatedObject -Level ($Level + 1)
        ForEach ($obj in $recursiveObjects) {
          $arr.Add($obj) | Out-Null
        }
      }
    }
    #endregion Process
    End{
      Return $arr
    }
}