Ваш симптом говорит о том, что целевой компьютер-нарушитель просто недоступен , например, из-за того, что он отключен от сети или выключен.
Ваш кодне имеет отношения к этому сценарию, но в остальном он корректен с точки зрения типов данных (хотя, учитывая, что свойство .Name
имеет тип [string]
, и вы использовали Select-Object -ExpandProperty
, $obj
уже представляет собой массив строки, следовательно, $item
является одной строкой в цикле foreach
, нет необходимости в отдельной переменной $itemString
, полученной с помощью .ToString()
).
Примечание: я предполагаючто значение свойства .Name
достаточно для идентификации компьютера в вызове Get-WmiObject
;если это не так, используйте Select-Object -ExpandProperty DNSHostName
.
Как правило, обратите внимание, что параметр Get-WmiObject
-ComputerName
имеет тип [string[]]
, так что вы можете напрямую передать массив имен хостов к нему.
Однако, к сожалению, [System.Management.Automation.ErrorRecord]
экземпляры, созданные Get-WmiObject
, когда целевой компьютер недоступен, не содержат имя компьютера-нарушителя, поэтому использование одной команды с последующей проверкой вывода ошибок не является(хотя см. альтернативу Get-CimInstance
внизу).
Имея это в виду, вот решение на основе петель PSv3 + , которое обрабатывает недоступные компьютеры изящно :
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])"
}
}
Для сравнения Get-CimInstance
- рекомендуется вместо Get-WmiObject
, так как его введение в PSv3 - делает добавление информации о происхождении в записи ошибок, поэтому a одного достаточно вызова Get-CimInstance
- обратите внимание, что результаты не гарантируются в том же порядке, в котором были указаны компьютеры, но вы получаете выгоду от параллельно исполнение .
# Use a single Get-CimInstance call to target all computers and
# quietly collect errors for later analysis.
$computerNames = (Get-ADComputer -Filter 'Name -like "L*"' -Properties *).Name
Get-CimInstance -ErrorAction SilentlyContinue -ErrorVariable errs `
-ComputerName $computerNames -Class Win32_ComputerSystem | #`
ForEach-Object {
"Computer: $($_.Name) Username: $(($_.UserName -split '\\')[-1])"
}
# Analyze the errors that occurred, if any.
$errs | ForEach-Object {
if ($_.Exception -is [Microsoft.Management.Infrastructure.CimException] -and $_.CategoryInfo.Category -eq 'ConnectionError') {
Write-Warning "Computer is unavailable: $($_.OriginInfo.PSComputerName)"
} else { # unexpected error, pass it through
Write-Error $_
}
}