【问题标题】:PSExec and Powershell fails to run a program located in Program Files (x86)PSExec 和 Powershell 无法运行位于 Program Files (x86) 中的程序
【发布时间】:2016-03-15 20:27:32
【问题描述】:

我正在努力在 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

但是它们都不起作用。知道有什么问题吗?

【问题讨论】:

    标签: powershell escaping quoting


    【解决方案1】:

    尝试以下方法:

    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首先解析字符串 - 无论是单引号还是双引号 - 如果适用,则进行插值,然后传递 resulting 字符串双引号到外部命令。
    • 注意powershell 参数上下文中的& \"...\" 构造,它确保正确执行带有嵌入空格的路径。

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

      • 传递给powershell的命令作为一个整体必须被双引号,因为cmd.exe - 在其上下文中调用powershell由于to cmd /c - 仅将双引号识别为参数分隔符,并且仅双引号可保护封闭的内容(大部分)不被解释。


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

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

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

    【讨论】:

    • 这简直太棒了。很好地分解了它应该如何做。谢谢@mklement0。我必须删除 ProgramFiles 和 (x86) 之间的空格才能使其正常工作,但除此之外,您的评论完美无缺。
    • @Okrx:很高兴;很高兴听到。无关空间:适合我在我的 32 位机器上伪造变量...感谢您的反馈;我已经确定了答案。
    【解决方案2】:

    通过混合 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
    

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

    【讨论】:

    • 虽然这确实简化了调用,但请注意 OP 如何提到“在 PS 脚本中使用 Psexec ”(强调我的)。
    • 此命令运行良好,非常感谢您的帮助,但这需要从 PS 脚本运行。
    猜你喜欢
    • 2021-11-08
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2014-08-28
    相关资源
    最近更新 更多