psexec 仅在使用用户名和密码并从 PowerShell 脚本调用时挂起

psexec 仅在使用用户名和密码并从 PowerShell 脚本调用时挂起

我正在尝试使用 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_pa​​rameters

更新:您还应该将用户名和密码部分分开,作为列表中的单独条目。基本上,每次您在 cmd 命令中有空格时,您都会创建一个单独的列表条目。因此您的 $psexecArgs 将变成:

$psExecArgs = "-accepteula", "-nobanner", "-u", "domain`\${username}", "-p", "${password}", "-h", "-d", "`\`\${hostname}", "`"${executableDirectory}`\${executableName}`""

不太确定该重定向是否有效(#2>$null),或者是否也应该以某种方式包含在列表中。

相关内容