Gốc rễ vấn đề: mỗi lệnh một bảng mã
Trong Windows PowerShell 5.1, gần như mỗi lệnh có bảng mã mặc định riêng: Get-Content đọc file không có BOM theo ANSI (Windows-1252, hoặc Windows-1258 nếu hệ thống đặt ngôn ngữ tiếng Việt), Out-File và > ghi UTF-16, Set-Content ghi ANSI, còn Export-Csv ghi ASCII. PowerShell 7 đã thống nhất và dùng UTF-8 không BOM ở mọi nơi.
Trước
Ngêi dïng;Phßng ban;Chi nh¸nh NguyÔn V¨n Hïng;Kinh doanh;§µ N½ng TrÇn ThÞ Mai;Mua hµng;H¶i Phßng
Sau
Người dùng;Phòng ban;Chi nhánh Nguyễn Văn Hùng;Kinh doanh;Đà Nẵng Trần Thị Mai;Mua hàng;Hải Phòng
Đọc và ghi file đúng cách
Get-Content data.csv -Encoding UTF8đọc đúng file UTF-8 kể cả khi không có BOM.Set-Content,Out-FilevàAdd-Contentghi UTF-8 khi có-Encoding UTF8– trong 5.1 luôn kèm BOM.Export-Csv data.csv -Encoding UTF8 -NoTypeInformationthay cho mặc định ASCII, vốn thay chữ có dấu bằng?.- Cho tất cả lệnh cùng lúc:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'ở đầu script.
Yêu cầu web với Invoke-RestMethod và Invoke-WebRequest
Nếu máy chủ không ghi bộ ký tự trong Content-Type, Windows PowerShell 5.1 giải mã phản hồi theo ISO-8859-1. Phản hồi UTF-8 khi đó bị vỡ chữ Việt. Cách xử lý: lấy phản hồi dưới dạng byte rồi tự giải mã, ví dụ [Text.Encoding]::UTF8.GetString((Invoke-WebRequest $url).RawContentStream.ToArray()).
File script có chữ tiếng Việt
Nếu bạn lưu script là UTF-8 không BOM, Windows PowerShell 5.1 đọc nó theo ANSI. Chữ trong chuỗi như Write-Host "Xin chào" sẽ bị vỡ. Hãy lưu file .ps1 là UTF-8 có BOM – trong VS Code qua bảng mã ở thanh trạng thái, trong Notepad++ qua menu Encoding (Mã hóa) rồi chọn UTF-8-BOM.
Cửa sổ console
Nếu chỉ cửa sổ console hiện sai ký tự, file thường vẫn ổn – console đọc UTF-8 theo trang mã DOS (437 hay 850) hoặc phông chữ không hiển thị được dấu. Đổi đầu ra bằng [Console]::OutputEncoding = [Text.Encoding]::UTF8. Với dữ liệu chuyển sang chương trình ngoài, đặt thêm $OutputEncoding = [Text.Encoding]::UTF8.
Nếu file đã ghi hỏng, hãy thả vào ô phía trên: Mojibuster sửa các lỗi như á và chuyển file ANSI sang UTF-8. Còn nếu file đã chứa dấu hỏi thì chữ đã mất, xem mojibake là gì. Văn bản gõ bằng font cũ (TCVN3, VNI) xem sửa lỗi font tiếng Việt.
Câu hỏi thường gặp
Tôi đang dùng phiên bản PowerShell nào?
$PSVersionTable.PSVersion cho biết. 5.1 là Windows PowerShell có sẵn trong Windows; từ 7 trở đi chỉ gọi là PowerShell và mặc định dùng UTF-8.
Vì sao Excel mở file CSV từ PowerShell bị lỗi font?
PowerShell 7 ghi UTF-8 không BOM nên Excel không nhận ra. Dùng -Encoding utf8BOM hoặc lưu file có BOM trong Mojibuster. Xem thêm lỗi font Excel và CSV.
Tôi có cần chcp 65001 không?
Chỉ với chương trình theo trang mã của console. Trong PowerShell, [Console]::OutputEncoding là đủ.