使用 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 非常有限),但如果我找到更优雅的方法,我会更新它。我现在主要发布这个相当粗略的解决方案,因为我想我理解你想要实现的目标,希望能激发出更好的解决方案。
我有下面的工作代码,它被用作 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 非常有限),但如果我找到更优雅的方法,我会更新它。我现在主要发布这个相当粗略的解决方案,因为我想我理解你想要实现的目标,希望能激发出更好的解决方案。