powershell远程执行中文乱码核心是两端编码不一致:本地utf-8而远程默认ansi(cp936),需检查chcp、[console]::outputencoding和$outputencoding三者是否统一为65001/utf8,并确认远程会话是否跳过profile导致编码设置未加载,脚本文件本身编码也需验证为utf-8或utf-8 bom。
powershell 远程执行脚本时出现中文乱码,核心问题不是“远程”本身,而是两端编码环境不一致:本地会话用 utf-8,远程会话却按系统默认 ansi(cp936)输出,或远程控制台未加载 utf-8 设置。排查要从「谁在输出」「谁在解码」「中间经过哪几层」三方面入手。
确认远程会话的实际代码页和输出编码
别只看本地终端显示,直接登录远程主机(如通过 RDP 或 WinRM 交互式连接),运行以下命令:
- chcp —— 查看当前控制台活动代码页(应为 65001 才支持 UTF-8 输出)
- [console]::OutputEncoding —— 检查 PowerShell 会话层的输出编码对象(应为 UTF8Encoding 实例)
-
$OutputEncoding —— 检查管道/外部进程通信编码(影响
Out-File、Start-Process等)
如果三者不一致(比如 chcp 显示 936,但 [console]::OutputEncoding 是 UTF8),说明控制台宿主(conhost)与 PowerShell 引擎之间存在编码错位,常见于非交互式远程会话(如 Invoke-Command -ScriptBlock)。
检查远程执行方式是否跳过 profile
很多远程调用(尤其是自动化工具如 OpenAICodex、Ansible、CI/CD agent)会使用 pwsh -NoProfile -Command ... 启动子进程。这会导致:
- profile.ps1 中设置的
[console]::OutputEncoding = [Text.UTF8Encoding]::new()不生效 -
chcp 65001命令不会执行 - 远程会话始终沿用系统 OEM 默认(GB2312/GBK),输出中文即乱码
验证方法:在远程主机上手动运行 pwsh -NoProfile -Command "[console]::OutputEncoding",对比 pwsh -Command "[console]::OutputEncoding" 的输出差异。
验证远程脚本内容的真实编码
乱码常被误判为“远程环境问题”,实则脚本文件本身编码不对。在远程主机上运行:
Get-Content -Path .\script.ps1 -Encoding UTF8 -TotalCount 3
若报错“无法识别的字符”,说明文件不是 UTF-8;若显示正常但远程执行仍乱码,则问题出在输出环节而非源文件。也可用以下函数检测:
function Test-FileEncoding { param($Path) $bytes = Get-Content -Path $Path -Encoding Byte -TotalCount 3 if ($bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { 'UTF8-BOM' } else { 'Not UTF8-BOM' } }
绕过 profile 限制的临时修复方案
若无法修改远程启动参数(如受限于第三方平台),可在脚本开头强制重置编码:
- 加一行
chcp 65001 | Out-Null(确保控制台代码页切换) - 加一行
[Console]::OutputEncoding = [Text.UTF8Encoding]::new() - 对关键输出命令显式指定编码,例如:
Write-Output "你好" | Out-String -Width 200 | ForEach-Object { $_.Trim() }
注意:这种写法不能解决 Write-Host 在某些旧版 conhost 中的渲染问题,建议优先用 Write-Output 或 Write-Information。











