PSExec 和 Powershell 无法 运行 位于 Program Files (x86) 中的程序

PSExec and Powershell fails to run a program located in Program Files (x86)

我很难在 PS 脚本中使用 Psexec 来执行交互式程序。 我试过这个:

PsExec.exe -i \192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell notepad" 2> $null

... 运行 非常好。记事本在远程计算机上启动。现在,当我想从 Program Files (x86) 中获取 运行 .exe 时,我什么也得不到。 我已经尝试过这种变体 运行 1.exe 位于 ProgramFiles(x86):

PsExec.exe -i \192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell "${env:ProgramFiles(x86)}.exe"" 2> $null

PsExec.exe -i \192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell "${env:ProgramFiles(x86)}" + ".exe"" 2> $null

但是 none 它们有效。知道出了什么问题吗?

混合使用 PowerShell、CMD 和 PsExec,您将自己置身于 Escape Hell 中。如果你想要的只是 运行 远程主机上的可执行文件,只需坚持使用 CMD 和 PsExec(运行 来自 CMD 的命令):

PsExec.exe -i \192.168.100.95 -u Administrador -p Test1234 cmd /c echo. ^| "%ProgramFiles(x86)%.exe" 2>nul

这样你只需要转义管道 (^|) 并将带空格的路径放在双引号中。

尝试以下操作:

psexec cmd /c 'echo . | powershell "& \"${env:ProgramFiles(x86)}.exe\"' 2>$null

注意:为了更好地关注解决方案的基础知识,我简化了 psexec 命令,但原始命令也应该有效。

  • 传递给 cmd /k 的整个字符串是 单引号 以防止 PS 预先插入元素,特别是 ${env:ProgramFiles(x86)} 其扩展应该推迟到命令在 target 机器上执行。

    • 请注意,当您将命令行传递给 cmd /c cmd.exe 调用时,通常需要 双引号 字符串本身。但是,在 PowerShell 中,这 不是 要求:PowerShell 首先解析字符串 - 无论最初是单引号还是双引号 - 插入(如果适用),然后传递 resulting 字符串 双引号 到外部命令。
  • 注意 powershell 参数上下文中的 & \"...\" 构造,它确保正确执行带有嵌入空格的路径。

    • 奇怪的是,PS 需要 " 个字符。当从外部世界传递参数时作为\"转义(与在PS领域内作为`"转义相反)。

    • 传递给powershell的命令整体必须双引号,因为cmd.exe - 由于 cmd /c 而在其上下文中调用 powershell - 仅将双引号识别为参数定界符,并且只有双引号可以保护所包含的内容(大部分)免于解释。


为什么你的命令不起作用:

  • 主要问题是您希望 powershell.exe 调用的可执行文件路径最终包含 空格 (C:\Program Files...),导致 PowerShell 无法将整个路径识别为单个参数。这样的路径必须 (a) 引用 和 (b) 使用调用运算符 & 调用。
    (在第二次尝试中,使用 + ...(字符串连接),您还必须使用 &,并将连接包含在 (...) 中)。

    • 对于调试,使用 cmd /k 而不是 cmd /c 可以让您更好地了解命令最终是如何执行的(/k 在之后保持控制台 window 打开命令的执行)。
  • 更微妙的一点是,通过整体使用 双引号 字符串,${env:ProgramFiles(x86)}source 机器而不是 target 机器,其中环境变量的定义可能相同也可能不同。