Традиционные приложения Windows запускаемые в консоли cmd.exe, как правило не являются unicode-приложениями. Иначе говоря, они ожидают ввод и выводят информацию в обычной кодировке, например, CP866 или CP1251. С другой стороны, Powershell является unicode-приложением. Это означает, что Powershell должен выполнять перекодировку в обе стороны при вызове native application. По умолчанию он это делает в большинстве случаев правильно. Но если на целевой системе вместо кодировки по умолчанию для non-unicode программ стоит не «Русский», что соответствует CP866, а «Английский» - CP437, при работе «русской» native application мы получим проблемы: программа не будет понимать ввод, а ее вывод будет абракадаброй.
В Powershell за перекодировку отвечают две переменные:
[Console]::OutputEncoding : отвечает за перекодировку <native application> -> <Powershell>
$OutputEncoding : отвечает за перекодировку <Powershell> -> <native application>
Есть ещё [Console]::InputEncoding, которая отвечает за ввод с клавиатуры в консольное приложение.
Например при попытке получить результат команды ping увидим такое:
Посмотрим кодировку в обоих консолях следующей командой [Console]::outputEncoding
ISE:
Powershell консоль:
Исправляем ситуацию - вставляем в рабочий профиль Powershell следующие три команды:
chcp
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')
chcp
Выполняем:
’ҐЄгй п Є®¤®ў п бва Ёж : 866
Текущая кодовая страница: 866
Все Ок.
function ConvertTo-Encoding ([string]$From, [string]$To){
ReplyDeleteBegin{
$encFrom = [System.Text.Encoding]::GetEncoding($from)
$encTo = [System.Text.Encoding]::GetEncoding($to)
}
Process{
$bytes = $encTo.GetBytes($_)
$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
$encTo.GetString($bytes)
}
}
Invoke-Command -ScriptBlock { dism /? } -ComputerName testcomp | ConvertTo-Encoding -From cp866 -To windows-1251