我正在尝试使用 psexec 在已打开的交互式会话中启动进程。我的计算机和远程计算机都是 Windows 7。使用命令提示符中的命令可以正常工作,可执行文件已启动并在 GUI 中可见。
psexec64 -accepteula -nobanner \\hostname -u domain\user -p password -h -i 2 -d C:\workingdir\subfolder\application.exe
但是,当我尝试在 PowerShell 脚本中执行相同的调用时,它不起作用。请参阅完整脚本以供参考。
# invalid args: $psExecArgs = "-accepteula", "-nobanner", "-u domain`\${username}", "-p ${password}", "-h", "-i ${sessionId}", "-d", "`\`\${hostname}", "`"${executableDirectory}`\${executableName}`""
# hangs: $psExecArgs = "-accepteula", "-nobanner", "-u domain`\${username}", "-p ${password}", "-h", "-d", "`\`\${hostname}", "`"${executableDirectory}`\${executableName}`""
$psExecArgs = "-accepteula", "-nobanner", "-h", "-d", "`\`\${hostname}", "`"${executableDirectory}`\${executableName}`""
& $EchoArgsPath $psExecArgs
$result = & $PsExecPath $psExecArgs #2>$null
- 当给出所有相同的参数时,的值
$result
是 psexec 帮助,就好像给出了无效的参数。 - 当
-i 2
被删除时,psexec 会显示在我的计算机上的正在运行的进程列表中并且似乎挂起;远程计算机上没有启动 psexecsvc 进程。 - 当
-u
和-p
被删除时,psexec 启动,但正如预期的那样,该过程在远程计算机上的我的帐户的非交互式会话中启动。
使用 pslist 和 pskill 时,我看到了同样的行为,因此我将它们替换为 tasklist 和 taskkill。我已确保 UAC 已禁用,并且我可以使用我提供的凭据映射到远程计算机上的 Admin$ 共享。
当我输入这个问题的时候,我发现了一个问题这表明 stdin 可能是一个问题但我不确定这是否与我的情况相关。
答案1
声明一个变量就像$psExecArgs = "-accepteula", "-nobanner"
创建一个字符串数组。
您正在运行字符串所说的内容(使用&
)而不是启动进程并提供参数,因此参数也需要是简单的字符串(而不是字符串数组)。
然后进一步混淆的是,如果你要在单个字符串()中提供参数$psExecArgs = "-accepteula -nobanner"
,它实际上只作为 PSExec 的一个参数出现,并且也不起作用。
因此,与其尝试运行字符串,不如使用 PowerShell 的Start-Process
命令,它期望将参数以数组的形式提供给它(就像您当前正在做的那样)。
尝试更改命令行,例如:
& $PsExecPath $psExecArgs
类似于:
Start-Process $PsExecPath $psExecArgs
您必须以稍微不同的方式处理返回代码和错误,例如:
try {
$process = (Start-Process -FilePath $psexec -ArgumentList $psExecArgs -NoNewWindow -PassThru)
}
catch {
Write-Output "Error launching process!"
Write-Output $_.Exception.Message
$process = $null
}
finally {
if ($process) {
$process.WaitForExit()
Write-Host "Process exit code: " $process.ExitCode
}
}
答案2
调试永远是你的朋友 - 如果你在执行期间检查 $psExecArgs 的值(在完整脚本中),你会注意到你没有提供 $password 的值。这意味着你向 psexec 发送了 -p(无内容),这再次导致 psexec 在等待密码输入时挂起。
C:\..\foobar.ps1
cmdlet foobar.ps1 at command pipeline position 1
Supply values for the following parameters:
hostname: myhostname
username: myusername
password: mypassword
sourcedirectory: c:\mysourcedir
targetdirectory: c:\mytargetdir
executablename: myexec.exe
Hit Line breakpoint on 'C:\...\foobar.ps1:34'
[DBG]: PS C:\Users\Zerqent>> $psExecArgs
-accepteula
-nobanner
\\myhostname
-u domain\myusername
-p
qwinsta
为了避免在 powershell 中出现这种情况,请将参数设为必需的https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_functions_advanced_parameters
更新:您还应该将用户名和密码部分分开,作为列表中的单独条目。基本上,每次您在 cmd 命令中有空格时,您都会创建一个单独的列表条目。因此您的 $psexecArgs 将变成:
$psExecArgs = "-accepteula", "-nobanner", "-u", "domain`\${username}", "-p", "${password}", "-h", "-d", "`\`\${hostname}", "`"${executableDirectory}`\${executableName}`""
不太确定该重定向是否有效(#2>$null),或者是否也应该以某种方式包含在列表中。