CIM 与 WMI 返回不同的信息
CIM vs WMI returning different information
我试图利用 CIM 的内置并行处理来获取有关针对给定计算机子网的所有已安装打印机的信息。该脚本比我的 WMI 变体运行得更快,但 return 没有相同的信息,并且并不总是 return 与 Get-WmiObject
调用一样多。
编辑:脚本删除的信息是有关整台计算机的信息。
这是 CIM 版本:
$Computer = Get-Content -Path c:\Scripts\input.txt
$Objects = foreach ($ComputerName in $Computer) {
# New CIM Instance
Write-Host Collecting information on $ComputerName
$Cim = New-CimSession -ComputerName $ComputerName
# Collect Printer Info
Get-CimInstance -CimSession $Cim -Class Win32_printer -Property deviceid, drivername, portname, systemName
# Define Hashtable properties
$ObjectProperties = @{
SystemName = $Cim.systemName
DeviceID = $Cim.deviceid
DriverName = $Cim.drivername
PortName = $Cim.portname
}
# Create new object
New-Object PSObject -Property $ObjectProperties
}
# Export Results
$Objects | Select DeviceID, DriverName, PortName, SystemName |
Export-Csv - NoTypeInformation -Path c:\Scripts\output.csv
这是 WMI 版本:
$results = @()
$Computer = Get-Content -Path c:\Scripts\input.txt
# Check each computer in the list
foreach ($ComputerName in $Computer) {
$results += Get-WmiObject -Class Win32_printer -cn $ComputerName |
Select deviceid, drivername, portname, systemName
Start-Sleep -Milliseconds 500
}
# Export to CSV file
$Results | Select DeviceID, DriverName, PortName, SystemName |
Export-Csv -NoTypeInformation -Path c:\Scripts\output.csv
我们有时需要针对多个子网运行此脚本。我转向 CIM 会话是因为它将脚本的总 运行 减少到始终低于 5 分钟,但如果它不会 return 所有信息,最好等待。
有没有人知道如何防止 CIM 丢失信息?
需要注意的是,WinRM 在这些机器上默认未启用,脚本必须使用以下命令强制启用 CIM。
& "c:\Scripts\SnIPT\psexec.exe" \$ComputerName -s -d -n 5 winrm.cmd quickconfig -q -force
相同的 WMI-class 应该 return 相同的数据(但是 CIM-cmdlet 转换日期 ++)。由于您没有解释有什么不同,我猜它缺少某些计算机的输出。这通常是因为目标计算机缺少 CIM 所需的 Windows Management Framework 3.0 或更高版本(想想 PS 3.0+)。如果是这种情况,它应该会生成一个错误,您可以捕获该错误并将其用于使用 DCOM(与 WMI 相同)作为后备。例如:
$Computer = Get-Content -Path c:\Scripts\input.txt
$DCOM = New-CimSessionOption -Protocol Dcom
$Objects = ForEach($ComputerName in $Computer)
{
#New Cim Instance with fallback to DCOM
Write-Host Collecting information on $ComputerName
$Cim = $null
try {
$Cim = New-CimSession -ComputerName $ComputerName -ErrorAction Stop
} catch [Microsoft.Management.Infrastructure.CimException] {
#CIM not available on target (requires WMF 3.0+). Using DCOM (used by WMI)
try { $Cim = New-CimSession -ComputerName $ComputerName -SessionOption $DCOM -ErrorAction Stop }
catch { Write-Host $_.Exception.Message }
}
#Collect Printer Info
Get-CimInstance -CimSession $Cim -Class Win32_printer -Property DeviceID, DriverName, PortName, SystemName
#Best practice to store the original object.
#No need to create a new one with a few properties when you do it during export anyways.
#If you really need it, add "| Select-Object -Property DeviceID, DriverName, PortName, SystemName" to the previous line
}
#Export Results
$Objects | Select-Object -Property DeviceID, DriverName, PortName, SystemName | Export-Csv - NoTypeInformation -Path c:\Scripts\output.csv
我试图利用 CIM 的内置并行处理来获取有关针对给定计算机子网的所有已安装打印机的信息。该脚本比我的 WMI 变体运行得更快,但 return 没有相同的信息,并且并不总是 return 与 Get-WmiObject
调用一样多。
编辑:脚本删除的信息是有关整台计算机的信息。
这是 CIM 版本:
$Computer = Get-Content -Path c:\Scripts\input.txt
$Objects = foreach ($ComputerName in $Computer) {
# New CIM Instance
Write-Host Collecting information on $ComputerName
$Cim = New-CimSession -ComputerName $ComputerName
# Collect Printer Info
Get-CimInstance -CimSession $Cim -Class Win32_printer -Property deviceid, drivername, portname, systemName
# Define Hashtable properties
$ObjectProperties = @{
SystemName = $Cim.systemName
DeviceID = $Cim.deviceid
DriverName = $Cim.drivername
PortName = $Cim.portname
}
# Create new object
New-Object PSObject -Property $ObjectProperties
}
# Export Results
$Objects | Select DeviceID, DriverName, PortName, SystemName |
Export-Csv - NoTypeInformation -Path c:\Scripts\output.csv
这是 WMI 版本:
$results = @()
$Computer = Get-Content -Path c:\Scripts\input.txt
# Check each computer in the list
foreach ($ComputerName in $Computer) {
$results += Get-WmiObject -Class Win32_printer -cn $ComputerName |
Select deviceid, drivername, portname, systemName
Start-Sleep -Milliseconds 500
}
# Export to CSV file
$Results | Select DeviceID, DriverName, PortName, SystemName |
Export-Csv -NoTypeInformation -Path c:\Scripts\output.csv
我们有时需要针对多个子网运行此脚本。我转向 CIM 会话是因为它将脚本的总 运行 减少到始终低于 5 分钟,但如果它不会 return 所有信息,最好等待。
有没有人知道如何防止 CIM 丢失信息?
需要注意的是,WinRM 在这些机器上默认未启用,脚本必须使用以下命令强制启用 CIM。
& "c:\Scripts\SnIPT\psexec.exe" \$ComputerName -s -d -n 5 winrm.cmd quickconfig -q -force
相同的 WMI-class 应该 return 相同的数据(但是 CIM-cmdlet 转换日期 ++)。由于您没有解释有什么不同,我猜它缺少某些计算机的输出。这通常是因为目标计算机缺少 CIM 所需的 Windows Management Framework 3.0 或更高版本(想想 PS 3.0+)。如果是这种情况,它应该会生成一个错误,您可以捕获该错误并将其用于使用 DCOM(与 WMI 相同)作为后备。例如:
$Computer = Get-Content -Path c:\Scripts\input.txt
$DCOM = New-CimSessionOption -Protocol Dcom
$Objects = ForEach($ComputerName in $Computer)
{
#New Cim Instance with fallback to DCOM
Write-Host Collecting information on $ComputerName
$Cim = $null
try {
$Cim = New-CimSession -ComputerName $ComputerName -ErrorAction Stop
} catch [Microsoft.Management.Infrastructure.CimException] {
#CIM not available on target (requires WMF 3.0+). Using DCOM (used by WMI)
try { $Cim = New-CimSession -ComputerName $ComputerName -SessionOption $DCOM -ErrorAction Stop }
catch { Write-Host $_.Exception.Message }
}
#Collect Printer Info
Get-CimInstance -CimSession $Cim -Class Win32_printer -Property DeviceID, DriverName, PortName, SystemName
#Best practice to store the original object.
#No need to create a new one with a few properties when you do it during export anyways.
#If you really need it, add "| Select-Object -Property DeviceID, DriverName, PortName, SystemName" to the previous line
}
#Export Results
$Objects | Select-Object -Property DeviceID, DriverName, PortName, SystemName | Export-Csv - NoTypeInformation -Path c:\Scripts\output.csv