【问题标题】:CIM vs WMI returning different informationCIM 与 WMI 返回不同的信息
【发布时间】:2018-05-06 06:34:42
【问题描述】:

我试图利用 CIM 的内置并行处理来获取有关给定计算机子网的所有已安装打印机的信息。该脚本比我的 WMI 变体运行得更快,但不会返回相同的信息,并且并不总是像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 分钟,但如果它不会返回所有信息,最好等待。

有人知道如何防止 CIM 丢失信息吗?

需要注意的是,WinRM 在这些机器上默认没有启用,脚本必须使用以下命令强制启用 CIM。

& "c:\Scripts\SnIPT\psexec.exe" \\$ComputerName -s -d -n 5 winrm.cmd quickconfig -q -force

【问题讨论】:

  • 您缺少什么信息?某些计算机缺少对象或 CIM 是否忽略了 DriveName 等单个属性?
  • 您的第一个故障排除步骤应该是使 2 个脚本尽可能相似。例如,Get-WmiObjectGet-CimInstance 都有参数-ComputerName,因此无需先打开 CIM 会话。此外,一个脚本将循环的输出收集到一个变量中,而另一个脚本则附加到一个数组中。在这两种情况下都使用前者,因为它提供了明显更好的性能。一个脚本正在构建自定义对象,而另一个只是使用Select-Object。在这两种情况下都做后者。
  • 至于两个脚本结果的实际差异:是否缺少整个记录,某些属性的值,或者您是否从两个脚本中获得了相同系统的不同值?出现差异的系统是否有共同点(操作系统、PowerShell 版本、安装的软件、防火墙设置……)?
  • 谢谢,我会清理它并使它们更相似。缺少多台计算机的记录,但作为你和@FrodeF,这可能是由于不同版本的 Windows。我正在运行这可能针对数千台机器(不是一次全部,而是随着时间的推移)。

标签: powershell wmi cim


【解决方案1】:

相同的 WMI 类应该返回相同的数据(但是 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

【讨论】:

  • 谢谢。固定的。忘记一行
  • 可能是 Windows 管理框架。在各种网络中,有数千台机器,因此它们不会都拥有这样的机器是有道理的。
猜你喜欢
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2011-04-20
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多