#powershell #invoke-command
#powershell #invoke-command
Вопрос:
Мне нужно получить некоторую информацию от клиентов с помощью «invoke-command», и я начал писать сценарий для запроса компьютеров из AD, помещать их в переменную, использовать переменную для проверки того, какие компьютеры подключены к сети или оффлайн, помещать статус в хеш-таблицу, а затем запускать invoke-command только на компьютерах в Сети. Работая над этим, я подумал, что было бы проще не использовать хэш-таблицу, вместо этого выполнить foreach test-connection непосредственно перед выполнением invoke-command. Итак, я клонировал и переписал. Теперь оба сценария завершены, и мне интересно, почему «invoke-command» выполняется намного медленнее после цикла «ForEach Test-connection», тогда как в моем другом сценарии это только половина времени. Кроме того, параметр -ErrorVariable также не работает. Вот что я имею в виду:
Measure-Command {
#########################################################################################
# Check Computerstatus and put into hashtable
#########################################################################################
$computerstatus = @{}
ForEach ($computer in $adcomputers) {
$result = Test-Connection $computer -Count 1 -quiet
If ($result) {$computerstatus.add( $computer, 'online')}
else {$computerstatus.add( $computer, 'offline')}
}
# Read hashtable and set Online/Offline variable:
$computersonline = Foreach ($Key in ($computerstatus.GetEnumerator() | Where-Object {$_.Value -eq "online"})) {$Key.name}
$computersoffline = Foreach ($Key in ($computerstatus.GetEnumerator() | Where-Object {$_.Value -eq "offline"})) {$Key.name}
#########################################################################################
# Now run the invoke-command on online computers
#########################################################################################
$remotequery = Invoke-command -ComputerName $computersonline -ErrorAction SilentlyContinue -ErrorVariable MyErrorVar4InvCmd -scriptblock {remote-command} | select Property | where Property -match 'True'
$cantaccess = $MyErrorVar4InvCmd.TargetObject
} # end measure-command
Общее количество секунд: 34 9779497 и » $ cantaccess = $ MyErrorVar4InvCmd.targetObject» отображается правильно
И другой, медленный, подход:
Measure-Command {
#########################################################################################
# Now run the invoke-command
#########################################################################################
$queryresult = @() # create blank array, it will get filled with =
$CompOFFLINE = @()
ForEach ($computer in $adcomputers) {
if (Test-Connection $computer -Count 1 -quiet) {
$remotequery = Invoke-command -ComputerName $computer -ErrorAction SilentlyContinue -ErrorVariable MyErrorVar4InvCmd -scriptblock {remote-command} | select Property | where Property -match 'True'
if ($remotequery.Property -eq 'true') {
$queryresult = $computer
}
else {
}
}
else {
$CompOFFLINE = $computer
}
}
$cantaccess = $MyErrorVar4InvCmd.TargetObject
} # end measure-command
Общее количество секунд: 107 4585155 и «$ cantaccess = $ MyErrorVar4InvCmd.targetObject» пусто…
Спасибо, Роберт
Комментарии:
1. 2-й выполняется медленно, потому что вы используете
=
в массиве. это создает НОВЫЙ массив каждый раз, когда вы добавляете к нему… массивы имеют фиксированный размер , поэтому для добавления к одному требуется создание нового, большего размера.2. вы можете значительно ускорить процесс, используя
-Computer
параметрInvoke-Command
… он принимает набор имен компьютеров и scriptblock для запуска в этих системах… параллельно .3. спасибо за объяснение. что касается предложения по скорости: я уже работаю с массивом компьютеров (в $ adcomputers) 😉
4. добро пожаловать! [ усмешка ] ///// ваш
ForEach ($computer in $adcomputers)
не выполняет ничего параллельно . он запускает их по одному за раз — и он запускает их локально. если вы используетеInvoke-Command
и передаете ему список систем в виде списка … вы будете запускать блоки сценариев параллельно и в целевых системах . это значительно ускорит работу, если у вас есть значительное количество систем для работы. [ усмешка ]5. теперь я понимаю, что вы имеете в виду. Спасибо 🙂