Get-WmiObject不处理键入的变量

时间:2018-11-26 16:06:17

标签: powershell active-directory

我正在尝试获取所有计算机的列表并为每台计算机登录用户。

我获得了计算机列表,当我查询返回的每个字符串时,都可以获得登录的用户。

但是,当我使用计算机名称变量来获取所有用户时-我收到一条错误消息,提示我的变量未知。我尝试将计算机名称转换为字符串,但这无济于事。

顺便说一句,这是我输入错误的计算机名称时出现的相同错误,所以它与变量#item的类型有关,当我打印出变量时它是正确的,但不能在内部使用循环。

$obj = Get-ADComputer -Filter 'Name -like "L*"' -Properties * | Select -ExpandProperty Name
foreach ( $item in $obj ) { 
    $itemString = $item.ToString()
    $user = Get-WmiObject –ComputerName $itemString –Class Win32_ComputerSystem | Select-Object UserName | select -expandproperty UserName -first 1
    $user = $user.SubString(8)
    write-output "Computer: $itemString Username: $user" 

}
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At N:\Foreach.ps1:4 char:13
+     $user = Get-WmiObject –ComputerName $itemString –Class Win32_Comp ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

1 个答案:

答案 0 :(得分:3)

您的症状表明,有问题的目标计算机根本是不可用 ,例如由于与网络断开连接或已断电。

您的代码无法处理这种情况,但是在数据类型方面是正确的(尽管假设.Name属性是[string]类型,并且您使用过{{1} },Select-Object -ExpandProperty已经是一个字符串数组,因此,$obj$item循环中的单个字符串,因此不需要通过{获得一个单独的foreach变量{1}}。

注意:我假设$itemString属性值足以识别.ToString()调用中的计算机;如果不是,请使用.Name

通常,请注意,Get-WmiObject的{​​{1}}参数是Select-Object -ExpandProperty DNSHostName类型的,因此您可以直接将主机名的 array 传递给它。

但是,令人遗憾的是,Get-WmiObject在目标计算机不可用时创建的-ComputerName实例不包含有问题的计算机名称,因此使用单个命令进行以后的错误输出检查不会一个选项(尽管请参阅底部的[string[]]替代项)。

请牢记这一点,这是一个基于PSv3 +循环的解决方案,它优雅地处理了不可用的计算机

[System.Management.Automation.ErrorRecord]

相比之下, Get-WmiObject -由于它是PSv3中引入的,因此推荐而不是Get-CimInstance-确实将原始信息添加到错误记录中,因此< strong> foreach ($computer in (Get-ADComputer -Filter 'Name -like "L*"' -Properties *).Name) { $computerInfo = Get-WmiObject -ErrorAction SilentlyContinue -ComputerName $computer -Class Win32_ComputerSystem if (-not $?) { # Call failed, analyze the reason. if ($Error[0].Exception.HResult -eq 0x800706BA) { # unavailable # Merely issue a *warning*. # Alternatively, collect the unavailable names in an array for later use. Write-Warning "Computer is unavailable: $computer" } else { # unexpected error, pass it through Write-Error $Error[0] } } else { # success "Computer: $($computerInfo.Name) Username: $(($computerInfo.UserName -split '\\')[-1])" } } 单个调用就足够-请注意,不能保证结果按指定的计算机顺序到达,但是您确实可以从中受益来自 parallel 执行

Get-CimInstance