Автор
Тема: Изменить язык в консоли PowerShell в русской Windows (Прочитано 24852 раз)
Всем привет. Мне кажется на форуме не хватает ветки по PowerShell. Там народ делился бы скриптами и все такое…
И сразу вопрос, как сделать вывод в консоль powershell на английском языке. ОС на русском, а вывод на английском !
Есть у кого какие идеи ?
« Последнее редактирование: 05 Ноября 2019, 07:39:50 от itpro »
Привествую!
Создал отдельную ветку по PoSh и перенес ваш топик.
По проблеме:
Текущую локализацию PowerShell можно получить с помощью команды:
get-UIculture
Скорее всего у вас так:
LCID Name DisplayName
—- —- ————
1049 ru-RU Русский (Россия)
Попробуйте установить английский LangugePack для Windows 10 и сменить язык так:
Set-Culture en-US
Либо попробуйте после установки LP, сделать Englich языком по умолчанию для новых пользователей, создать пользователя и посмотреть что будет в консоли PowerShell
Спасибо
В данной статье приведу несколько практических примеров по изменению кодировки в PowerShell. Ранее я уже публиковал статью про смену кодировки, когда не отображались кириллические символы, сейчас рассмотрю тему более подробно.
Смена кодировки вывода в консоль
Сменить кодировку вывода в консоль можно одним из предложенных ниже способов:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")
В данных примерах меняем ее на utf8. Это решает проблему с отображением кириллицы. Решение будет действовать только в текущем сеансе консоли.
Кракозябры в PowerShell ISE можно побороть вот так (сменив кодировку на cp866):
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')
При сборке скрипта в exe файл через Win-PS2EXE тоже были проблемы с кодировкой при выводе кириллицы:
В Windows 10 помогло это:
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("windows-1251")
В Win7 нужную кодировку не подобрал.
Смена кодировки вывода в файл Out-File
Вывод результата консольной утилиты, запущенной через PowerShell, в txt файл выдавал кракозябры. Помогло использование параметра -Encoding и выбор кодировки oem в конвейере в качестве параметра командлета Out-File (в примере zab_api.exe это консольная утилита, вывод которой нужно было писать в файл).
.\zab_api.exe | Out-File data.txt -Encoding oem
Глобальная смена кодировки на уровне системы
В этом решении будет рассказано как решить этот вопрос глобально.
Win + R -> Intl.cpl -> OK
На вкладке «Дополнительно»(«Administrative») Измените язык для программ, не поддерживающих Юникод — выберите Русский (Russian)
Перезагрузите систему
Время на прочтение6 мин
Количество просмотров151K
В процессе разработки очень часто возникает необходимость запустить из powershell скрипта консольное приложение. Что может быть проще?
#test.ps1
& $PSScriptRoot\ConsoleApp.exe
Изучим поведение консольных приложений при запуске их из командной строки, через PowerShell и через PowerShell ISE:
Результат выполнения
В PowerShell ISE возникла проблема с кодировкой, так как ISE ожидает вывод в кодировке 1251. Воспользуемся гуглом и найдем два решения проблемы: c использованием [Console]::OutputEncoding и через powershell pipeline. Воспользуемся первым решением:
test2.ps1
$ErrorActionPreference = "Stop"
function RunConsole($scriptBlock)
{
$encoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
try
{
&$scriptBlock
}
finally
{
[Console]::OutputEncoding = $encoding
}
}
RunConsole {
& $PSScriptRoot\ConsoleApp1.exe
}
Результат выполнения
В командной строке все хорошо, а вот в ISE ошибка. Exception setting «OutputEncoding»: «The handle is invalid.». Снова берем в руки гугл, и в первом же результате находим решение — надо запустить какое-нибудь консольное приложение для создания консоли. Ну что-же, попробуем.
test3.ps1
$ErrorActionPreference = "Stop"
function RunConsole($scriptBlock)
{
# Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
& cmd /c ver | Out-Null
$encoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
try
{
&$scriptBlock
}
finally
{
[Console]::OutputEncoding = $encoding
}
}
RunConsole {
& $PSScriptRoot\ConsoleApp1.exe
}
Результат выполнения
Все красиво, все работает. Кто читал мою прошлую заметку, обратил внимание, что WinRM приносит нам много острых впечатлений. Попробуем запустить тест через WinRM. Для запуска воспользуемся вот таким скриптом:
remote1.ps1
param($script)
$ErrorActionPreference = "Stop"
$s = New-PSSession "."
try
{
$path = "$PSScriptRoot\$script"
Invoke-Command -Session $s -ScriptBlock { &$using:path }
}
finally
{
Remove-PSSession -Session $s
}
Результат выполнения
Что-то пошло не так. Решение с созданием консоли не работает. Ранее мы находили два решения проблемы кодировки. Попробуем второй:
test4.ps1
$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"
function RunConsole($scriptBlock)
{
function ConvertTo-Encoding ([string]$From, [string]$To)
{
Begin
{
$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)
}
}
Write-Verbose "RunConsole: Pipline mode"
&$scriptBlock | ConvertTo-Encoding cp866 windows-1251
}
RunConsole {
& $PSScriptRoot\ConsoleApp1.exe
}
Результат выполнения
В ISE и через WinRM решение работает, а вот через командную строку и shell — нет.
Надо объединить эти два способа и проблема будет решена!
test5.ps1
$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"
function RunConsole($scriptBlock)
{
if([Environment]::UserInteractive)
{
# Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
& cmd /c ver | Out-Null
$encoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
try
{
Write-Verbose "RunConsole: Console.OutputEncoding mode"
&$scriptBlock
return
}
finally
{
[Console]::OutputEncoding = $encoding
}
}
function ConvertTo-Encoding ([string]$From, [string]$To)
{
Begin
{
$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)
}
}
Write-Verbose "RunConsole: Pipline mode"
&$scriptBlock | ConvertTo-Encoding cp866 windows-1251
}
RunConsole {
& $PSScriptRoot\ConsoleApp1.exe
}
Результат выполнения
Кажется, что проблема решена, но продолжим исследование и усложним наше консольное приложение, добавив в него вывод в stdError.
Результат выполнения
Становится все веселее В ISE исполнение скрипта прервалось на середине, а через WinRM мало того, что прервалось, так еще сообщение из stdErr прочитать невозможно. Первым шагом решим проблему с остановкой запускаемого из скрипта приложения, для этого перед запуском приложения изменим значение глобальной переменной $ErrorActionPreference.
test7.ps1
$ErrorActionPreference = "Stop"
#$VerbosePreference = "Continue"
function RunConsole($scriptBlock)
{
if([Environment]::UserInteractive)
{
# Популярное решение "устранения" ошибки: Exception setting "OutputEncoding": "The handle is invalid."
& cmd /c ver | Out-Null
$encoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
try
{
Write-Verbose "RunConsole: Console.OutputEncoding mode"
$prevErrAction = $ErrorActionPreference
$ErrorActionPreference = "Continue"
try
{
&$scriptBlock
return
}
finally
{
$ErrorActionPreference = $prevErrAction
}
}
finally
{
[Console]::OutputEncoding = $encoding
}
}
function ConvertTo-Encoding ([string]$From, [string]$To)
{
Begin
{
$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)
}
}
Write-Verbose "RunConsole: Pipline mode"
$prevErrAction = $ErrorActionPreference
$ErrorActionPreference = "Continue"
try
{
&$scriptBlock | ConvertTo-Encoding cp866 windows-1251
return
}
finally
{
$ErrorActionPreference = $prevErrAction
}
}
RunConsole {
& $PSScriptRoot\ConsoleApp2.exe
}
Write-Host "ExitCode = $LASTEXITCODE"
Результат выполнения
Для тех что знает о существовании параметра -ErrorAction
error.cmd
echo error message 1>&2
errorActionTest.ps1
#error.cmd
#echo error message 1>&2
#errorActionTest.ps1
$ErrorActionPreference = "Stop"
Write-Host "before"
Invoke-Expression -ErrorAction SilentlyContinue -Command $PSScriptRoot\error.cmd
Write-Host "after"
Какой будет результат выполнения такого скрипта?
Вторым шагом доработаем скрипт удаленного запуска через WinRM, чтобы он не падал:
remote2.ps1
param($script)
$ErrorActionPreference = "Stop"
$s = New-PSSession "."
try
{
$path = "$PSScriptRoot\$script"
$err = @()
$r = Invoke-Command -Session $s -ErrorAction Continue -ErrorVariable err -ScriptBlock `
{
$ErrorActionPreference = "Stop"
& $using:path | Out-Host
return $true
}
if($r -ne $true)
{
Write-Error "The remote script was completed with an error"
}
if($err.length -ne 0)
{
Write-Warning "Error occurred on remote host"
}
}
finally
{
Remove-PSSession -Session $s
}
Результат выполнения
И осталось самое сложное — скорректировать сообщение формируемое через stdErr и при этом не изменить его положение в логе. В процессе решения этой задачи коллеги предложили самостоятельно создать консоль, воспользовавшись win api функцией AllocConsole.
test8.ps1
$ErrorActionPreference = "Stop"
#$VerbosePreference = "continue"
$consoleAllocated = [Environment]::UserInteractive
function AllocConsole()
{
if($Global:consoleAllocated)
{
return
}
&cmd /c ver | Out-Null
$a = @'
[DllImport("kernel32", SetLastError = true)]
public static extern bool AllocConsole();
'@
$params = New-Object CodeDom.Compiler.CompilerParameters
$params.MainClass = "methods"
$params.GenerateInMemory = $true
$params.CompilerOptions = "/unsafe"
$r = Add-Type -MemberDefinition $a -Name methods -Namespace kernel32 -PassThru -CompilerParameters $params
Write-Verbose "Allocating console"
[kernel32.methods]::AllocConsole() | Out-Null
Write-Verbose "Console allocated"
$Global:consoleAllocated = $true
}
function RunConsole($scriptBlock)
{
AllocConsole
$encoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
$prevErrAction = $ErrorActionPreference
$ErrorActionPreference = "Continue"
try
{
& $scriptBlock
}
finally
{
$ErrorActionPreference = $prevErrAction
[Console]::OutputEncoding = $encoding
}
}
RunConsole {
& $PSScriptRoot\ConsoleApp2.exe
}
Write-Host "ExitCode = $LASTEXITCODE"
Избавится от информации, которую добавляет powershell к stdErr мне так и не удалось.
Надеюсь, что эта информация окажется полезной не только мне!
update 1
В некоторых сценариях использования создавалась дополнительная консоль, в которую выдавался результат выполнения скриптов. В скрипт test8.ps1 внесены исправления.
update 2
Так как у многих комментаторов статьи возникла путаница между понятиями набор символов (char set) и кодировка (encoding) хотел бы еще раз обратить внимание, что в статье решается проблема именно несоответствия кодировок консоли и вызываемого приложения.
Как можно увидеть из скрипта test8.ps1, кодировка указывается в статическом свойстве [Console]::OutputEncoding, и никто не мешает указать в нем одну из кодировок семейства unicode:
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")
Но, для работы скрипта в стандартной консоли windows (aka cmd.exe) необходимо изменить шрифт консоли со стандартного «Rasters Fonts» на Consolas или «Lucida Console». Если бы данные скрипты мы использовали только на собственных рабочих станциях или серверах, то такое изменение было бы допустимо, но так как нам приходится распространять наши решения заказчикам, вмешиваться в системные настройки серверов мы не имеем права. Именно по этой причине в скриптах используется cp866, как кодировка настроенная по умолчанию для консоли.
-
Unicode in PowerShell
-
Change System Locale to Use UTF-8 Encoding in Windows PowerShell
-
Set Encoding in
$PSDefaultParameterValues
Variable to Use UTF-8 Encoding in Windows PowerShell -
Use the
chcp
Command to Switch to UTF-8 Encoding in Windows PowerShell -
Benefits of Using UTF-8 Encoding in PowerShell
-
Conclusion
UTF-8 encoding, represented by CHCP 65001
in PowerShell, is a pivotal tool for working with multilingual and special characters in the console.
This article will provide a comprehensive guide on how to utilize UTF-8 encoding in PowerShell, from understanding its significance to practical implementation.
Unicode in PowerShell
Unicode is a worldwide character encoding standard. It defines how characters in text files, web pages, and other documents are represented.
The computer system uses Unicode to manipulate characters and strings. The default encoding in PowerShell is Windows-1252.
Unicode was developed to support characters from all languages of the world. PowerShell supports a Unicode character encoding by default.
UTF-8 and UTF-16 are the most common Unicode encodings. PowerShell always uses BOM
in all Unicode encodings except UTF7.
The BOM
(byte-order-mark) is a Unicode signature included in the first few bytes of a file or text stream that indicates the Unicode encoding.
Understanding UTF-8 Encoding
UTF-8 is a character encoding standard that uses variable-width encoding to represent text. It’s capable of encoding virtually all characters in Unicode, making it the most widely used character encoding on the internet.
In the context of PowerShell, UTF-8 encoding ensures that characters from different languages, symbols, and special characters are displayed and processed correctly in the console window.
Change System Locale to Use UTF-8 Encoding in Windows PowerShell
There is an option to change the system locale (current language for non-Unicode programs) in Windows. But this feature is still in beta.
Go to Region Settings
from the Control Panel
or open intl.cpl
from the Run
program (Windows+R).
Open the Administrative
tab and click Change system locale
. Then, check the Beta
option, as shown in the image below.
After that, press OK
and restart the computer to apply the settings.
After restarting the computer, you can check the $OutputEncoding
variable to view the current encoding.
Output:
As you can see, the current encoding is Unicode (UTF-8).
BodyName : utf-8
EncodingName : Unicode (UTF-8)
HeaderName : utf-8
WebName : utf-8
WindowsCodePage : 1200
IsBrowserDisplay : True
IsBrowserSave : True
IsMailNewsDisplay : True
IsMailNewsSave : True
IsSingleByte : False
EncoderFallback : System.Text.EncoderReplacementFallback
DecoderFallback : System.Text.DecoderReplacementFallback
IsReadOnly : True
CodePage : 65001
Now, you can view the characters of other languages in PowerShell.
Output:
Set Encoding in $PSDefaultParameterValues
Variable to Use UTF-8 Encoding in Windows PowerShell
$PSDefaultParameterValues
is a built-in automatic variable in PowerShell that allows you to set default values for cmdlet parameters. This means you can specify default values for parameters of cmdlets without having to explicitly provide them every time you use the cmdlet.
You can run the following command to activate the UTF-8 encoding in PowerShell.
$PSDefaultParameterValues = @{'*:Encoding' = 'utf8' }
It is only valid for the current PowerShell console. It will be reset to default after you exit the PowerShell window.
Output:
Several cmdlets in PowerShell have the -Encoding
parameter to specify the encoding for different character sets. Some of them are Add-Content
, Set-Content
, Get-Content
, Export-Csv
, Out-File
, etc.
The -Encoding
parameter supports these values: ascii
, bigendianunicode
, oem
, unicode
, utf7
, utf8
, utf8BOM
, utf8NoBOM
, utf32
.
Use the chcp
Command to Switch to UTF-8 Encoding in Windows PowerShell
To switch to UTF-8 encoding in PowerShell, use the chcp
command followed by 65001
:
This command tells PowerShell to use UTF-8 encoding for character input and output.
Here’s what this command does in detail:
-
chcp
: This is a command in the Windows command prompt and PowerShell. It stands for"Change Code Page"
. The code page determines how characters are encoded and displayed in the console window. -
65001
: In this context,65001
represents the code page for UTF-8 encoding. UTF-8 is a variable-width character encoding capable of encoding all possible characters, or code points, in Unicode.- UTF-8: It’s a widely used character encoding that can represent almost all characters from all human languages. It’s especially prevalent on the internet.
-
Changing to UTF-8 (
65001
): When you runchcp 65001
, you’re telling PowerShell to use UTF-8 encoding for character input and output in the console. This can be helpful when working with text data that includes characters from different languages and symbols.For instance, if you’re dealing with files or data that contain non-English characters, setting the code page to UTF-8 ensures that these characters are displayed correctly in the console.
Resetting to Default Code Page
Remember that changing the code page might affect how some console applications behave, so it’s generally a good practice to reset it to the default code page (usually 437
for English) when you’re done using UTF-8.
To reset the code page to the default, you can use the command:
This will switch back to the default code page for your system, which is suitable for English text.
Benefits of Using UTF-8 Encoding in PowerShell
- Multilingual Support: UTF-8 allows PowerShell to handle text in multiple languages, ensuring correct display and processing of characters from different scripts.
- Special Characters: It’s crucial when dealing with special characters like emojis or mathematical symbols that aren’t represented in standard encodings.
- File Handling: When working with text files that include characters from various languages, using UTF-8 ensures accurate file operations.
- Data Processing: If you’re working with data that contains non-English characters, setting the code page to UTF-8 ensures correct handling and processing.
Potential Considerations
- Console Applications: Changing the code page might affect how some console applications behave. Always reset to the default code page (
chcp 437
for English) when done using UTF-8. - Compatibility: Ensure that the programs or scripts you’re running in PowerShell can handle UTF-8 encoding. Older applications may not fully support it.
Practical Use Cases
- Reading Files: When reading text files with non-English characters, using UTF-8 ensures accurate representation.
- Web Scraping: If you’re extracting text from websites that may contain characters from various languages, UTF-8 ensures correct interpretation.
- Script Outputs: If your scripts generate outputs with non-English characters, using UTF-8 ensures they are displayed correctly.
- Interactive PowerShell Sessions: For interactive sessions where you need to input or output text with special characters, UTF-8 encoding is invaluable.
Conclusion
UTF-8 encoding (CHCP 65001
) in PowerShell is a powerful tool for handling multilingual and special characters in the console. It allows for accurate representation and processing of text from various languages and scripts. Understanding when and how to use UTF-8 encoding ensures a seamless experience when working with diverse sets of characters.
Remember to consider the compatibility of programs or scripts with UTF-8 and always revert to the default code page when necessary. By harnessing the power of UTF-8 encoding, you’ll be equipped to handle a wide range of text data with confidence and accuracy in PowerShell.
Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe
Вы тут: Главная → Popular → Нюансы полной локализации Windows с помощью PowerShell
Сегодняшний рассказ продолжает серию публикаций о языковых настройках. Для управления ими в Windows 11 появились новые командлеты: Install-Language и Copy-UserInternationalSettingsToSystem. С ними стала возможна полная локализации системы командлетами PowerShell. Но понадобятся еще пять других
Цель упражнения — полностью локализовать установленную Windows на русский язык для текущего пользователя и всех созданных впоследствии аккаунтов.
Я не призываю переводить английскую ОС с ног до головы на русский язык. Тогда уж проще взять русский дистрибутив. Я показываю тонкости работы языковых командлетов. А вам нужно отталкиваться от практической задачи, выбирая только необходимые составляющие локализации.
В качестве подопытной системы используется английская Windows 11 23H2. ОС установлена с настройками по умолчанию, и никакие языковые параметры не менялись. Если у вас другой язык дистрибутива или добавлены языки, учитывайте это при управлении списком языков. В остальном разницы нет.
Для успеха необходимо подключение к интернету, потому что языковой пакет скачивается с серверов Microsoft. (Добавление языковых пакетов в автономный образ пошагово описано в официальной документации.)
[+] Сегодня в программе
Install-Language
В Windows 11 добавили новый модуль LanguagePackManagement, а затем портировали его в Windows 10. Командлет Install-Language входит в состав этого модуля.
Пример добавления русского языка в английскую систему:
Install-Language ru-RU Language Language Packs Language Features -------- -------------- ----------------- ru-RU LpCab BasicTyping, Handwriting, TextToSpeech, OCR
Название и описание командлета несколько вводят в заблуждение относительно графического интерфейса. На самом деле добавляется не язык, а языковой пакет и сопутствующие компоненты — рукописный ввод, OCR и т.д.
Добавленный командлетом язык не активируется автоматически!
Он появляется лишь в списке языков интерфейса, потому что установили языковой пакет. Однако новый язык не добавляется в список предпочитаемых и следовательно недоступен в качестве языка ввода.
Вы можете полностью применить установленный язык другими командлетами. Оба приема я показывал в блоге. Этот фрагмент кода с помощью Get-WinUserLanguageList добавляет русский язык и как следствие раскладку клавиатуры, но не меняет язык интерфейса.
# Добавить русский язык в список предпочитаемых # Как следствие добавляется русский метод ввода # https://www.outsidethebox.ms/20484/#_Toc501 $List = Get-WinUserLanguageList $List.Add("ru-RU") Set-WinUserLanguageList $List -Force Get-WinUserLanguageList
Следующий фрагмент делает то же самое, а также ставит русский на первое место в списке предпочитаемых языков. Плюс командлет Set-WinUILanguageOverride назначает язык интерфейса. Для вступления изменений в силу требуется завершить сеанс.
# Добавить русский язык в список предпочитаемых # Как следствие добавляется русский метод ввода $List = Get-WinUserLanguageList $List.Add("ru-RU") # Сделать русский язык первым в списке предпочитаемых # https://www.outsidethebox.ms/19024/#lang Set-WinUserLanguageList $($list[1], $list[0]) -Force Get-WinUserLanguageList # Задать русский язык в качестве языка интерфейса Set-WinUILanguageOverride ru-RU
При использовании Install-Language можно избежать установки дополнительных компонентов параметром -ExcludeFeatures
. Однако он блокирует все компоненты сразу, а тонкой настройки не предусмотрено. Это решается с помощью командлетов для управления компонентами по требованию. Ниже пример получения сведений о компонентах и удаления OCR после установки языка посредством Install-Language.
# Состояние русских языковых компонентов после установки русского языка Get-WindowsCapability -Online | Where-Object {$_.Name -like '*lang*ru-RU*'} Name : Language.Basic~~~ru-RU~0.0.1.0 State : Installed Name : Language.Handwriting~~~ru-RU~0.0.1.0 State : Installed Name : Language.OCR~~~ru-RU~0.0.1.0 State : Installed Name : Language.TextToSpeech~~~ru-RU~0.0.1.0 State : Installed # Удаление компонентa OCR Remove-WindowsCapability -Name "Language.OCR~~~ru-RU~0.0.1.0" -Online
Кроме того, у командлета есть параметр -CopyToSettings
. Добавляя язык, можно установить его в качестве языка для неюникодных программ, а также языком интерфейса, ввода и форматов на экране приветствия и в настройки всех новых учетных записей.
Однако обратите внимание, что метод ввода и форматы у новых аккаунтов остались английскими. При том что на экране приветствия все соответствует описанию. Добавление языка до запуска Install-Language ничего не изменило. Что ж, мы пойдем другим путем, чуть ниже.
Наконец, после работы Install-Language вверху страницы языковых параметров появляется уведомление, что некоторыми настройками управляет организация (см. первую картинку в статье). Я не нашел ни сконфигурированных политик, ни заблокированных [языковых] настроек, с которыми такие сообщения обычно идут рука об руку. Похоже на ошибочное сообщение.
Uninstall-Language
Для удаления языка в том же модуле LanguagePackManagement предусмотрен командлет Uninstall-Language. У него свои нюансы.
- Удаление языкового пакета и дополнительных компонентов выполняется асинхронно — в фоне и не моментально, а вступает в силу после перезагрузки.
- Языковой пакет не удалится, если его язык задан для интерфейса ОС. Допустим у вас выбран русский язык. Тогда удалятся только языковые компоненты, а языковой пакет останется. Поэтому сначала следует явно переопределить язык интерфейса командлетом Set-WinUILanguageOverride.
Set-WinUILanguageOverride en-US Uninstall-Language ru-RU
- Удаление не затрагивает язык и метод ввода, добавленные вручную или командлетом Get-WinUserLanguageList.
Copy-UserInternationalSettingsToSystem
Командлет Copy-UserInternationalSettingsToSystem добавили в модуль International. Спасибо Alexander Starostin за наводку. Командлет копирует пользовательские настройки на экран входа / системные учетные записи и/или в настройки всех новых учетных записей.
В этом примере языковые параметры копируются всюду:
Copy-UserInternationalSettingsToSystem -WelcomeScreen $True -NewUser $True
Здесь тонкостей поменьше.
- У Install-Language регион почему-то исключен из копирования. А здесь копируется полный набор параметров. Кстати,
GeoID
фигурирует в блоге в контексте блокировки Office 365 в РФ и РБ. - Копирование языка на экран входа определяет не только язык интерфейса там, но и дефолтную раскладку для ввода пароля. Ее можно задать командлетом Set-WinDefaultInputMethodOverride везде, в том числе на экране входа:
Set-WinDefaultInputMethodOverride -InputTip "0409:00000409" #en-US
Тонкой же настройке я посвятил статью: Как грамотно настроить язык ввода на экране входа в Windows.
- Наконец, командлет доступен только в Windows 11. Его не портировали ни в Windows 10, ни в Windows Server 2022.
Скрипт для полной локализации ОС
Помимо рассмотренных выше командлетов в скрипт вошли также:
- Set-WinHomeLocation — задает регион
- Set-WinSystemLocale — указывает кодовую страницу
- Set-WinDefaultInputMethodOverride (необязательно) — переопределяет метод ввода по умолчанию, на случай если вы при полной локализации все-таки предпочитаете дефолтную английскую раскладку
Код ниже:
- устанавливает русский язык со всеми компонентами
- добавляет русский язык в список языков и методов ввода
- ставит русский на первое место в списке предпочитаемых (при условии, что он на втором из двух)
- задает русский в качестве языка интерфейса
- задает регион РФ
- копирует вышеперечисленные языковые настройки на экран приветствия и в новые учетные записи
- задает русскую кодовую страницу
Скрипт:
# Полная локализация Windows: https://www.outsidethebox.ms/22149/ Install-Language ru-RU Set-WinUILanguageOverride ru-RU $List = Get-WinUserLanguageList $List.Add("ru-RU") Set-WinUserLanguageList $($list[1], $list[0]) -Force Set-WinHomeLocation -GeoId 203 # https://go.microsoft.com/fwlink/?LinkID=242308 Set-WinSystemLocale ru-RU Copy-UserInternationalSettingsToSystem -WelcomeScreen $True -NewUser $True # Бонус: переопределить дефолтный метод ввода на английский # Set-WinDefaultInputMethodOverride -InputTip "0409:00000409"
Результат:
Заключение
Новые командлеты навели два недостающих мостика к локализации всех компонентов установленной системы. Конечно, с непривычки трудно ориентироваться в разнообразии языковых командлетов. Но фактически разработчики стараются делать отдельный командлет для каждой настройки в графическом интерфейсе. Зная это, проще находить подходящий командлет для решения конкретной задачи.