Запуск удаленного GUI-приложения в Powershell
У нас есть пользовательский comonent, который обертывает некоторые функции powershell, поэтому его можно использовать frim BizTalk 2006. Для большинства операций (проверка пути к файлу, копирование или перемещение файла) это работает нормально. Однако нам нужно удаленно запускать графическое приложение, чтобы выполнить некоторую обработку. Сам компонент обрабатывает соединение с удаленным ящиком, все, что нам нужно сделать, это установить некоторые параметры, а затем сообщить ему выполнить команду
Start-Process -FilePath "path to exe" -ArgumentList "arguments for exe" -WorkingDirectory "workingdir for exe"
Проблема заключается в следующем: если мы запустим это из командной строки powershell на самом ящике, это отлично работает. Однако, когда мы запускаем его удаленно (из BizTalk, из тестового жгута, даже используя удаленную командную строку Powershell и соединение через Start-PSSession), это приложение запустится ненадолго, а затем выйдет, фактически ничего не сделав. Мое подозрение состоит в том, что, поскольку exe, о котором идет речь, требует загрузки GUI для запуска процесса, что именно это вызывает проблему. Я пробовал все, что мог придумать, включая -NoNewWindow и -WindowStyle, но безрезультатно. Любая помощь в получении этой работы будет очень оценена.
Примечание. У нас нет доступа к источнику для приложения, которое мы пытаемся запустить, поскольку оно является более старым приложением win32, и не было выпущено пакетной или командной строки этого приложения.
Ответы
Ответ 1
Используя стандартные методы PowerShell (WinRM, WMI), вы не можете запускать приложения с графическим интерфейсом. Единственное решение, о котором я знаю, это использовать PsExec из SysInternals (или аналогичные инструменты). Он может запускать приложения, которые представляют GUI пользователю. Ваша команда будет выглядеть так:
& ".\psexec" -accepteula -i "\\computername" -u "domain\username" -p "password" "command line"
-
-accepteula
- молча принять EULA.
-
-i
- разрешить графический интерфейс.
Другие решения более хаки, включая удаленное добавление задач к планировщику.
Ответ 2
Так как я натолкнулся на это недавно, вот мое решение, используя предложение Discord о добавлении удаленной задачи. Я предпочел "взломать" необходимость установки отдельного инструмента.
function Start-Process-Active
{
param
(
[System.Management.Automation.Runspaces.PSSession]$Session,
[string]$Executable,
[string]$Argument,
[string]$WorkingDirectory,
[string]$UserID,
[switch]$Verbose = $false
)
if (($Session -eq $null) -or ($Session.Availability -ne [System.Management.Automation.Runspaces.RunspaceAvailability]::Available))
{
$Session.Availability
throw [System.Exception] "Session is not availabile"
}
Invoke-Command -Session $Session -ArgumentList $Executable,$Argument,$WorkingDirectory,$UserID -ScriptBlock {
param($Executable, $Argument, $WorkingDirectory, $UserID)
$action = New-ScheduledTaskAction -Execute $Executable -Argument $Argument -WorkingDirectory $WorkingDirectory
$principal = New-ScheduledTaskPrincipal -userid $UserID
$task = New-ScheduledTask -Action $action -Principal $principal
$taskname = "_StartProcessActiveTask"
try
{
$registeredTask = Get-ScheduledTask $taskname -ErrorAction SilentlyContinue
}
catch
{
$registeredTask = $null
}
if ($registeredTask)
{
Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
}
$registeredTask = Register-ScheduledTask $taskname -InputObject $task
Start-ScheduledTask -InputObject $registeredTask
Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
}
}