如何访问SCOM监控数组中显示但Get-Member未识别的属性?
我有一个名为$monitors的数组,它是通过以下两行PowerShell命令创建的SCOM监控列表:
Start-OperationsManagerClientShell -ManagementServerName: "your-mgmt-server" -PersistConnection: $false -Interactive: $false; $monitors = Get-SCOMMonitor | Where-Object -Property XmlTag -eq "UnitMonitor"
直接输出该数组时,成员似乎包含Overridden和Target两个属性:
PS D:\Daniel> $monitors Enabled DisplayName ParentMonitorID Overri Target dden ------- ----------- --------------- ------ ------ true Database Performance (rollup) ManagementPackElementUniqueIdentif... True SQL Server 2005 DB Engine true File Share Shadow Copy Availability ManagementPackElementUniqueIdentif... False File Server VSS Agent Service (Windows Serv... true Server Role hosts User Service Category - Configuration ManagementPackElementUniqueIdentif... False Server Role false Delt-Astraia License Monitor ManagementPackElementUniqueIdentif... False Windows Server true DB Memory-Optimized Data Filegroup Space (rollup) ManagementPackElementUniqueIdentif... True SQL Server 2016 DB
但通过Get-Member查询时,"Overridden"属性不存在:
PS D:\Daniel> $monitors | gm TypeName: Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonitor Name MemberType Definition ---- ---------- ---------- CheckVersionCompatibility Method System.Collections.Generic.IList[Microsoft.EnterpriseManagement.Configuration.Verification.ManagementPackVerificationResult] CheckVersionCompatibilit... CreateNavigator Method System.Xml.XPath.XPathNavigator CreateNavigator(), System.Xml.XPath.XPathNavigator IXPathNavigable.CreateNavigator() Equals Method bool Equals(System.Object obj) GetCategories Method System.Collections.Generic.IList[Microsoft.EnterpriseManagement.Configuration.ManagementPackCategory] GetCategories() GetDisplayString Method Microsoft.EnterpriseManagement.Configuration.ManagementPackDisplayString GetDisplayString(cultureinfo culture), Microsoft.EnterpriseManagement.Config... GetFolders Method Microsoft.EnterpriseManagement.Configuration.ManagementPackElementCollection[Microsoft.EnterpriseManagement.Configuration.ManagementPackFolder] GetFo... GetHashCode Method int GetHashCode() GetImageReferences Method System.Collections.Generic.IEnumerable[Microsoft.EnterpriseManagement.Configuration.ManagementPackImageReference] GetImageReferences() GetKnowledgeArticle Method Microsoft.EnterpriseManagement.Configuration.ManagementPackKnowledgeArticle GetKnowledgeArticle(cultureinfo culture), Microsoft.EnterpriseManagement.... GetManagementPack Method Microsoft.EnterpriseManagement.Configuration.ManagementPack GetManagementPack() GetOverrideableParameters Method System.Collections.Generic.IList[Microsoft.EnterpriseManagement.Configuration.ManagementPackOverrideableParameter] GetOverrideableParameters() GetType Method type GetType() Reconnect Method void Reconnect(Microsoft.EnterpriseManagement.Configuration.ManagementPack mp), void Reconnect(Microsoft.EnterpriseManagement.EnterpriseManagementGro... ToString Method string ToString() Verify Method System.Collections.Generic.IList[Microsoft.EnterpriseManagement.Configuration.Verification.ManagementPackVerificationResult] Verify(Microsoft.Enterpr... WriteXml Method void WriteXml(System.Xml.XmlWriter writer) Accessibility Property Microsoft.EnterpriseManagement.Configuration.ManagementPackAccessibility Accessibility {get;set;} AlertSettings Property Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitorAlertSettings AlertSettings {get;set;} Category Property Microsoft.EnterpriseManagement.Configuration.ManagementPackCategoryType Category {get;set;} Comment Property string Comment {get;set;} Configuration Property string Configuration {get;set;} ConfirmDelivery Property bool ConfirmDelivery {get;set;} Description Property string Description {get;set;} DisplayName Property string DisplayName {get;set;} Enabled Property Microsoft.EnterpriseManagement.Configuration.ManagementPackMonitoringLevel Enabled {get;set;} HasNonCategoryOverride Property bool HasNonCategoryOverride {get;} Id Property guid Id {get;} Identifier Property Microsoft.EnterpriseManagement.Configuration.ExtensionIdentifier Identifier {get;} InstanceName Property string InstanceName {get;set;} LanguageCode Property string LanguageCode {get;set;} LastModified Property datetime LastModified {get;set;} ManagementGroup Property Microsoft.EnterpriseManagement.EnterpriseManagementGroup ManagementGroup {get;} ManagementGroupId Property guid ManagementGroupId {get;} Name Property string Name {get;} OperationalStateCollection Property Microsoft.EnterpriseManagement.Configuration.ManagementPackSubElementCollection[Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonito... ParentMonitorID Property Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference[Microsoft.EnterpriseManagement.Configuration.ManagementPackAggregateMonit... Priority Property Microsoft.EnterpriseManagement.Configuration.ManagementPackWorkflowPriority Priority {get;set;} Remotable Property bool Remotable {get;set;} RunAs Property Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference[Microsoft.EnterpriseManagement.Configuration.ManagementPackSecureReferenc... Status Property Microsoft.EnterpriseManagement.Configuration.ManagementPackElementStatus Status {get;set;} Target Property Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference[Microsoft.EnterpriseManagement.Configuration.ManagementPackClass] Target ... TimeAdded Property datetime TimeAdded {get;set;} TypeID Property Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference[Microsoft.EnterpriseManagement.Configuration.ManagementPackUnitMonitorTyp... XmlTag Property string XmlTag {get;}
Target属性确实存在,但使用Format-Table打印时显示的值与数组输出时不同:
PS D:\Daniel> $monitors | Format-Table Target Target ------ ManagementPackElementUniqueIdentifier=e817d034-02e8-294c-3509-01ca25481689 ManagementPackElementUniqueIdentifier=0302db52-58b0-43ff-65fe-0b492a1461ae ManagementPackElementUniqueIdentifier=979b9385-5195-5be8-ce28-1467a6323c36 ManagementPackElementUniqueIdentifier=2d34f1de-ce5d-9a5d-bce1-67b75619d3a6
展开该属性也无法得到数组输出时看到的名称值:
PS D:\Daniel> $monitors | Select-Object -ExpandProperty Target | Format-List * Name : Id : e817d034-02e8-294c-3509-01ca25481689 Identifier : 1|Microsoft.Windows.Library/31bf3856ad364e35|1.0.0.0|Microsoft.Windows.Server.Computer|| Name : Id : 0302db52-58b0-43ff-65fe-0b492a1461ae Identifier : 1|Microsoft.Windows.2016.Cluster.Management.Library/31bf3856ad364e35|1.0.0.0|Microsoft.Windows.10.0.Cluster.NetworkInterface|| Name : Id : 979b9385-5195-5be8-ce28-1467a6323c36 Identifier : 1|Microsoft.Windows.InternetInformationServices.2000/31bf3856ad364e35|1.0.0.0|Microsoft.Windows.InternetInformationServices.2000.FTPSite||
请问如何访问Overridden和Target属性,以便进行排序、导出到CSV等操作?
这种情况其实是SCOM PowerShell对象的默认格式化视图在搞鬼——当你直接输出$monitors时,PowerShell用了预定义的格式展示了一些动态计算的属性(比如Overridden),而这些属性并不是对象本身的原生属性,所以Get-Member找不到它们。下面分别解决两个属性的问题:
1. 获取Target的友好名称
你看到的Target显示名称是目标类的显示名,不是ManagementPackElementReference对象本身的属性。要获取这个名称,你需要通过GetManagementPackClass()方法加载完整的类对象,然后读取它的DisplayName属性:
$monitors | ForEach-Object { [PSCustomObject]@{ DisplayName = $_.DisplayName TargetName = $_.Target.GetManagementPackClass().DisplayName Enabled = $_.Enabled # 按需添加其他属性 } }
如果类对象的DisplayName为空,你还可以回退到Name属性,或者解析Identifier字段里的类名部分。
2. 检测Overridden状态
Overridden是一个动态计算的属性,你有两种方式获取它:
方式一:直接调用动态属性
PowerShell的PSObject可以访问格式化视图里的动态属性:
$monitors | Select-Object DisplayName, Enabled, @{Name='Overridden'; Expression={$_.PSObject.Properties['Overridden'].Value}}, @{Name='TargetName'; Expression={$_.PSObject.Properties['Target'].Value}}
方式二:通过管理组查询真实覆盖状态
这种方式更可靠,能准确判断监视器是否存在任何覆盖:
$mgmtGroup = Get-SCOMManagementGroup $monitors | ForEach-Object { $monitor = $_ $hasOverride = $mgmtGroup.Overrides.GetOverridesForObject($monitor.Id).Count -gt 0 [PSCustomObject]@{ DisplayName = $monitor.DisplayName Overridden = $hasOverride TargetName = $monitor.Target.GetManagementPackClass().DisplayName Enabled = $monitor.Enabled } }
3. 导出到CSV的完整示例
把这些逻辑整合起来,生成包含所需属性的自定义对象,就能顺利导出到CSV用于后续处理:
$mgmtGroup = Get-SCOMManagementGroup $exportData = $monitors | ForEach-Object { $targetClass = $_.Target.GetManagementPackClass() [PSCustomObject]@{ DisplayName = $_.DisplayName Enabled = ($_.Enabled -eq 'true') Overridden = ($mgmtGroup.Overrides.GetOverridesForObject($_.Id).Count -gt 0) TargetDisplayName = $targetClass.DisplayName TargetInternalName = $targetClass.Name } } $exportData | Export-Csv -Path 'C:\temp\SCOM_Monitors.csv' -NoTypeInformation -Encoding UTF8
这样生成的CSV文件里的属性都是可排序、可筛选的,完全满足你的需求。
内容的提问来源于stack exchange,提问作者Daniel Hjertholm

