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 机器,其中环境变量的定义可能相同也可能不同。
我很难在 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 机器,其中环境变量的定义可能相同也可能不同。