我有下面的工作代码,该代码用作SCCM中的检测子句,以检测是否已将服务器功能安装为服务器功能脚本安装程序的一部分。
$role = Get-WmiObject -Class Win32_ServerFeature | Where-Object {$_.ID -eq 2}
if ($role) {
Write-Host "Installed"
}
else {
}
问题是,以上仅是服务器功能中的1个,我将如何使用数组在类中的每个相关服务器功能中进行添加,以使检测子句的准确度达到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) >
谢谢
答案 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调用,而不只是您需要的WMI调用。我不确定使用某些WQL语法是否可以做得更好(因为WQL非常有限),但是如果我找到更优雅的方式,我将对此进行更新。我现在主要是发布这个相当粗糙的解决方案,因为我想我理解您想要实现的目标,以期寻求更好的解决方案。
答案 1 :(得分:0)
我在想什么,但是将对象放入数组而不是单个变量?这似乎不是最简单的方法。
$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 {
}
答案 2 :(得分:0)
我怀疑我完全误解了您的问题,但这还是我的答案 ...
您为什么要重复打电话来创建自己已有的东西? [皱眉],您可以从该WMI调用中收集整个属性集。如果只需要它们的子集,则创建一个包含所需属性的[PSCustomObject]
。
请勿重复调用同一愚蠢的WMI类! [咧嘴]
我的win7ps5.1框上没有Win32_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