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 } } |