Выполнение приложения HTA ​​через PSEXEC с аргументами командной строки

У меня есть .hta приложение, которое принимает два аргумента командной строки. Запуск приложения на удаленном компьютере через командную строку работает так же, как показано ниже.

(командная строка - cmd) Пример:

C:\Users\<user>\Desktop>MSI-BUILDER.hta "MSI_APP" "D:\APP\15.9.98"

Но когда я использую свой рабочий стол, пытаясь выполнить ту же команду на удаленном компьютере через PSEXEC, я вижу, что приложение работает в диспетчере задач, но ничего не происходит.

Первыми шагами было присвоение аргументов командной строки переменным в PowerShell:

$arg1 = "MSI_APP"
$arg2 = "D:\APP\15.9.98"

и выполнение этой команды в PowerShell не выполняется (ошибок нет, просто зависает):

.\psexec -s -i \\Srv2012 cmd /c "start /i "MSI-BUILDER" "C:\Users\<user>\Desktop\MSI-BUILDER.hta" $arg1 $arg2"

Приложение запускается только в диспетчере задач, и я предполагаю, что в фоновом режиме, но я не вижу никаких изменений, поэтому оно может просто зависать ...

Я не на 100% уверен, что мой синтаксис в этом вопросе верен для запуска HTA через PowerShell с аргументами командной строки.

Также есть ли способ или переключатель, с помощью которого я действительно могу видеть запуск приложения и выполнять свою работу после удаленного выполнения кода в целях тестирования?


person demo7up    schedule 17.09.2019    source источник
comment
есть ли способ или переключатель, с помощью которого я действительно могу видеть запуск приложения и выполнять свою работу после удаленного выполнения кода - Нет. Удаленно выполняемое приложение не будет видно графическому интерфейсу интерактивного пользователя на удаленной машине. Это сделано специально из соображений безопасности.   -  person Bill_Stewart    schedule 17.09.2019
comment
@Bill_Stewart: psexec может удаленно запускать приложения видимым образом в сеансе рабочего стола локально вошедшего в систему пользователя, а именно с помощью параметра -i - см. документы.   -  person mklement0    schedule 18.09.2019
comment
Откройте окно командной строки и введите start /? и cmd /?, чтобы узнать, как работают эти конкретные команды. Вы заметите, что команде start потребуется заголовок, подойдет пустой, start "" ..., вы также увидите раздел под cmd /?, в котором объясняется, как она обрабатывает двойные кавычки с /C. Однако вам совсем не нужно запускать приложение HTML через cmd.exe или использовать его внутреннюю команду start.   -  person Compo    schedule 18.09.2019
comment
@ mklement0 Спасибо за уведомление. Он может это сделать, потому что он устанавливает службу на удаленном компьютере, а затем вызывает исполняемый файл в консольном (или указанном) сеансе.   -  person Bill_Stewart    schedule 18.09.2019


Ответы (2)


Вызов вашего *.hta файла можно упростить, передав его путь и аргументы непосредственно в mshta.exe (это также предотвращает кратковременное отображение окна консоли, если вы запускаете через cmd/ c):

# From PowerShell (-accepteula omitted for brevity)
# IMPORTANT: You must use the *.hta file's FULL PATH.
.\psexec \\SERVER -i -s mshta.exe "D:\path\toapp\app.hta" $arg1 $arg2

По умолчанию psexec выполняется синхронно, т. е. не возвращается до тех пор, пока удаленный процесс не завершится, что необходимо, если вы хотите знать процесс. 'код выхода. [1]

В вашем случае процесс не завершается , пока окно приложения HTA ​​не закроется, поэтому я предполагаю, что ваше автоматически закрывается при вызове с аргументами командной строки - если это не так ' t, psexec не вернется, пока интерактивный пользователь не закроет окно при вызове с помощью -i, или не вернется вообще без -i.

В случаях, когда вам нужно асинхронное выполнение, используйте параметр -d; это заставляет psexec вернуться после успешного запуска целевого процесса, не дожидаясь его завершения. Поскольку в этом случае вы по определению не можете знать истинный код выхода запущенного процесса, все, что psexec скажет вам, это то, можно ли создать процесс.

Предупреждение: запуск в интерактивном режиме (-i) с -s, то есть под учетной записью NT AUTHORITY\SYSTEM, представляет собой угрозу безопасности - см. следующий раздел.

Однако при правильном цитировании ваша первоначальная попытка тоже может сработать - см. Нижний раздел.


Что касается:

Также есть ли способ или переключатель, с помощью которого я действительно могу видеть запуск приложения?

Это psexec параметр -i, который заставляет указанную команду запускаться в интерактивном режиме на удаленной целевой машине, в сеансе любого пользователя. происходит интерактивный вход в систему в это время. [2]

Что касается личности пользователя, psexec обычно позволяет запускать команды как:

  • либо: учетная запись SYSTEM (NT AUTHORITY\SYSTEM) с параметром -s, который не рекомендуется с -i, однако:

    • NT AUTHORITY\SYSTEM is a highly privileged account that represents the local computer, so its use in an application that the user can control interactively is a a security risk.
  • или: заданный фиксированный пользователь с опцией -u-p; см. пример ниже)

Обратите внимание, что то, что вы не можете делать с -i, - это автоматически запускать с идентификатором любого пользователя, который случайно вошел в интерактивный сеанс на целевом компьютере, так как это было бы очень проблематично с точки зрения безопасности. Однако явное использование -u с теми же учетными данными, что и интерактивный в данный момент пользователь (если он известен), работает.

Дополнительную информацию см. В документации.

С -i лучше использовать учетную запись, которая имеет только минимальный набор привилегий, необходимых для работы приложения; вместо -s можно использовать параметры -u (имя пользователя) и -p (пароль); например.:

# From PowerShell
.\psexec \\SERVER -i -u user1 -p passwd1 mshta.exe "D:\path\toapp\app.hta" $arg1 $arg2

Что касается того, что вы пробовали (в вашем вопросе):

Ваша исходная команда, вероятно, сработала бы, если бы вы исправили свои проблемы с цитированием:

.\psexec \\Srv2012 -s -i cmd /c start /i `"MSI-BUILDER`" "C:\Users\<user>\Desktop\MSI-BUILDER.hta" $arg1 $arg2

Чтобы избежать проблем с вложенным цитированием, внешнее цитирование команды, переданной в cmd /c, было опущено.

Обратите внимание, как " chars. которые заключают MSI-BUILDER, к сожалению, должны быть экранированы как `", чтобы гарантировать, что PowerShell передает их psexec и, в конечном итоге, cmd /c:

  • PowerShell за кулисами использует политику двойных кавычек по запросу, поэтому даже аргументы, которые вы изначально указали в кавычках, заканчиваются без двойных кавычек. , если значение аргумента не содержит пробелов [3] - следовательно, ваш "MSI-BUILDER" аргумент в конечном итоге будет передан как MSI-BUILDER - без двойных кавычек - в psexec.

  • К сожалению, команда cmd-internal start имеет неудобный синтаксис: она всегда требует, чтобы аргумент, являющийся заголовком окна, был заключен в "..." в командной строке, даже если title - это одно слово (например, MSI-BUILDER в вашем случае).

  • Следовательно, в этом конкретном пограничном случае " вокруг аргумента заголовка окна для start необходимо экранировать как `", чтобы гарантировать их сохранение.

Однако, как показано выше, есть более простой способ вызвать ваш *.hta (не требующий промежуточного cmd.exe процесса).

В стороне: команда start излишняя, и установка заголовка для временного окна, запускающего графический интерфейс *.hta, бессмысленна, поскольку окно просто мигает на мгновение.


[1] Обратите внимание, что приложения HTA ​​не поддерживают явную установку кодов выхода, если вы не используете подробный обходной путь. Без него код выхода всегда был бы 0 - если только процесс mshta.exe не аварийно завершит работу.

[2] То, что psexec на это способен, может показаться удивительным; это возможно с помощью следующего хитроумного метода: psexec подключается к $ADMIN общему ресурсу целевой машины (обычно C:\Windows), временно извлекает исполняемый файл службы в собственном исполняемом образе (PSEXESVC.exe) в это место и запускает этот исполняемый файл как локальная служба (PSEXESVC) на целевой машине. Именно эта служба запускает команду, переданную psexec при вызове, необязательно (-i) в сеансе текущего пользователя (видимая оконная станция). Вызывающий экземпляр psexec на исходной машине связывается со службой через именованный канал (psexecsvc), что позволяет вызывающей машине получать вывод консоли удаленного процесса, если -i был не < / em> указано; по завершении команды (или с параметром -d (не ждать) при успешном запуске команды) служба останавливается, а исполняемый файл службы удаляется - см. эту статью для получения дополнительной информации.

[3] Есть и другие сложные критерии, относящиеся к " символам. встроено в значение.

person mklement0    schedule 17.09.2019

Итак, наконец, после нескольких часов пробуя разные вещи, это команда, которая сработала для меня.

Отредактированная команда:

.\PSEXEC -accepteula -s -i 2 \\SERVER cmd /c "D:\path\toapp\app.hta" $arg1 $arg2 -u username -p password

person demo7up    schedule 17.09.2019
comment
Я думаю, вы имели в виду -i вместо -h (что, по сути, подразумевается -s); обратите внимание на последствия для безопасности запуска интерактивной программы с -s; при использовании cmd /c сначала на целевой машине на короткое время появится окно консоли. - person mklement0; 18.09.2019
comment
Спасибо за обновление. -i без аргумента идентификатора сеанса является умным и автоматически выбирает сеанс, который в настоящее время является интерактивным на целевой машине (сеанс с именем console). Использование идентификаторов сеансов, таких как 2, может работать ситуативно, но идентификаторы меняются в зависимости от того, кто вошел в систему первым. - person mklement0; 19.09.2019
comment
Кроме того, использование обоих -s и -u + -p противоречиво; в то время как psexec спокойно принимает эту комбинацию, она -s вступает в силу независимо от порядка аргументов. - person mklement0; 19.09.2019
comment
@ mklement0 К сожалению, это было мое первоначальное направление с использованием mshta.exe, но приложение зависало и никогда не возвращало код из PowerShell, который мне как бы нужно продолжать обрабатывать мои функции с помощью cmd. Я получаю cmd exited on Srv2012 with error code 0., который я могу вернуть в свой php-скрипт. Что более чем достаточно - person demo7up; 19.09.2019
comment
-d просто запускает приложение и успешно возвращается независимо от конечного результата, так как для cmd / c он запускает окно, ожидающее закрытия приложения, а затем закрывается, возвращая истинный успешный ответ. - person demo7up; 19.09.2019
comment
Таким образом, HTA буквально принимает два аргумента и запускает около 25-30 сценариев vbs с этими аргументами после итерации, хотя 25-30 сценариев его устанавливают в window.close, когда это происходит, окно cmd закрывается, потому что процесс завершается. - person demo7up; 19.09.2019
comment
Спасибо за разъяснение. Обратите внимание, что приложения HTA ​​не поддерживают явную установку кодов выхода, если вы не используете сложный обходной путь. Без него код выхода всегда был бы 0 - если только процесс mshta.exe не выйдет из строя. Подводя итог: мы вернулись к исходной точке: заставьте psexec вызывать mshta.exe напрямую - без -d - и он будет ждать кода выхода по желанию - нет необходимости в cmd /c. Я обновил свой ответ, чтобы сопоставить два сценария (синхронный и асинхронный). - person mklement0; 19.09.2019