簡短描述
描述 PowerShell 如何針對字串數據的輸入和輸出使用字元編碼。
完整描述
Unicode 是全球字元編碼標準。 系統會以獨佔方式使用 Unicode 進行字元和字串操作。 如需 Unicode 所有層面的詳細描述,請參閱 Unicode Standard。
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 中,除了 UTF7之外,任何 Unicode 編碼一律都會建立 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 大端序位元組順序。 -
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-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使用 BOM 建立Utf8檔案。 使用 Append 參數時,編碼方式可能不同(請參閱下方)。
針對附加至現有檔案的命令:
Out-File -Append和>>重新導向運算符不會嘗試比對現有目標檔案內容的編碼。 相反地,除非使用 Encoding 參數,否則會使用預設編碼。 附加內容時,您必須使用檔案的原始編碼方式。如果沒有明確的 Encoding 參數,
Add-Content會偵測現有的編碼,並自動將它套用至新的內容。 如果現有的內容沒有 BOM,則會使用 anSI 編碼Default。Add-Content的行為在 PowerShell(v6 及更高版本)中相同,只是其預設編碼是Utf8。當目標檔案包含 BOM 時,
Export-Csv -Append符合現有的編碼。 如果沒有 BOM,它會使用Utf8編碼。Start-Transcript -Append符合包含 BOM 之檔案的現有編碼方式。 在沒有 BOM 的情況下,預設會編碼為Ascii。 當文字記錄中的數據包含多位元組字元時,此編碼可能會導致資料遺失或字元損毀。
對於在沒有 BOM 的情況下讀取字串數據的 Cmdlet:
Get-Content和Import-PowerShellDataFile使用DefaultANSI 編碼。 ANSI 也是 PowerShell 引擎從檔案讀取原始程式碼時所使用的專案。在沒有 BOM 的情況下,
Import-Csv、Import-Clixml和Select-String假設Utf8。
PowerShell 中的字元編碼
在 PowerShell (v7.1 和更新版本中),Encoding 参數支援下列值:
-
ascii:使用 ASCII (7 位) 字元集的編碼方式。 -
ansi:使用目前文化特性的 ANSI 碼頁編碼。 此選項已在PowerShell 7.4中新增。 -
bigendianunicode:使用大端位元組順序以 UTF-16 格式編碼。 -
bigendianutf32:使用大端位元組順序以 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格式編碼。
PowerShell 預設為所有輸出 utf8NoBOM。
從 PowerShell 6.2 開始,編碼 參數也允許已註冊代碼頁的數值識別元(例如 -Encoding 1251)或已註冊代碼頁的字串名稱(例如 -Encoding "windows-1251")。 如需詳細資訊,請參閱 Encoding.CodePage的 .NET 檔。
從 PowerShell 7.4 開始,您可以使用 ANSI 參數的 值,即可傳遞當前文化的 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 用來儲存至檔案的編碼方式。