【问题标题】:PowerShell WMI/WQL to get information from SCCM - optimisationPowerShell WMI/WQL 从 SCCM 获取信息 - 优化
【发布时间】:2019-02-22 13:57:47
【问题描述】:

在这种情况下,我的工作正常,但我不禁觉得必须有更快的方法来做到这一点。我在这里怀疑我的结构。您是否看到了一种更快的方法可以做到这一点? foreach 需要一段时间,因为它必须查询很多次。目标是拥有一个显示计算机 ($poste) 集合(名称和对象路径)的数组。

$poste = "p1234"

$SiteCode = "PRX"
$SiteServer = "SSX"

$ResourceID = Get-WmiObject -Namespace root\sms\site_$SiteCode -Computer $SiteServer -Class SMS_R_SYSTEM -Filter "Name='$poste'" |
              Select-Object -ExpandProperty ResourceID
$CollectionIDs = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class sms_fullcollectionmembership -Filter "ResourceID ='$resourceID'" |
                 Select-Object -expand CollectionID

foreach ($CollectionID in $CollectionIDs) {
    $query = @"
SELECT * FROM SMS_Collection
WHERE SMS_Collection.CollectionID='$CollectionID'
"@

[array]$CollectionNamesPath += Get-WmiObject -Namespace root\sms\site_$SiteCode -Computer $SiteServer -Query $query |
                               Select-Object name,ObjectPath |
                               Sort-Object -Property Name
} 

$CollectionNamesPath | Out-GridView

【问题讨论】:

  • 如果项目的数量“大”,那么这个[array]$CollectionNamesPath += 将使循环在每次通过时运行得更慢。数组+= 不添加......它创建一个新的一项更大的数组,将旧的复制到新的,插入新的项目,然后删除旧的。正如您所猜测的那样,随着数组变大,它会变得非常慢。通常的解决方案是使用$Collection = foreach ( 将整个结果集一次性放入数组中。
  • 嗨,李!好点,我不禁觉得必须有更好的方法来解决这个问题,也许是 SCCM CMDlets?
  • 我对 SCCM cmdlet 一无所知……但是,希望它们得到优化。 [grin] 我会试一试...
  • Invoke-Command 将同时运行多个命令。
  • 这个问题已经回答了。如果您有新问题,请点击 按钮提出问题。如果有助于提供上下文,请包含指向此问题的链接。

标签: powershell wmi wql get-wmiobject


【解决方案1】:

这可能是您现有代码的最干净的版本:

$poste = "p1234"
$SiteCode = "PRX"
$SiteServer = "SSX"
$ResourceID = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class SMS_R_SYSTEM -Filter "Name='$poste'" -Property ResourceID | Select-Object -ExpandProperty ResourceID
$CollectionIDs = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class sms_fullcollectionmembership -Filter "ResourceID='$resourceID'" -Property CollectionID | Select-Object -ExpandProperty CollectionID

$CollectionNamesPath = foreach ($CollectionID in $CollectionIDs) {
    $Query = "Select Name, ObjectPath From SMS_Collection Where SMS_Collection.CollectionID='$CollectionID'"
    Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Query $Query | Select-Object Name, ObjectPath | Sort-Object -Property Name
} 

$CollectionNamesPath | Out-GridView

你也可以试试这个,虽然我不确定 WQL 是否支持它:

$poste = "p1234"
$SiteCode = "PRX"
$SiteServer = "SSX"
$ResourceID = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class SMS_R_SYSTEM -Filter "Name='$poste'" -Property ResourceID | Select-Object -ExpandProperty ResourceID
$CollectionIDs = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class sms_fullcollectionmembership -Filter "ResourceID='$resourceID'" -Property CollectionID | Select-Object -ExpandProperty CollectionID

$Query = "Select CollectionID, Name, ObjectPath From SMS_Collection Where" + $($($CollectionIDs | ForEach-Object { " SMS_Collection.CollectionID='$_' " }) -join 'or')

$CollectionNamesPath = Get-WmiObject -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Query $Query |
    Sort-Object -Property CollectionID, Name |
    Select-Object Name, ObjectPath

$CollectionNamesPath | Out-GridView

你也许可以做这样的事情:

Get-CimInstance -Namespace root\sms\site_$SiteCode -ComputerName $SiteServer -Class SMS_R_SYSTEM -Filter "Name='$poste'" -KeyOnly |
    Get-CimAssociatedInstance -ComputerName $SiteServer -ResultClassName sms_fullcollectionmembership -KeyOnly |
    Get-CimAssociatedInstance -ComputerName $SiteServer -ResultClassName SMS_Collection |
    Sort-Object -Property CollectionID, Name |
    Select-Object Name, ObjectPath

当它起作用时,它太棒了。然而,根据我使用Get-CimAssociatedInstance 的经验,充其量是一种不平衡的体验,在远程计算机上工作时更是如此。

【讨论】:

  • 或者只在Get-WmiObject上使用-Filter而不构建一些大查询
  • 非常感谢您的建议,有时间我会尝试并报告
  • @Bacon Bits 我正在尝试通过作业收集数据,因此速度要快得多,但是我遗漏了一些东西……您对此有什么建议吗(检查问题的编辑)跨度>
  • @TheIncorrigible1 我完全不确定使用-Filter 会如何在此处保存任何内容。过滤器的值与 WQL 的 Where 子句相同。它们使用相同的语法。
  • @Rakha 这与最初在这里提出的问题完全不同。如果您想问这个问题,您应该将该问题发布到另一个问题。
猜你喜欢
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
  • 1970-01-01
  • 2012-08-28
相关资源
最近更新 更多