使用 Get-WmiObject 将多个对象添加到数组中 | Where对象

Adding Multiple Objects into Array using Get-WmiObject | Where-Object

我有下面的工作代码,它被用作 SCCM 中的检测子句,以检测是否安装了服务器功能,作为服务器功能脚本安装程序的一部分。

$role = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 2}
if ($role) {
    Write-Host "Installed"
}
else {
}

问题,问题是,上面只有 1 个服务器功能,我如何使用数组添加 class 中的每个相关服务器功能,以便检测子句 100% 准确?

本案例中的相关角色是:

Web-Server Web-ISAPI-Ext Web-Windows-Auth Web-Metabase Web-WMI RDC

在已经安装了它们的机器上,我可以提取这些信息来添加:

Get-WmiObject -Class win32_serverfeature | select Name, ID

Name                                ID
----                                --
Web Server (IIS)                     2
File Services                        6
Windows Deployment Services         19
.NET Framework 3.0 Features         36
Windows Process Activation Service  41
Telnet Client                       44
SNMP Services                       59
Remote Server Administration Tools  67
Web Server                         140
Common HTTP Features               141
Static Content                     142
Default Document                   143
Directory Browsing                 144
HTTP Errors                        145
Application Development            147
ISAPI Extensions                   152
Health and Diagnostics             155
HTTP Logging                       156
Request Monitor                    158
Security                           162
Windows Authentication             164
Request Filtering                  169
Performance                        171
Static Content Compression         172
Management Tools                   174
IIS Management Console             175
IIS 6 Management Compatibility     178
IIS 6 Metabase Compatibility       179
Configuration APIs                 217
.NET Environment                   218
Process Model                      219
.NET Framework 3.0                 220
SNMP Service                       224
SNMP WMI Provider                  225
Deployment Server                  251
Transport Server                   252
File Server                        255
Role Administration Tools          256
Windows Deployment Services Tools  264
Web Server (IIS) Tools             281

注意:这是为旧服务器设计的 运行 2008 SP2 所以,这意味着我有旧的工具集可以使用(ServerFeaturecmd.exe - Install-WindowsFeature 和 Get-Windowfeature不能使用)

谢谢

我的想法是这样的,但是,将对象放入数组而不是单个变量?这似乎不是最简单的方法。

$roleID2 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 2}
$roleID140 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 140}
$roleID141 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 141}
$roleID162 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 162}
$roleID164 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 164}
$roleID179 = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 179}

If ($roleID2 -and $roleID140 -and $roleID141 -and $roleID162 -and $roleID164 $roleID179) {
    Write-Host "Installed"
}
else {
}

我怀疑我完全误解了你的问题,但无论如何这就是我的回答 ...

你为什么要反复调用来创建你已经拥有的东西? [皱眉]您拥有来自该 WMI 调用的整个属性集的集合。如果您只想要其中的一个子集,请创建一个包含您想要的属性的 [PSCustomObject]

不要重复调用同一个愚蠢的 WMI class! [咧嘴一笑]

我的 win7ps5.1 机器上没有 class 作为 Win32_ServerFeature,所以下面的演示是与其他 classes 一起使用的。

[注 1] 您可以调用 几个 classes,将它们保存到唯一的 $Vars,然后使用它们构建整个子集捆绑的属性。

[注 2] 您可以在远程系统上使用 Invoke-Command 到 运行 在脚本块中并行调用所有这些。

#requires -RunAsAdministrator

# fake reading in a list of computer names
#    in real life, use Get-Content or (Get-ADComputer).Name
$ComputerList = @'
Localhost
BetterNotBeThere
127.0.0.1
10.0.0.1
::1
'@.Split("`n").Trim("`r")

$IC_ScriptBlock = {
    $CIM_ComputerSystem = Get-CimInstance -ClassName CIM_ComputerSystem
    $CIM_BIOSElement = Get-CimInstance -ClassName CIM_BIOSElement
    $CIM_OperatingSystem = Get-CimInstance -ClassName CIM_OperatingSystem
    $CIM_Processor = Get-CimInstance -ClassName CIM_Processor
    $CIM_LogicalDisk = Get-CimInstance -ClassName CIM_LogicalDisk |
        Where-Object {$_.Name -eq $CIM_OperatingSystem.SystemDrive}

    [PSCustomObject]@{
        LocalComputerName = $env:COMPUTERNAME
        Manufacturer = $CIM_ComputerSystem.Manufacturer
        Model = $CIM_ComputerSystem.Model
        SerialNumber = $CIM_BIOSElement.SerialNumber
        CPU = $CIM_Processor.Name
        SysDrive_Capacity_GB = '{0:N2}' -f ($CIM_LogicalDisk.Size / 1GB)
        SysDrive_FreeSpace_GB ='{0:N2}' -f ($CIM_LogicalDisk.FreeSpace / 1GB)
        SysDrive_FreeSpace_Pct = '{0:N0}' -f ($CIM_LogicalDisk.FreeSpace / $CIM_LogicalDisk.Size * 100)
        RAM_GB = '{0:N2}' -f ($CIM_ComputerSystem.TotalPhysicalMemory / 1GB)
        OperatingSystem_Name = $CIM_OperatingSystem.Caption
        OperatingSystem_Version = $CIM_OperatingSystem.Version
        OperatingSystem_BuildNumber = $CIM_OperatingSystem.BuildNumber
        OperatingSystem_ServicePack = $CIM_OperatingSystem.ServicePackMajorVersion
        CurrentUser = $CIM_ComputerSystem.UserName
        LastBootUpTime = $CIM_OperatingSystem.LastBootUpTime
        }
    }

$IC_Params = @{
    ComputerName = $ComputerList
    ScriptBlock = $IC_ScriptBlock
    ErrorAction = 'SilentlyContinue'
    }
$RespondingSystems = Invoke-Command @IC_Params
$NOT_RespondingSystems = $ComputerList.Where({
    # these two variants are needed to deal with an ipv6 localhost address
    "[$_]" -notin $RespondingSystems.PSComputerName -and
    $_ -notin $RespondingSystems.PSComputerName
    })

$RespondingSystems
$NOT_RespondingSystems

t运行响应系统的分类输出...

LocalComputerName           : [MySystemName]
Manufacturer                : System manufacturer
Model                       : System Product Name
SerialNumber                : System Serial Number
CPU                         : AMD Phenom(tm) II X4 945 Processor
SysDrive_Capacity_GB        : 931.41
SysDrive_FreeSpace_GB       : 750.18
SysDrive_FreeSpace_Pct      : 81
RAM_GB                      : 8.00
OperatingSystem_Name        : Microsoft Windows 7 Professional 
OperatingSystem_Version     : 6.1.7601
OperatingSystem_BuildNumber : 7601
OperatingSystem_ServicePack : 1
CurrentUser                 : [MySystemName]\[MyUserName]
LastBootUpTime              : 2018-10-29 1:48:53 AM
PSComputerName              : Localhost
RunspaceId                  : 367b79f3-dd9a-48c3-8e15-7be4d9134eda

无响应系统的输出...

BetterNotBeThere
10.0.0.1

如果你只是想减少代码,你可以这样写:

$featureIDs = @(2, 140, 141, 162, 164, 179)
$compliant = $true

foreach($ID in $featureIDs) {
    $compliant = $compliant -and ((Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq $ID}) -ne $null)
}

if ($compliant) {
    Write-Host "Installed"
}
else {
}

然而,这确实执行了大量 WMI 调用,而不仅仅是您需要的那个。我不确定使用某些 WQL 语法是否可以做得更好(因为 WQL 非常有限),但如果我找到更优雅的方法,我会更新它。我现在主要发布这个相当粗略的解决方案,因为我想我理解你想要实现的目标,希望能激发出更好的解决方案。