Запуск сценария .ps1 из PowerShell с параметрами и учетными данными и получение результатов из него

Я думаю, что моя проблема имеет простое решение. Но сейчас я немного запутался. У меня есть Java-код, который запускает 1 скрипт Powershell. Этот скрипт PowerShell должен запускать другие скрипты.
Java ->
Powershell.ps1 ->
Script1.ps1 Script2.ps1 Script3.ps1 Скрипт ....

Script1,2, .. и т.д., выполняющие несколько задач и возвращающие строковые значения.

Я пробовал Start-Process, Invoke-Command и Invoke-Expression

Предполагая, что script1.ps1:

$a = 1+2
$a

Start-Process будет работать лучше для меня, но я не получаю вывод:

$arguments = "C:..script1.ps1" + " -ClientName" + $DeviceName
$output = Start-Process powershell -ArgumentList $arguments -Credential $credentials
$output 

$ output ist NULL.

Большое спасибо!

Всего 1 ответ


Start-Process производит вывод по умолчанию.

(Единственный способ заставить его производить вывод напрямую - это использовать -PassThru , который затем не возвращает вывод скрипта , а экземпляр System.Diagnostics.Process представляющий вновь созданный процесс - см. Ниже.)

Единственный способ получить выходные данные из вашего скрипта через Start-Process - это использовать -RedirectStandardOutput и
-RedirectStandardError параметры для захвата вывода скрипта в виде текста , в файлах . [1]

Затем вы можете прочитать эти файлы в PowerShell после завершения нового процесса , что можно обеспечить одним из двух способов:

  • Также -Wait ключ -Wait в Start-Process , чтобы сделать вызов синхронным, что означает, что при Start-Process выходные данные уже были записаны в указанные файлы.

  • Используйте -PassThru для получения экземпляра System.Diagnostics.Process и последующей передачи его в Wait-Process (или используйте его .WaitForExit() напрямую; свойство .HasExited можно использовать для проверки того, что процесс все еще выполняется).

Вот что может работать в вашей ситуации:

$arguments = "-File C:...script1.ps1" + " -ClientName" + $DeviceName

# Launch the script in a new window running as the given user,
# capture its standard output in file ./out.txt,
# and wait for it to finish.
Start-Process -Wait -RedirectStandardOutput ./out.txt powershell -ArgumentList $arguments -Credential $credentials

"Running script1.ps1 produced the following output:"
Get-Content ./out.txt

К сожалению, интерфейс командной строки PowerShell сообщает обо всех 6 выходных потоках PowerShell через стандартный вывод (см. Этот ответ ), поэтому вышеизложенное фиксирует все выходные данные из вашего сценария, включая вывод ошибок.

Однако вы можете использовать, например, -RedirectStandardError ./err.txt для отдельного захвата потока ошибок.


[1] Вызов другого экземпляра PowerShell через его CLI предлагает структурированную альтернативу записи неструктурированного текста (вывод для отображения, как при печати на консоль, что происходит по умолчанию):

-OutputFormat xml (или -of xml / -o xml ) заставляет PowerShell форматировать свои выходные данные в формате CLIXML, который является тем же форматом сериализации на основе XML, который используется в удаленном взаимодействии PowerShell и фоновых заданиях для сериализации богатых объектов , которые можно «перетекать» с помощью более Import-Clixml вызов Import-Clixml .

Примечание. Для большинства сложных объектов потеря точности типов : то есть они сериализуются как эмуляции исходных объектов; короче говоря, как «свойство сумки» без методов, которые, однако, может быть достаточно - см. этот ответ .

Вот краткая демонстрация с использованием экземпляра [datetime] , который десериализуется с верностью типа:

Start-Process -Wait -RedirectStandardOutput ./out.xml powershell '-of xml -c Get-Date'

"Type of the CLIXML-serialized and deserialized `Get-Date` output:"
(Import-CliXml ./out.xml).GetType().FullName # -> System.DateTime

Есть идеи?

10000