Запуск ‘Start-Process’ удаленно: как отобразить стандартный вывод?

Вопрос или проблема

У меня есть скрипт PowerShell для установки программного обеспечения на удаленные компьютеры.

На сегодняшний день я успешно использую следующий код:

$prog = "ping"
$arg = "localhost"
$computername = "MACHINE01"
invoke-command -computername $computername {param($p,$a)& $p $a} -ArgumentList $prog,$arg

Теперь мне нужно установить MSI, например, ‘msiexec /i c:\file.msi /passive’.

Я не могу заставить MSIEXEC воспринимать все после ‘MSIEXEC’ как параметры. Вместо этого PowerShell пытается выполнить это как одну большую команду. Я пробовал множество вещей, в основном связанных с размещением литералов в кавычках, но не смог заставить это работать.

Я сейчас отказался от оператора вызова (&) в пользу ‘Start-Process’, который имеет параметр ‘-ArgumentList’. MSI теперь выполняется корректно. Отлично!

invoke-command -computername $computername {param($p,$a) start-process $p -argumentlist $a -nonewwindow -wait -redirectstandardoutput c:\output.txt; get-content c:\output.txt} -ArgumentList $prog,$arg

Проблема с ‘Start-Process’ в том, что он не выводит никакого консольного вывода, когда запускается удаленно с использованием ‘Invoke-Command’. Мне пришлось прибегнуть к перенаправлению вывода в файл, а затем чтению файла. Есть ли лучший способ?

Я бы попробовал передать это в командлет tee-object, а затем сохранить ваш файл там, если это необходимо (не знаю, сработает ли отправка вывода файла в $null, жаль, что это не linux, и мы не можем отправить это в /dev/null, но я отвлекся)

Это командлет tee-object http://technet.microsoft.com/en-us/library/ee177014.aspx

invoke-command -computername $computername {param($p,$a) start-process $p -argumentlist $a -nonewwindow -wait | tee-object -file c:\output.txt} -ArgumentList $prog,$arg

это непроверенный код, но в общем-то это именно то, что вам нужно.

invoke-command -computername $computername {param($p,$a) start-process $p -argumentlist $a -nonewwindow -wait | tee-object -file $null} -ArgumentList $prog,$arg

тоже может сработать.

Ответ или решение

Для выполнения команды Start-Process удалённо и получения стандартного вывода при использовании PowerShell, необходимо учитывать несколько важных аспектов. Когда вы запускаете процессы удалённо с помощью Invoke-Command, стандартный вывод и стандартные ошибки не отображаются в консоли вызова. Вместо этого рекомендуется использовать перенаправление вывода в файл или использовать команды, которые позволяют отправлять вывод обратно в консоль.

Решение проблемы с выводом при использовании Start-Process

Ваш текущий подход с Start-Process является корректным, однако, как вы уже заметили, он не возвращает вывод непосредственно в консоль. Чтобы решить эту проблему, вы можете воспользоваться несколькими альтернативными методами. Я предложу несколько решений:

1. Использование Pipe и Tee-Object

Вы можете использовать Tee-Object, который позволяет захватывать вывод и одновременно отправлять его в файл. Пример кода может выглядеть следующим образом:

$prog = "msiexec"
$arg = "/i C:\file.msi /passive"
$computername = "MACHINE01"

Invoke-Command -ComputerName $computername {
    param($p, $a)
    Start-Process $p -ArgumentList $a -NoNewWindow -Wait | Tee-Object -FilePath C:\output.txt
} -ArgumentList $prog, $arg

Этот код устанавливает MSI-приложение и записывает весь вывод в файл C:\output.txt. Кроме того, если вы хотите видеть вывод в консоли, вы можете просто пропустить создание файла или сохранить его для последующего анализа.

2. Использование -RedirectStandardOutput

Если вы хотите сохранить вывод в файл и одновременно выводить его в консоль, используйте опцию -RedirectStandardOutput:

Invoke-Command -ComputerName $computername {
    param($p, $a)
    Start-Process $p -ArgumentList $a -NoNewWindow -Wait -RedirectStandardOutput C:\output.txt
    Get-Content C:\output.txt
} -ArgumentList $prog, $arg

Этот метод сохраняет вывод в файл и затем выводит его с помощью Get-Content, что позволяет вам просматривать результат выполнения сразу после завершения процесса.

3. Использование Invoke-Expression

Если вы хотите избежать проблем с передачей аргументов и стандартного вывода, можно использовать Invoke-Expression. Однако, это может быть менее безопасно, так как оно выполняет строку как команду. Пример:

$command = 'msiexec /i C:\file.msi /passive'

Invoke-Command -ComputerName $computername {
    param($cmd)
    Invoke-Expression $cmd
} -ArgumentList $command

Заключение

Хотя Start-Process не выводит штатный вывод и ошибки в консоль при удалённом запуске, существуют эффективные методы для обработки этого ограничения. Использование Tee-Object, перенаправление вывода и другие техники позволяют вам продолжать работать независимо от сложности задачи. Правильный подход обеспечит как сохранение логов, так и возможность видеть вывод в реальном времени, что упрощает администрирование и диагностику в вашей среде.

Оцените материал
Добавить комментарий

Капча загружается...