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

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

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

Я пробовал 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 Ответ

1 голос
/ 27 марта 2020

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

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

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

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

  • Также передайте переключатель -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 своим выводом в формате CLI XML, который является тот же формат сериализации на основе XML, используемый в удаленном взаимодействии PowerShell и фоновых заданиях для serializi нг богатые объекты , которые вы можете "регидрировать" с последующим Import-Clixml вызовом .

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

Вот краткая демонстрация с использованием экземпляра [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
...