You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CIM与WMI返回信息不一致:子网计算机打印机获取问题咨询

解决CIM并行获取打印机信息时丢失整台机器数据的问题

看起来你已经发现CIM比传统WMI快很多,但遇到了两个头疼的问题:返回的信息和WMI不一致,甚至会直接丢失整台计算机的记录。我来帮你拆解一下问题原因,再给出具体的解决脚本。

首先,丢失整台机器信息最常见的原因是CIM连接失败但没有被捕获——WMI通常会把错误信息返回给你,但CIM如果处理不当,连接不上的机器就直接被跳过了,连个错误记录都没有。另外,CIM默认返回的属性集可能比WMI少,这也会导致信息不一致。

第一步:捕获连接错误,记录所有机器

先修改你的脚本,加入错误捕获逻辑,这样不管机器能不能连接,都会留下记录:

$ComputerList = Get-Content -Path c:\Scripts\input.txt
$Results = @()

foreach ($ComputerName in $ComputerList) {
    try {
        # 显式指定要获取的属性,确保和WMI返回一致
        $SelectedProps = 'Name', 'DriverName', 'PortName', 'Shared', 'ShareName', 'Default'
        $Printers = Get-CimInstance -ClassName Win32_Printer -ComputerName $ComputerName -Property $SelectedProps -ErrorAction Stop
        
        foreach ($Printer in $Printers) {
            $Results += [PSCustomObject]@{
                ComputerName = $ComputerName
                PrinterName  = $Printer.Name
                DriverName   = $Printer.DriverName
                PortName     = $Printer.PortName
                IsShared     = $Printer.Shared
                ShareName    = $Printer.ShareName
                IsDefault    = $Printer.Default
            }
        }
    }
    catch {
        # 把连接失败的机器也加入结果
        $Results += [PSCustomObject]@{
            ComputerName = $ComputerName
            PrinterName  = "⚠️ 连接失败"
            ErrorMessage = $_.Exception.Message
            DriverName   = $null
            PortName     = $null
            IsShared     = $null
            ShareName    = $null
            IsDefault    = $null
        }
    }
}

$Results | Export-Csv -Path "C:\Scripts\Printer_Report.csv" -NoTypeInformation

第二步:用CIM真正的并行处理提升效率

如果你想充分利用CIM的并行能力(比foreach循环快得多),可以用Invoke-CimCommand来批量处理,同时捕获所有错误:

$ComputerList = Get-Content -Path c:\Scripts\input.txt

# 创建CIM会话选项(根据你的环境选择DCOM或Wsman,一般内网用DCOM)
$SessionOption = New-CimSessionOption -Protocol DCOM

# 创建CIM会话,同时捕获创建失败的机器
$CimSessions = New-CimSession -ComputerName $ComputerList -SessionOption $SessionOption -ErrorAction SilentlyContinue -ErrorVariable SessionErrors

# 并行执行命令获取打印机信息
$PrinterData = Invoke-CimCommand -CimSession $CimSessions -ScriptBlock {
    # 在远程机器上执行的逻辑,同样指定属性
    Get-CimInstance -ClassName Win32_Printer -Property 'Name', 'DriverName', 'PortName', 'Shared', 'ShareName', 'Default'
} -ErrorAction SilentlyContinue -ErrorVariable CommandErrors

# 整理正常返回的结果
$FinalResults = $PrinterData | Select-Object `
    @{Name='ComputerName'; Expression={$_.PSComputerName}},
    @{Name='PrinterName'; Expression={$_.Name}},
    DriverName,
    PortName,
    @{Name='IsShared'; Expression={$_.Shared}},
    ShareName,
    @{Name='IsDefault'; Expression={$_.Default}}

# 添加会话创建失败的机器记录
foreach ($err in $SessionErrors) {
    $FinalResults += [PSCustomObject]@{
        ComputerName = $err.TargetObject
        PrinterName  = "⚠️ 会话创建失败"
        ErrorMessage = $err.Exception.Message
        DriverName   = $null
        PortName     = $null
        IsShared     = $null
        ShareName    = $null
        IsDefault    = $null
    }
}

# 添加命令执行失败的机器记录
foreach ($err in $CommandErrors) {
    $FinalResults += [PSCustomObject]@{
        ComputerName = $err.TargetObject
        PrinterName  = "⚠️ 命令执行失败"
        ErrorMessage = $err.Exception.Message
        DriverName   = $null
        PortName     = $null
        IsShared     = $null
        ShareName    = $null
        IsDefault    = $null
    }
}

# 输出结果到CSV
$FinalResults | Export-Csv -Path "C:\Scripts\Parallel_Printer_Report.csv" -NoTypeInformation

# 清理CIM会话
Remove-CimSession -CimSession $CimSessions

关键注意事项

  1. 错误处理是核心:之前丢失整台机器信息,大概率是因为没有捕获CIM连接/执行的错误,上面的脚本会把所有失败的机器都记录下来,你可以清楚看到哪些机器出了问题。
  2. 属性显式指定:CIM默认返回的属性可能比WMI少,所以一定要用-Property参数指定你需要的所有属性,确保和WMI返回的信息一致。
  3. 会话重用:创建CIM会话比每次调用Get-CimInstance重新连接高效得多,尤其是处理大量机器时,一定要重用会话。

内容的提问来源于stack exchange,提问作者fausty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:38:22