介绍 PowerShell 如何使用字符编码来输入和输出字符串数据。

Unicode 是一种全球字符编码标准。 系统专门使用 Unicode 进行字符和字符串操作。 有关 Unicode 所有方面的详细说明,请参阅 Unicode 标准 版。

Windows 支持 Unicode 和传统字符集。 传统字符集(如 Windows 代码页)使用 8 位值或 8 位值的组合来表示特定语言或地理区域设置中使用的字符。

PowerShell 默认使用 Unicode 字符集。 但是,多个 cmdlet 有一个 Encoding 参数,可以指定不同字符集的编码。 此参数允许你选择与其他系统和应用程序互操作所需的特定字符编码。

以下 cmdlet 具有 Encoding 参数:

  • Microsoft.PowerShell.Management
    • Add-Content
    • Get-Content
    • Set-Content
    • Microsoft.PowerShell.Utility
      • Export-Clixml
      • Export-Csv
      • Export-PSSession
      • Format-Hex
      • Import-Csv
      • Out-File
      • Select-String
      • Send-MailMessage
      • byte-order-mark

        BOM) (字节顺序标记是文件或文本流的前几个字节中的 Unicode 签名 ,指示用于数据的 Unicode 编码。 有关详细信息,请参阅 字节顺序标记 文档。

        在 Windows PowerShell 中,除 之外 UTF7 的任何 Unicode 编码始终创建 BOM。 对于所有文本输出,PowerShell (v6 及更高版本) 默认 utf8NoBOM 为 。

        为了获得最佳整体兼容性,请避免在 UTF-8 文件中使用 BOM。 Windows 平台上也使用的 Unix 平台和 Unix 遗产实用工具不支持 BOM。

        同样, UTF7 应避免编码。 UTF-7 不是标准 Unicode 编码,在所有版本的 PowerShell 中都是在没有 BOM 的情况下编写的。

        在类似于 Unix 的平台上或使用 Windows 上的跨平台编辑器(如 Visual Studio Code)创建 PowerShell 脚本,会导致使用 UTF8NoBOM 进行编码的文件。 这些文件在 PowerShell 中正常工作,但如果文件包含非 Ascii 字符,则可能会中断Windows PowerShell。

        如果需要在脚本中使用非 Ascii 字符,请使用 BOM 将它们另存为 UTF-8。 如果没有 BOM,Windows PowerShell会将脚本错误解释为在旧版“ANSI”代码页中编码。 相反,具有 UTF-8 BOM 的文件在类似 Unix 的平台上可能会出现问题。 许多 Unix 工具(如 cat sed awk )和某些编辑器(例如 gedit )不知道如何处理 BOM。

        Windows PowerShell 中的字符编码

        在 PowerShell 5.1 中, Encoding 参数支持以下值:

      • Ascii 使用 Ascii (7 位) 字符集。
      • BigEndianUnicode 将 UTF-16 与 big-endian 字节顺序一起使用。
      • BigEndianUTF32 将 UTF-32 与 big-endian 字节顺序一起使用。
      • Byte 将一组字符编码为字节序列。
      • Default 使用与系统的活动代码页相对应的编码 (通常为 ANSI) 。
      • Oem 使用对应于系统的当前 OEM 代码页的编码。
      • String Unicode 相同。
      • Unicode 将 UTF-16 与 little-endian 字节顺序一起使用。
      • Unknown Unicode 相同。
      • UTF32 将 UTF-32 与 little-endian 字节顺序一起使用。
      • UTF7 使用 UTF-7。
      • UTF8 将 UTF-8 (与 BOM) 配合使用。
      • 通常,Windows PowerShell默认使用 Unicode UTF-16LE 编码。 但是,Windows PowerShell中 cmdlet 使用的默认编码不一致。

        使用除 之外 UTF7 的任何 Unicode 编码始终创建 BOM。

        对于将输出写入文件的 cmdlet:

      • Out-File 和 重定向运算符 > >> 创建 UTF-16LE,这与 和 Add-Content 明显不同 Set-Content

      • New-ModuleManifest 以及 Export-CliXml 创建 UTF-16LE 文件。

      • 当目标文件为空或不存在时, Set-Content Add-Content 请使用 Default 编码。 Default 是由活动系统区域设置的 ANSI 旧代码页指定的编码。

      • Export-Csv Ascii 创建文件,但在使用 Append 参数时使用不同的编码 (请参阅以下) 。

      • Export-PSSession 默认情况下,使用 BOM 创建 UTF-8 文件。

      • New-Item -Type File -Value 创建无 BOM 的 UTF-8 文件。

      • Send-MailMessage 默认情况下使用 Ascii 编码。

      • Start-Transcript Utf8 使用 BOM 创建文件。 使用 Append 参数时,编码可能不同, (请参阅以下) 。

        对于追加到现有文件的命令:

      • Out-File -Append >> 重定向运算符不会尝试匹配现有目标文件内容的编码。 他们改用默认编码,除非使用 Encoding 参数。 追加内容时,必须使用文件原始编码。

      • 在没有显式 编码 参数的情况下, Add-Content 检测现有编码并将其自动应用于新内容。 如果现有内容没有 BOM, Default 则使用 ANSI 编码。 在 PowerShell (v6 及更高版本) 中的行为 Add-Content 相同,但默认编码为 Utf8

      • Export-Csv -Append 当目标文件包含 BOM 时,匹配现有编码。 在没有 BOM 的情况下,它使用 Utf8 编码。

      • Start-Transcript -Append 匹配包含 BOM 的文件的现有编码。 如果没有 BOM,则默认为 Ascii 编码。 如果脚本中的数据包含多字节字符,则此编码可能导致数据丢失或字符损坏。

        对于在没有 BOM 的情况下读取字符串数据的 cmdlet:

      • Get-Content Import-PowerShellDataFile 使用 Default ANSI 编码。 ANSI 也是 PowerShell 引擎在从文件中读取源代码时使用的内容。

      • Import-Csv Import-CliXml Select-String 假设 Utf8 没有 BOM。

        PowerShell 中的字符编码

        在 PowerShell (v7.1 及更高版本) 中, Encoding 参数支持以下值:

      • ascii :使用 ASCII (7 位) 字符集的编码。
      • bigendianunicode :使用 big-endian 字节顺序以 UTF-16 格式进行编码。
      • bigendianutf32 :使用 big-endian 字节顺序以 UTF-32 格式进行编码。
      • oem :使用 MS-DOS 和控制台程序的默认编码。
      • unicode :使用 little-endian 字节顺序以 UTF-16 格式进行编码。
      • utf7 :以 UTF-7 格式进行编码。
      • utf8 :以 UTF-8 格式编码, (无 BOM) 。
      • utf8BOM :使用字节顺序标记 (BOM) 以 UTF-8 格式进行编码
      • utf8NoBOM :以 UTF-8 格式编码,不带字节顺序标记 (BOM)
      • utf32 :使用 little-endian 字节顺序以 UTF-32 格式进行编码。
      • 对于所有输出, utf8NoBOM PowerShell 默认为 。

        从 PowerShell 6.2 开始, Encoding 参数还允许注册代码页的数字 ID () -Encoding 1251 或已注册代码页的字符串名称 () -Encoding "windows-1251" 。 有关详细信息,请参阅 Encoding.CodePage 的 .NET 文档。

        更改默认编码

        PowerShell 有两个默认变量,可用于更改默认编码行为。

      • $PSDefaultParameterValues
      • $OutputEncoding
      • 有关详细信息,请参阅 about_Preference_Variables

        从 PowerShell 5.1 开始,重定向运算符 ( > >> ) 调用 Out-File cmdlet。 因此,可以使用首选项变量设置它们 $PSDefaultParameterValues 的默认编码,如以下示例所示:

        $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
        

        使用以下语句更改具有 Encoding 参数的所有 cmdlet 的默认 编码

        $PSDefaultParameterValues['*:Encoding'] = 'utf8'
        

        将此命令放在 PowerShell 配置文件中会使首选项成为会话全局设置,该设置会影响未显式指定编码的所有命令和脚本。

        同样,应在脚本或模块中包含要以相同方式运行的此类命令。 使用这些命令可确保 cmdlet 的行为方式相同,即使由另一个用户、在另一台计算机上或在 PowerShell 的其他版本中运行也是如此。

        自动变量 $OutputEncoding 会影响 PowerShell 用于与外部程序通信的编码。 它不会影响输出重定向运算符和 PowerShell cmdlet 用于保存到文件的编码。

      • about_Preference_Variables
      • 字节顺序标记
      • 代码页 - Win32 应用
      • Encoding.CodePage
      • .NET 中的字符编码简介
      • Unicode 标准
      • UTF-16LE
  •