Как экранировать не-ascii символы в PowerShell 5.1?

Я отправляю на сервер содержимое файла:

$uri = ...
$headers = @{
    ...
    "Content-Type" = "application/json"
}
[string] $content = Get-Content .\filename -Encoding utf8 -Raw
$body = @{
    ...
    "content" = $content
} | ConvertTo-Json
$response = Invoke-WebRequest $uri -Method 'PUT' -Headers $headers -Body $body

Но все не-ascii символы меняются либо на похожие ascii, либо на вопросики

Как я могу их экранировать?

Я читал документацию и знаю про параметр -EscapeHandling у командлета ConvertTo-Json, но он доступен с PowerShell 6.2, у меня же версия 5.1


Ответы (1 шт):

Автор решения: Андрей NOP

В итоге написал простенькую функцию:

function EscapeNonAscii([string] $s)
{
    $sb = New-Object System.Text.StringBuilder;
    for ([int] $i = 0; $i -lt $s.Length; $i++)
    {
        $c = $s[$i];
        if ($c -gt 127)
        {
            $sb = $sb.Append("\u").Append(([int] $c).ToString("X").PadLeft(4, "0"));
        }
        else
        {
            $sb = $sb.Append($c);
        }
    }
    return $sb.ToString();
}

И использовал ее так:

$updateFileResponse = Invoke-WebRequest $updateFileUri -Method 'PUT' -Headers $headers -Body (EscapeNonAscii $body)

Это сработало. Странно, что не помогала установка заголовка "Content-Type" = "application/json; charset=utf-8". Ну и для будущих гуглящих, это обращение к API GitLab Update existing file in repository

PS: Я пишу на PS как на C#, потому что PS толком не знаю, если у кого есть идеи как переписать это более по павершельному — you're welcome.

PPS: Ну и я знаю, что StringBuilder.Append меняет существующий объект, а не возвращает новый, но я добавляю здесь присваивание ($sb = $sb.Append($c) вместо простого $sb.Append($c)), т. к. без него каждая строчка будет еще и на консоль выведена, если знаете как исправить без этого костыля, тоже, пожалуйста, напишите.

→ Ссылка