Powershell 使用Get WmiObject | Where Object将多个对象添加到数组中
我有下面的工作代码,它在SCCM中用作检测子句,用于检测服务器功能是否作为服务器功能脚本安装程序的一部分安装Powershell 使用Get WmiObject | Where Object将多个对象添加到数组中,powershell,sccm,Powershell,Sccm,我有下面的工作代码,它在SCCM中用作检测子句,用于检测服务器功能是否作为服务器功能脚本安装程序的一部分安装 $role = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 2} if ($role) { Write-Host "Installed" } else { } 问题是,上面只提供了服务器特性中的一个特性,我如何使用数组来添加类中每个相关的服务器特性,从而使detection子句100%准确
$role = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 2}
if ($role) {
Write-Host "Installed"
}
else {
}
问题是,上面只提供了服务器特性中的一个特性,我如何使用数组来添加类中每个相关的服务器特性,从而使detection子句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类![咧嘴笑]
在我的win7ps5.1机器上没有像Win32\u ServerFeature这样的类,所以下面的演示是针对其他类的
[注意1]您可以调用多个类,将它们保存到唯一的$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
来自响应系统的截断输出
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
来自无响应系统的输出
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非常有限),但是如果我找到一种更优雅的方法,我会更新它。我现在主要发布这个相当粗糙的解决方案,因为我想我了解您想要实现的目标,希望能够激发出更好的解决方案。定义“相关”。@AnsgarWiechers-请参阅编辑请再次编辑,因此您提到的角色确实在功能列表中。使用准确的名称,以免混淆。ie.
Windows身份验证
是Web Windows身份验证
的功能吗?奇怪的是,我真的不确定你在找什么……无论如何,还是要为我重写它?@ArcSet我想他想要的(从我个人的sccm知识和他发布的内容来看)是一个任意数组,带有ID,他可以在脚本开始时定义,然后是一个查询(或之后的一些代码)检查数组中的ID是否都存在于win32_serverfeature中,并输出“installed”(已安装)仅在这种情况下我还没有这些服务器功能,这就是添加这些功能的全部目的,它们都需要存在,以便语句返回“installed”值这反过来又告诉SCCM,脚本安装程序工作正常并安装了这些特定角色。安装是通过设备集合在一组计算机上完成的,因此,在这种情况下,不需要使用Invoke命令。@Royston-因此,您希望在2的Name
列中自动生成项目列表ndwin32\u serverfeature
示例?如果是,您可以使用隐藏的.PSObject
属性获取列表。类似于(获取日期).PSObject.Properties.Name
的内容将为您提供对象的属性名称列表。