PSExec和Powershell无法运行程序文件(x86)

时间:2016-03-14 22:09:59

标签: powershell escaping quoting

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

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

......它运行得非常好。记事本在远程计算机上启动。现在,当我想从Program Files(x86)运行.exe时,我什么都没得到。 我尝试过这些变体来运行位于ProgramFiles(x86)中的1.exe:

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

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

然而,它们都不起作用。有什么想法错了吗?

2 个答案:

答案 0 :(得分:3)

通过混合PowerShell,CMD和PsExec,你将自己置身于Escape Hell。如果您只想在远程主机上运行可执行文件,只需坚持使用CMD和PsExec(也可以从CMD运行命令):

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

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

答案 1 :(得分:3)

尝试以下方法:

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

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

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

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

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

    • 作为整体传递给powershell的命令必须双引号,因为cmd.exe - 在其上下文中{{由于powershell而调用了1}} - 只能将双引号识别为参数分隔符,并且只有双引号可以保护所包含的内容(主要是)免于解释。

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

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

    • 对于调试,使用(...)而不是cmd /k可以更好地了解命令的最终执行方式(cmd /c在执行命令后保持控制台窗口打开)。
  • 更微妙的一点是,通过整体使用双引号字符串,/k机器上展开,而不是在< em> target 机器,其中该环境变量的定义可能相同也可能不同。