Private/Write-Utf8TextFile.ps1
|
<# .SYNOPSIS Writes text to a file as UTF-8, with or without a byte order mark, exactly as given (no newline is added). .DESCRIPTION Set-Content -Encoding UTF8 writes a BOM on Windows PowerShell 5.1 but not on PowerShell 7, so files written by the same command differed between editions. This helper makes the BOM explicit: - PowerShell 7: Set-Content with utf8BOM or utf8NoBOM. - Windows PowerShell 5.1: Set-Content -Encoding UTF8 for a BOM; System.IO.File for no BOM. In Constrained Language Mode (where .NET methods are blocked) the file is written with a BOM instead. .PARAMETER Path The file to write. Relative paths are resolved against the current PowerShell location. .PARAMETER Content The text to write. .PARAMETER Utf8Bom Write a UTF-8 byte order mark. #> function Write-Utf8TextFile { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [AllowEmptyString()] [string]$Content, [switch]$Utf8Bom ) if ($PSVersionTable.PSEdition -eq 'Core') { $encoding = if ($Utf8Bom) { 'utf8BOM' } else { 'utf8NoBOM' } Set-Content -LiteralPath $Path -Value $Content -Encoding $encoding -NoNewline -Force -ErrorAction Stop -WhatIf:$false -Confirm:$false return } if ($Utf8Bom -or $ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') { Set-Content -LiteralPath $Path -Value $Content -Encoding UTF8 -NoNewline -Force -ErrorAction Stop -WhatIf:$false -Confirm:$false return } $fullPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Path) [System.IO.File]::WriteAllText($fullPath, $Content, (New-Object -TypeName System.Text.UTF8Encoding -ArgumentList $false)) } |