Get-WmiObject在foreach循环中无法正常运行

时间:2017-08-22 20:37:20

标签: powershell recordset get-wmiobject

我目前正在尝试编写一个脚本,其中列出了加入我们域的计算机列表,逐个迭代它们以检查它们是否存在于我创建的Access数据库中,对它们运行WMI查询以收集它们的系统信息,并将数据添加到数据库(如果它们尚未包含在数据库中)。我在大多数计算机上都能成功(大约一半),但有些人说没有找到RPC服务器。

我知道其中一些错误是由于计算机处于脱机状态(防火墙已禁用且启用了WMI查询)。问题是有些计算机在线,当我在脚本中对它们运行Get-WmiObject命令时,我得到了RPC服务器错误,但当我在脚本之外单独运行命令时,我能够成功查询信息。我发布了导致奇怪行为的功能,并希望有更多编程知识的人能够找到我正在做的noob错误。

第二个问题是在第一次迭代后我得到以下错误,说明空白CompName字段?前两次迭代按预期工作,然后只是在"计算机已经存在"之后就抛出了一堆这些错误。

Snippet of Error

function Update-Systems {
    $PSCredential = Get-Credential
    $Comp = (Get-ADComputer -Filter * | select -ExpandProperty Name)

    foreach ($Computer in $Comp) {
        $RecordSet.MoveFirst()
        $RecordSet.Find("CompName = '$Computer'")
        $RecordCheck = $RecordSet.Fields.Item("CompName").Value

        if (!$RecordCheck) {
            "Collecting Data for $Record"
            $SystemProp = Get-WmiObject -Class Win32_ComputerSystem -Credential $PSCredential -ComputerName: $Computer -ErrorAction SilentlyContinue 
            $RecordSet.Addnew()
            $RecordSet.Fields.Item("DateRan") = Get-Date
            $RecordSet.Fields.Item("Domain") = $SystemProp.Domain
            $RecordSet.Fields.Item("CompName") = $SystemProp.Name
            $RecordSet.Fields.Item("Model") = $SystemProp.Model
            $RecordSet.Fields.Item("Manufacturer") = $SystemProp.Manufacturer
            $RecordSet.Update()
        } else {
            "Computer already exists"
        }
    }
}

1 个答案:

答案 0 :(得分:0)

很可能Get-WmiObject无法从远程计算机查询信息。由于您指示cmdlet仅在发生错误(-ErrorAction SilentlyContinue)时继续运行,因此变量$SystemProp在发生错误时结束为空,因为$SystemProp.Name计算为$null也是。

您可以通过将$Computer而不是$SystemProp.Name分配给记录集来解决此问题,至少作为这样的后备:

$RecordSet.Fields.Item("CompName") = if (-not $SystemProp) {
    $Computer
} else {
    $SystemProp.Name
}

但是,更好的方法是进行适当的错误处理:

$ErrorActionPreference = 'Stop'
try {
    $SystemProp = Get-WmiObject -Class Win32_ComputerSystem -Credential $PSCredential -ComputerName $Computer
    $RecordSet.AddNew()
    $RecordSet.Fields.Item("DateRan")      = Get-Date
    $RecordSet.Fields.Item("Domain")       = $SystemProp.Domain
    $RecordSet.Fields.Item("CompName")     = $SystemProp.Name
    $RecordSet.Fields.Item("Model")        = $SystemProp.Model
    $RecordSet.Fields.Item("Manufacturer") = $SystemProp.Manufacturer
} catch {
    Write-Error $_ -ErrorAction Continue
}

在放弃之前你也可以retry几次。