private/Set-XmlFile.ps1

function Set-XmlFile {

    <#
        .SYNOPSIS
        (Re-)Write the given XML file in a normalized way.

        .DESCRIPTION

    #>


    [CmdletBinding()]
    param (
        # Path + file name of the target file to be (re)written.
        # Directory will be created if it does not exist.
        # File will be created if non-existent and overwritten if existing.
        [Parameter(Mandatory, Position=0)]
        [ValidateNotNullOrEmpty()]
        [string] $FilePath,

        # A string with the raw xml.
        [Parameter(Mandatory, Position=1)]
        [ValidateNotNullOrEmpty()]
        [string] $XmlString
    )

    $ErrorActionPreference = 'Stop'
    [bool] $IsDebug   = $DebugPreference   -ne 'SilentlyContinue'
    [bool] $IsVerbose = $VerbosePreference -ne 'SilentlyContinue'

    Write-Debug "(Re-)Writing [$FilePath]"

    # --- force-create the target file path
    $DirectoryPath = Split-Path $FilePath -Parent
    $Directory = New-Item -ItemType Directory -Path $DirectoryPath -Force

    # --- Prepare the XML Document from our raw xml formatted string
    [xml]$xmlDocument = $XmlString

    # --- Prepare the XML Writer Settings to generate an UTF-8 encoded .xml file with unix-style LF
    $XmlSettings = [Xml.XmlWriterSettings]::new()
    $XmlSettings.Encoding = [System.Text.Encoding]::UTF8
    $XmlSettings.Indent = $true
    $XmlSettings.IndentChars = ' '
    $XmlSettings.NewLineChars = "`n"

    # --- Prepare the XML Writer and save the XML Document to it
    $xmlWriter = [System.XML.XmlWriter]::Create($FilePath, $XmlSettings)
    $xmlDocument.Save($xmlWriter)
    $xmlWriter.Close()

    # --- post-processing of the resulting file to
    # a) remove BOM by explicitlty rewriting without BOM
    # b) enforce last line ending with LF as EOL
    # c) enforce encoding attribute in XML declaration to be in upper case
    $Content = Get-Content $FilePath -Raw # return a single string (as apposed to a string array)
    if (!($Content.EndsWith("`n"))) {
        $Content += "`n"
    }
    $Content = $Content.Replace('<?xml version="1.0" encoding="utf-8"?>', '<?xml version="1.0" encoding="UTF-8"?>')
    Set-Content $FilePath $Content -Encoding utf8NoBOM -NoNewLine
}