#powershell #powershell-remoting #powershell-jobs
Вопрос:
Я пытаюсь выполнить довольно простую команду на 20 серверах параллельно. Что у меня есть до сих пор, так это :
$servers = @()
$servers = (
"server1",
"server2",
"server3",
"server4",
"server5",
"server6"
)
$jobs = foreach($server in $servers){
try{
$pw = convertto-securestring -AsPlainText -Force -String MyPassword
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "DomainMyuser",$pw
Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock { Get-WmiObject -Class Win32_Product | select Name, Version, Vendor | Sort-Object -Property Vendor | where Name -EQ "New Relic Infrastructure Agent" } -AsJob
}
catch{
write-output "ERROR : Failed to connect to server $($server)"
$_.Exception.Message
$Error[0].Exception.PSObject.Properties | select Name,Value | FL *
}
}
get-job
While ($(Get-Job -State Running).count -gt 0){
start-sleep 1
}
foreach($job in Get-Job){
$results= Receive-Job -Id ($job.Id)
}
$results | select PSComputerName, Version | Sort-Object -Property Version | Format-Table -AutoSize
Get-job | Remove-Job -force
ОБНОВЛЕНИЕ: Я обновил приведенный выше код до того, что у меня есть в настоящее время.
Сейчас происходит то, что я получаю один результат для одного сервера. другие задания просто отменены или не закончены, я не уверен.
Я включил предложения из комментариев, но, похоже, я все еще не совсем там. Есть какие-нибудь идеи?
Комментарии:
1. Зачем использовать сеанс(ы) для этого, когда
Invoke-Command
также есть параметры-ComputerName
и —Credential
? Тем более, что ты, похоже, никогда этого не делаешьDisconnect-PSSession
… Кстати, старайтесь не использовать=
объединение в массив. Используйте$jobs = foreach($server in $servers){...}
вместо этого, и пусть PowerShell соберет результаты.2. Это все еще происходит, если вы переместите server5 вверх по списку? Я не думаю, что существует такой низкий лимит на сеансы. Мне кажется, что что-то идет не так,
New-PSSession
когда вы попадаете на пятый сервер в списке. Вам нужно будет проверить значение переменной перед запускомInvoke-Command
. Когда вы получите сообщение об ошибке, вы можете$Error[0].Exception.PSObject.Properties | select Name,Value | FL *
запросить более подробную информацию о том, что происходит не так (если есть внутреннее исключение, которое вы можете вставитьInnerException.
послеException.
, чтобы просмотреть его детали/трассировку стека, а затем$Error[1]
и т. Д.3. Этот захват ошибок очень полезен, спасибо! Это показало мне, что он не может найти сервис, который я ищу, на этом ящике, так вот в чем была ошибка! И я также удалил создание сеанса, и теперь, похоже, это работает параллельно. Я действительно получаю ошибку на одном из серверов, которая, похоже, работает, если я войду локально и выполню сценарий, поэтому не уверен, почему это не удается: WinRM не может завершить операцию. Убедитесь, что указанное имя компьютера является допустимым, что компьютер доступен по сети…
4. Похоже, у вас есть какие-то сетевые подключения для расследования. Убедитесь, что вы можете подключиться по 5985 с компьютера, на котором выполняется код, к серверу.
5. Я добавил последний приведенный выше код, включающий все предложенные изменения. Все еще работает не так, как ожидалось!