Я попытаюсь объяснить здесь вариант использования. Пишу скрипт для автоматизации управления удаленными сервисами. Это можно легко сделать с помощью sc.exe через командную строку. Однако этот вариант использования заключается в написании сценария через Powershell.
На данный момент у меня есть следующее:
Start-Process cmd.exe -ArgumentList "/c runas.exe /netonly /user:$username cmd.exe"
Переменная $username уже установлена и имеет формат домен\имя пользователя. Вышеуказанное работает. Появляется всплывающее окно cmd с предложением ввести пароль (было бы здорово, если бы полные учетные данные можно было передать через Get-Credential, включая пароль, но я понимаю последствия этого для безопасности). После ввода пароля и нажатия клавиши Enter откроется новое окно командной строки, запускаемое от имени данного пользователя. Именно в этом новом окне мы хотим запустить:
sc.exe \\$target query
Опять же, переменная $target уже установлена. Однако цель здесь не в том, чтобы пользователь вручную запускал эту команду. Надеялись передать эту команду через начальную команду Start-Process в надежде, что единственным действием пользователя, выполняемым вручную, будет ввод пароля.
Мне не очень повезло с осуществимостью этого. Является ли это возможным? Конечной целью, как мы надеемся, будет передача команды sc.exe и принятие мер по ее выводу (были ли возвращены службы? отлично, теперь сделайте «это»...)
Вам не нужно cmd.exe
вызывать runas.exe
— просто вызовите последний напрямую.
Поскольку runas.exe
запускает целевую программу асинхронно, вам также не нужен Start-Process - если только вы не хотите дождаться выхода целевой программы, запущенной runas.exe
.
Если вы хотите запустить процесс cmd.exe
от имени другого пользователя с помощью команды, используйте опцию /C
или /K
последнего, за которой следует однострочная командная строка; /C
выполняет командную строку, а затем выходит (тем самым закрывая окно), тогда как /K
сохраняет cmd.exe
вводит интерактивный сеанс после выполнения командной строки (тем самым оставляя окно открытым).
Поэтому используйте что-то вроде следующего, чтобы асинхронно запустить процесс cmd.exe
от имени данного пользователя, выполнить указанную команду и войти в интерактивный сеанс:
runas.exe /netonly /user:$username "cmd.exe /K sc.exe \\$target query"
Если вы хотите дождаться завершения процесса cmd.exe
и сделать это сразу после выполнения указанной команды, используйте опцию Start-Process -Wait
и cmd.exe
/C
; однако учтите, что для проверки результатов вам необходимо перенаправить вывод cmd.exe
в файл; например.:
# Note the use of /C rather than /K and
# >out.txt 2>&1 to capture both stdout and stderr output in file "out.txt"
Start-Process -Wait runas.exe "/netonly /user:$username `"cmd.exe /C sc.exe \\$target query >out.txt 2>&1`""
# Now you can examine file "out.txt" for the results.
С удовольствием, @sbagnato. Боюсь, вам придется использовать файл. Start-Process
не имеет прямого вывода (за исключением случая, когда вы используете -PassThru
, но тогда вы получаете объект информации о процессе в качестве вывода), поэтому вы не можете использовать -ov
(-OutVariable
). Start-Process
предлагает -RedirectStandardOutput/Error
захватить выходные данные запущенного процесса, но эти параметры также могут быть нацелены только на файлы. В >
ожидается улучшение: вы сможете делать что-то вроде > variable:out
(см. GitHub PR #20381, но с Start-Process
это не поможет.
Ах, окей, я понимаю. С файлом все в порядке, потому что я все равно могу получить содержимое файла и использовать регулярное выражение для поиска по мере необходимости. Еще раз спасибо.
Потрясающе, спасибо. На самом деле я читаю еще один комментарий, который вы предоставили кому-то относительно использования -ov для передачи вывода в переменную. Однако я не могу понять, где в приведенной выше строке я бы это добавил.