我正在努力在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
然而,它们都不起作用。有什么想法错了吗?
答案 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 机器,其中该环境变量的定义可能相同也可能不同。