簡短描述
描述 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
位元組順序標記
位元組順序標記 (BOM) 是 檔案或文字數據流前幾個位元組的 Unicode 簽章 ,表示用於數據的 Unicode 編碼。 如需詳細資訊,請參閱 位元組順序標記 檔。
在 Windows PowerShell 中,除了 以外的任何 Unicode 編碼 UTF7,一律會建立 BOM。 PowerShell (v6 和更新版本)預設 utf8NoBOM 為所有文字輸出。
為獲得最佳整體相容性,請避免在UTF-8檔案中使用 BOM。 Windows 平臺上也使用 Unix 平臺和 Unix 傳統公用程式不支援 BOM。
同樣地, UTF7 應該避免編碼。 UTF-7 不是標準 Unicode 編碼,而且在所有版本的 PowerShell 中都未撰寫 BOM。
在類似 Unix 的平臺或使用 Windows 上的跨平台編輯器建立 PowerShell 腳本,例如 Visual Studio Code,會導致使用 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搭配位元組順序。 -
Unknown與Unicode相同。 -
UTF32使用UTF-32搭配位元組順序。 -
UTF7使用UTF-7。 -
UTF8使用UTF-8(含 BOM)。
一般而言,Windows PowerShell 預設會使用 Unicode UTF-16LE 編碼。 不過,Windows PowerShell 中 Cmdlet 所使用的預設編碼方式並不一致。
注意
使用任何 Unicode 編碼,除了 之外 UTF7,一律會建立 BOM。
對於將輸出寫入檔案的 Cmdlet:
Out-File和 重新導向運算符>,並>>建立UTF-16LE,這明顯與Set-Content和Add-Content不同。New-ModuleManifest和Export-Clixml也會建立UTF-16LE檔案。當目標檔案是空的或不存在時,
Set-Content並使用Add-ContentDefault編碼。Default是使用中系統地區設定的 ANSI 舊版代碼頁所指定的編碼方式。Export-Csv會Ascii建立檔案,但在使用Append參數時使用不同的編碼方式(請參閱下文)。Export-PSSession預設會建立具有 BOM 的 UTF-8 檔案。New-Item -Type File -Value會建立無 BOM 的 UTF-8 檔案。Send-MailMessage預設會使用Ascii編碼。Start-TranscriptUtf8使用 BOM 建立檔案。 使用 Append 參數時,編碼方式可能不同(請參閱下方)。
針對附加至現有檔案的命令:
Out-File -Append和 重新>>導向運算子不會嘗試比對現有目標檔案內容的編碼方式。 除非使用 Encoding 參數,否則會改用預設編碼。 附加內容時,您必須使用檔案的原始編碼方式。如果沒有明確的 Encoding 參數,
Add-Content就會偵測現有的編碼,並自動將它套用至新的內容。 如果現有的內容沒有 BOM,Default則會使用 ANSI 編碼。 的行為Add-Content在 PowerShell 中相同(v6 和更新版本),但預設編碼方式為Utf8。Export-Csv -Append當目標檔案包含 BOM 時,會比對現有的編碼。 如果沒有 BOM,它會使用Utf8編碼。Start-Transcript -Append符合包含 BOM 之檔案的現有編碼方式。 如果沒有 BOM,則預設為Ascii編碼。 當文字記錄中的數據包含多位元組字元時,此編碼可能會導致資料遺失或字元損毀。
對於在沒有 BOM 的情況下讀取字串數據的 Cmdlet:
Get-Content和Import-PowerShellDataFile會使用DefaultANSI 編碼。 ANSI 也是 PowerShell 引擎從檔案讀取原始程式碼時所使用的專案。Import-Csv、Import-Clixml、 和Select-String假設Utf8沒有 BOM。
PowerShell 中的字元編碼
在 PowerShell(v7.1 和更新版本中), Encoding 參数支援下列值:
-
ascii:使用 ASCII (7 位) 字元集的編碼方式。 -
ansi:針對目前文化特性的 ANSI 代碼頁,使用 的編碼方式。 此選項已在PowerShell 7.4中新增。 -
bigendianunicode:使用 big-endian 位元組順序以 UTF-16 格式編碼。 -
bigendianutf32:使用 big-endian 位元組順序以 UTF-32 格式編碼。 -
oem:使用 MS-DOS 和控制台程式的預設編碼方式。 -
unicode:使用位元組順序以UTF-16格式編碼。 -
utf7:以 UTF-7 格式編碼。 -
utf8:以 UTF-8 格式編碼(無 BOM)。 -
utf8BOM:使用位元節順序標記以 UTF-8 格式編碼 (BOM) -
utf8NoBOM:以 UTF-8 格式編碼,不含位元組順序標記 (BOM) -
utf32:使用位元組順序以UTF-32 格式編碼。
所有輸出的 utf8NoBOM PowerShell 預設為 。
從 PowerShell 6.2 開始,Encoding 參數也允許已註冊代碼頁的數值識別元(例如 -Encoding 1251)或已註冊代碼頁的字串名稱(例如 )。-Encoding "windows-1251" 如需詳細資訊,請參閱 Encoding.CodePage 的 .NET 檔。
從 PowerShell 7.4 開始,您可以使用 ANSI Encoding 參數的值,傳遞目前文化特性 ANSI 代碼頁的數值標識碼,而不需要手動指定它。
變更預設編碼
PowerShell 有兩個預設變數,可用來變更預設編碼行為。
$PSDefaultParameterValues$OutputEncoding
如需詳細資訊,請參閱 about_Preference_Variables。
從 PowerShell 5.1 開始,重新導向運算符 (> 和 >>) 會呼叫 Out-File Cmdlet。 因此,您可以使用喜好設定變數的預設編碼方式 $PSDefaultParameterValues ,如下列範例所示:
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
使用下列語句來變更具有 Encoding 參數之所有 Cmdlet 的預設編碼方式。
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
重要
將此命令放在 PowerShell 配置檔中,可讓喜好設定成為會影響未明確指定編碼之所有命令和腳本的會話全域設定。
同樣地,您應該在想要以相同方式運作的腳本或模組中包含這類命令。 使用這些命令可確保即使其他使用者、在不同的計算機上或不同版本的PowerShell上執行,Cmdlet的行為也一樣。
自動變數 $OutputEncoding 會影響PowerShell用來與外部程式通訊的編碼方式。 它不會影響輸出重新導向運算符和 PowerShell Cmdlet 用來儲存至檔案的編碼方式。