You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell 5.1通过SSH发送脚本字符串的转义与执行差异问题

问题:通过SSH远程执行PowerShell脚本修改sshd_config时的参数拆分错误

我在PowerShell 5.1中尝试通过SSH将PowerShell脚本以字符串形式发送到远程计算机,目标是修改其sshd_config配置文件。此前已解决特殊字符序列的转义问题,但发现ssh $Username@$ComputerIP $stringScript的执行逻辑与cmd.exe /c $stringScript不同,执行时出现错误。

我的预期代码

$forceOnlyKeysSSH = '`nMatch all`n`tPasswordAuthentication no'
$rmtPSAuthOnlyKeys = "powershell Add-Content -Force -Verbose -Path c:\ProgramData\ssh\sshd_config " +
    "-Value \`"$forceOnlyKeysSSH\`""
ssh -o ConnectTimeout=10 $Username@$ComputerIP $rmtPSAuthOnlyKeys

理想执行结果

向sshd_config文件添加以下内容:

Match all
    PasswordAuthentication no

实际错误提示

Add-Content : A positional parameter cannot be found that accepts argument 'all
        PasswordAuthentication'.
At line:1 char:1
+ Add-Content -Force -Verbose -Path c:\ProgramData\ssh\sshd_config -Val ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Add-Content], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.AddContentCommand

问题原因

你确实存在字符串转义逻辑的问题,核心差异在于SSH与cmd.exe的命令参数解析逻辑完全不同:

  • cmd.exe /c会将整个传入的字符串当作单个完整命令处理,它会自行解析内部的引号转义,确保-Value的参数能完整传递给PowerShell,不会被空格拆分。
  • 而SSH在传递命令时,会将你提供的命令字符串按空格拆分为多个参数发送给远程shell;同时远程shell(Windows下默认是cmd.exe)会再次解析命令,你当前的转义方式无法保留-Value参数的完整性,导致空格分隔的内容被拆成了多个位置参数,触发PowerShell的参数绑定错误。

解决方案

方案1:调整转义逻辑,用嵌套引号确保参数完整性

$forceOnlyKeysSSH = "`nMatch all`n`tPasswordAuthentication no"
# 用单引号包裹外层命令,内部用双引号嵌套,通过重复单引号实现转义
$rmtPSAuthOnlyKeys = 'powershell "Add-Content -Force -Verbose -Path ''c:\ProgramData\ssh\sshd_config'' -Value ''''$forceOnlyKeysSSH''''"'
ssh -o ConnectTimeout=10 $Username@$ComputerIP $rmtPSAuthOnlyKeys

方案2:用Base64编码彻底避免转义问题(最可靠)

PowerShell支持通过-EncodedCommand参数执行Base64编码的脚本,完全规避多层转义的问题:

# 构建要执行的脚本内容
$scriptContent = @"
Add-Content -Force -Verbose -Path 'c:\ProgramData\ssh\sshd_config' -Value "`nMatch all`n`tPasswordAuthentication no"
"@

# 将脚本编码为Unicode格式的Base64字符串
$encodedScript = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($scriptContent))

# 构建远程执行命令
$rmtCommand = "powershell -EncodedCommand $encodedScript"

# 执行SSH命令
ssh -o ConnectTimeout=10 $Username@$ComputerIP $rmtCommand

内容的提问来源于stack exchange,提问作者JackOA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 23:36:06