Packer SSH通信器构建Windows AMI时PowerShell脚本执行失败
问题根因
- 会话令牌权限不匹配:OpenSSH for Windows 建立的SSH会话默认走**网络登录(Network Logon)流程,拿到的是被UAC过滤过的受限管理员令牌,和WinRM通信器默认拿到的交互式登录(Interactive Logon)**完整高权限令牌有本质差异。受限令牌没有访问Defender签名存储区、系统控制台内核对象、受保护安装路径的权限,直接触发0x5访问拒绝错误。
- 控制台缓冲区权限缺失:通过AWS SSM Session Manager的SSH接口转发的会话不会分配完整的窗口站(Window Station)和桌面堆,子进程(安装包、解压工具、Defender更新模块都是原生Win32程序)默认会尝试附加到父进程的控制台读写输出,因为没有对应缓冲区的访问权限直接报错,也就是日志里显示的“读取控制台输出缓冲区时访问被拒”。
- 官方默认execute_command配置没有做Windows适配:默认配置既没有关闭远程UAC限制,也没有给PowerShell进程分配独立控制台,直接跑涉及系统级操作的脚本必然失败。
可落地修复步骤
- 先调整OpenSSH服务与系统权限配置,把下面的逻辑加到配置OpenSSH的user_data脚本里,在实例首次启动时执行:
# 关闭远程登录的UAC令牌过滤,让SSH登录的管理员账户拿到完整权限 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ` -Name "LocalAccountTokenFilterPolicy" -Value 1 -PropertyType DWord -Force # 配置PowerShell为OpenSSH默认shell Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" ` -Name "DefaultShell" -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Force # 重启SSHD服务让配置生效 Restart-Service sshd -Force
- 替换Packer模板里SSH通信器的默认execute_command,不要直接用官方文档给的最简配置,换成带独立隐藏控制台、绕过执行策略的版本:
communicator = "ssh" ssh { ssh_username = "Administrator" execute_command = "powershell -ExecutionPolicy Bypass -NoProfile -NonInteractive -WindowStyle Hidden -Command \"$ProgressPreference='SilentlyContinue'; $ErrorActionPreference='Stop'; & { {{.Vars}}; & '{{.Path}}'; exit $LASTEXITCODE }\"" }
这里的-WindowStyle Hidden参数会给PowerShell进程分配独立的隐藏控制台缓冲区,子进程不需要再访问SSH会话本身无权限的转发控制台,从根源解决读控制台缓冲区报错的问题。
3. 对脚本里容易触发权限问题的操作做针对性适配:
- 所有下载的安装包、压缩包,解压/执行前先跑
Unblock-File移除Zone Identifier备用数据流,避免Windows安全拦截触发权限错误 - 涉及Defender更新、系统级组件安装的操作,不要直接在当前SSH会话上下文执行,用conhost托管独立进程执行,比如更新Defender签名改成:
Start-Process -FilePath "C:\Windows\System32\conhost.exe" ` -ArgumentList "powershell -NoProfile -Command Update-MpSignature" ` -Wait -NoNewWindow - 所有EXE、MSI安装操作统一用
Start-Process启动,加-Wait参数,同时把标准输出、错误输出重定向到本地日志文件,不要直接往SSH会话控制台写入:# Sysmon安装示例 Start-Process msiexec.exe ` -ArgumentList "/i C:\temp\Sysmon.msi /qn /norestart ACCEPT_EULA=1" ` -Wait -RedirectStandardOutput "C:\temp\sysmon_install.log" ` -RedirectStandardError "C:\temp\sysmon_install_err.log"
验证方式
配置完成后可以先手动通过SSM SSH连接到测试实例,执行whoami /priv核对权限列表,确认和WinRM登录时的权限一致(包含SeSecurityPrivilege、SeTakeOwnershipPrivilege等系统级权限),再单独执行之前报错的解压、Defender更新步骤,确认返回码为0即可。
内容的提问来源于stack exchange,提问作者nikhilsoman
相关产品推荐
相关产品推荐

