CIM与WMI返回不同的信息

时间:2018-05-06 06:34:43

标签: powershell wmi cim

我试图利用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

1 个答案:

答案 0 :(得分:0)

相同的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