我正在尝试获取所有计算机的列表并为每台计算机登录用户。
我获得了计算机列表,当我查询返回的每个字符串时,都可以获得登录的用户。
但是,当我使用计算机名称变量来获取所有用户时-我收到一条错误消息,提示我的变量未知。我尝试将计算机名称转换为字符串,但这无济于事。
顺便说一句,这是我输入错误的计算机名称时出现的相同错误,所以它与变量#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
答案 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