Powershell / cmd - перенаправление потоков вывода встроенного скрипта в файл - PullRequest
1 голос
/ 05 июля 2019

У меня есть ситуация, когда сценарий cmd должен запустить сценарий powershell (install.ps1), поднявшись до уровня admin, если cmd еще нет.Строка, которая запускает PowerShell, выглядит следующим образом:

powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass -File `\"%~dp0install.ps1`\" %args%\" -Verb runAs -Wait"

Или это также работает:

powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass invoke-command { %~dp0install.ps1 %args% } \" -Verb runAs -Wait"

Я бы хотел перенаправить вывод из сценария install.ps1 в файл дляцели ведения журнала, но возникли проблемы с этим.Что-то вроде следующего создаст файл log.txt, но вывод все равно будет отображаться в консоли, а полученный файл log.txt будет пустым:

powershell -WindowStyle Hidden "Start-Process powershell \"-NoP -Exec Bypass invoke-command { %~dp0install.ps1 %args% } \" *> log.txt -Verb runAs -Wait"

Перемещение части *> log.txt внутрьБлок Start-Process (сразу после блока invoke-command), который я считал ключевым, кажется, даже не запускает скрипт вообще (или он слишком быстро замечает ошибку в консоли, потому что он немедленно закрывается).

Возможно ли добиться такого поведения при ведении журнала, когда нужные мне данные находятся в паре слоев PowerShell, выполняемых файлом cmd?

Технически мы добились этого, создавсценарий оболочки PowerShell, который вызывается / повышается с помощью cmd, затем внутри оболочки вызывается сценарий install.ps1 и назначается регистрация в этом вызове.К сожалению, дополнительный слой сценария вызывает кучу других хитрых / более критических проблем, связанных с передачей аргументов в командной строке вплоть до самого сценария установки, поэтому мы действительно стараемся избегать этого маршрута.

EDIT

Спасибо @ mklement0 за указатель на необходимость перенаправления, что было моей проблемой.Дополнительный вопрос - следующая команда прекрасно работает для записи в файл, но есть ли способ получить то же поведение, используя -File, а не -Command при вызове сценария PS ("-Command% ~ dp0pg.ps1")?

powershell -Command "Start-Process -WindowStyle Hidden -Verb RunAs -Wait powershell \"-NoProfile -ExecutionPolicy Bypass -Command %~dp0pg.ps1 *^> %CD%\log.txt\""

1 Ответ

2 голосов
/ 05 июля 2019

Перемещение перенаправления *>log.txt в блок Invoke-Command работает в принципе , но ваша проблема в том, что в Windows PowerShell (в отличие от PowerShell Core ) процесс вызывается с помощью повышение прав (как администратор), через -Verb RunAs, по умолчанию C:\Windows\System32 в качестве рабочего каталога , а не рабочий номер вызывающего абонента .

Помимо того факта, что вы, вероятно, не хотели создавать файл журнала в C:\Windows\System32, команда не удастся , потому что запись в это местоположение требует, чтобы вызывающий уже был повышен.

Самое простое решение - перенаправить *> в файл, указанный с полным путем вместо:

powershell -Command "Start-Process -WindowStyle Hidden -Verb RunAs -Wait powershell \"-NoProfile -ExecutionPolicy Bypass -Command %~dp0pg.ps1 *^> %CD%\log.txt\""

Примечание:

  • Нет необходимости в Invoke-Command - просто вызовите файл *.ps1 напрямую;однако я добавил -Command, чтобы сделать более очевидным, что остальная часть командной строки должна интерпретироваться как код PowerShell (не путь к файлу сценария только с аргументами).

  • Поскольку > является метасимволом cmd.exe, его необходимо экранировать как ^>, чтобы его можно было передать через в PowerShell - возможно, что удивительно, cmd.exe считает > без кавычек , потому что он не распознает последовательности \" как встроенные двойные кавычки - это делает только PowerShell.

  • Как в исходной командеПредполагается, что ни %~dp0, ни папка командного файла dir.путь - ни %CD% - рабочий директор вызывающего абонента.путь - содержит пробелы или другие специальные символы.это потребовало бы дополнительного цитирования / экранирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...