у меня естьWindows сервер 2016машина, которая должна запустить файл, использующий cli, удаленноиспользуя SSH.
Известно, что выход из SSH-соединения завершает процессы, запущенные пользователем ssh. На машинах Linux можно использовать такие решения, как nohup
или screen
, в результате чего процесс не будет завершен после выхода из системы.
Однако такие решения не будут работать на компьютерах с Windows, и я ищу способ предотвратить завершение процесса после выхода из системы.
- Мой клиент —Машина с Ubuntu
- Мой сервер Windows 2016 работаетOpenSHH, сPowerShellкак оболочка по умолчанию
- Моя программа настроена на работу в режиме демона, и ни одно окно cmd или powershell не остается открытым.
- Использование
Get-Process -Name proc_name
показывает, что процесс действительно запущен - Использование
Get-Process
после выхода из SSH не приводит к такому процессу
Что я еще попробовал:
- Запуск
.exe
файла с помощьюcmd
. - Запуск
.bat
и.ps
файлов, которые запускают.exe
с его аргументами.
Есть ли способ решить эту проблему на машине с Windows?
решение1
Потратив много времени на поиски решений, я нашел абсолютно правильный способ сделать это с помощью PowerShell.
Похоже, это один из тех командлетов, которые редко используются или документированы в сети, и в нем практически невозможно разобраться самостоятельно, используя документацию MSDN, если только вы не очень хорошо знакомы с огромным миром Wmi Objects
.
Суммируя:
Предположим, что у меня есть программа foo.exe
, которая должна работать в фоновом режиме с аргументами -a
, -b
и bar
, мне следует использовать точную команду:
Invoke-WmiMethod -Path 'Win32_Process' -Name Create -ArgumentList 'C:\Users\foo\Desktop\foo.exe -a -b bar'
Конечно, если ваш exe-файл является «известным» exe-файлом (либо по умолчанию, например, notepad или ping), либо добавленным вами, полный путь не нужен, -ArgumentList
достаточно использовать имя exe-файла (notepad, ping и т. д.).
Дополнительные параметры:
Invoke-WmiMethod
поддерживает дополнительные параметры, такие как -Credential
, -ComputerName
(хороший способ использовать локальный PS для Invoke
чего-либо на удаленной машине без использования SSH) -Impersonation
и многиеболее подробно описано здесь.
Объяснение синтаксиса командлета и дополнительные инструменты командлета:
- Аргумент
-Path
указывает наWmiObject
имя. ЕстьдесяткиизWmiObjects
, каждый со многимиMethods
иProperties
. - Аргумент
-Name
направляет используемыйMethod
. - Перечислить все доступные
Wmi-Objects
варианты использованияGet-WmiObject -List
(очень сложно найти нужный вам объект таким образом). - Чтобы перечислить и просмотреть все доступные
Win32_Process
Methods
иProperties
использовать
Get-WmiObject -List |where{$_.name -match '^Win32_Process$'}
Это вернет вывод следующей структуры:
NameSpace: ROOT\cimv2
Name Methods Properties
---- ------- ----------
Win32_Process {Create, Terminat... {Caption, CommandLine, CreationClassName, CreationDate...}
И, конечно, использование |Select-Object -ExpandProperty (_your_property_here_)
покажет все доступные, Methods
такие как Create
мы использовали в команде выше, и все доступные Properties
(которые мы не использовали).