Обработка ошибок в ScriptBlock в Командлете Invoke-Command

Я пытаюсь установить службу на удаленной машине с помощью powershell.

пока у меня есть следующие:

Invoke-Command -ComputerName  $remoteComputerName -ScriptBlock {
         param($password=$password,$username=$username) 
         $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
         $credentials = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
         New-Service -Name "XXX" -BinaryPathName "c:XXX.exe" -DisplayName "XXX XXX XXX" -Description "XXXXXX." -Credential $credentials -ErrorVariable errortext 
         Write-Host("Error in: " + $errortext)
        } -ArgumentList $password,$username -ErrorVariable errortext 


Write-Host("Error out: " + $errortext)

когда есть ошибка при выполнении New-Service $ errortext ErrorVariable правильно устанавливается внутри ScriptBlock, потому что текст: "ошибка в: показывает мне ошибку.

ErrorVariable команды Invoke-не получает set (который я ожидал).

мой вопрос:

это как-то можно установить ErrorVariable команды Invoke на ошибку, которую я получил внутри ScriptBlock?

Я знаю, что могу также использовать InstalUtil, WMI и SC для установки службы, но это не актуально на данный момент.

3 ответов


нет, вы не можете получить Errorvariable С Invoke-Command вызов должен быть установлен так же, как в scriptblock.

но если ваша цель - " обнаружить и обработать ошибки в scriptblock, а также получить ошибки, возвращенные в контекст Invoke-Command caller " тогда просто сделайте это вручную:

$results = Invoke-Command -ComputerName server.contoso.com -ScriptBlock {
   try
   {
       New-Service -ErrorAction 1
   }
   catch
   {
       <log to file, do cleanup, etc>
       return $_
   }
   <do stuff that should only execute when there are no failures>
}

$results теперь содержит информацию об ошибке.


список аргументов Invoke-Command-это односторонняя сделка. Вы можете либо вывести переменную ошибки в скрипте, например, в последней строке ScriptBlock put:

$errortext

или еще лучше, просто не фиксируйте ошибку через-ErrorVariable вообще. Вывод scriptblock, включая ошибки, будет возвращаться вызывающему абоненту даже через удаленное соединение.

C:\> Invoke-Command -cn localhost { Get-Process xyzzy } -ErrorVariable errmsg 2>$null
C:\> $errmsg
Cannot find a process with the name "xyzzy". Verify the process name and call the cmdlet again.
    + CategoryInfo          : ObjectNotFound: (xyzzy:String) [Get-Process], ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
    + PSComputerName        : localhost

В общем, я думаю, что гораздо лучше держать ошибки в потоке ошибок, отделенном от нормального выход.


в самом строгом смысле, я считаю, что ответ Нет, вы не можете установить ErrorVariable Invoke-Command для содержимого ErrorVariable внутри блока скрипта. ErrorVariable только для команды, к которой он прикреплен.

однако вы можете передать переменную в блоке скрипта в область Invoke-Command. В коде вы запускаете команду New-Service с помощью -ErrorVariable errortext. Вместо этого создайте переменную в области "script", предваряя имя переменной " script:", например это: -ErrorVariable script:errortext. Это делает переменную доступной как снаружи блока скрипта, так и внутри.

Теперь ваша последняя строка Write-Host("Error out: " + $errortext) выведет ошибку, которая была сгенерирована внутри блока скрипта.

дополнительная информация здесь и здесь.