Windows 11 バージョン 24H2 で netsh.exe の出力を PowerShell の変数に代入すると、非 ASCII 文字が文字化けする事象について

Last Update: feedback 共有

本記事はマイクロソフト社員によって公開されております。

いつも弊社製品をご利用いただきまして誠にありがとうございます。
日本マイクロソフト Windows サポートチームです。

このブログでは、Windows 11 バージョン 24H2 で PowerShell で netsh コマンド (netsh.exe) を実行し、その結果を変数に代入すると日本語の文字など非 ASCII 文字が文字化けする問題とその解決策について紹介します。

事象

以下のように、PowerShell で netsh コマンド (netsh.exe) を実行し、その結果を変数に代入して使用するスクリプトを実装している場合に、Windows 11 バージョン 24H2 では期待される文字列を取得出来ない場合があります。

1
2
3
4
5
6
7
PS C:\> $result = netsh interface ipv4 show interface
PS C:\> $result

Idx Met MTU 迥カ諷・ 蜷榊燕
--- ---------- ---------- ------------ ---------------------------
1 75 4294967295 connected Loopback Pseudo-Interface 1
8 15 1500 connected 繧、繝シ繧オ繝阪ャ繝・

また、パイプを使った処理でも同様に文字化けが発生し、期待した処理が出来ない可能性があります。

1
2
3
4
PS C:\> netsh interface ipv4 show interface | Select-String connected

1 75 4294967295 connected Loopback Pseudo-Interface 1
8 15 1500 connected 繧、繝シ繧オ繝阪ャ繝・

原因

netsh.exe は Windows 11 バージョン 24H2 から、結果を UTF-8 で出力するようになりました。
これにより PowerShell の文字列の取り扱いとミスマッチが発生し、変数の参照時に文字化けが発生します。

回避策

以下 3 点の、いずれかの方法を検討ください。

PowerShell の OutputEncoding を UTF-8 にする

PowerShell の出力エンコーディングを UTF-8 に設定することで、文字化けの発生を防ぐことができます。
ただし、出力に含まれるテンプレート部分 (メッセージや出力のカラム見出し等) が英語になります。

1
2
3
4
5
6
7
8
PS C:\> [System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8
PS C:\> $result = netsh interface ipv4 show interface
PS C:\> $result

Idx Met MTU State Name
--- ---------- ---------- ------------ ---------------------------
1 75 4294967295 connected Loopback Pseudo-Interface 1
8 15 1500 connected イーサネット

プロセス実行時のパラメーターを設定する

netsh.exe を実行する際の各種パラメーターを調整し、文字化けを回避します。
以下のように関数化してご利用いただけます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Get-NetshInterfaces {
try {
$process = New-Object System.Diagnostics.Process
$process.StartInfo.FileName = "C:\Windows\System32\netsh.exe"
$process.StartInfo.Arguments = "interface ipv4 show interface"
$process.StartInfo.UseShellExecute = $false
$process.StartInfo.RedirectStandardOutput = $true
$process.StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
$process.Start() | Out-Null
return $process.StandardOutput.ReadToEnd()
}
finally {
$process.Dispose()
}
}

上記例を実行すると、以下のように出力されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
PS C:\> function Get-NetshInterfaces {
>> try {
>> $process = New-Object System.Diagnostics.Process
>> $process.StartInfo.FileName = "C:\Windows\System32\netsh.exe"
>> $process.StartInfo.Arguments = "interface ipv4 show interface"
>> $process.StartInfo.UseShellExecute = $false
>> $process.StartInfo.RedirectStandardOutput = $true
>> $process.StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
>> $process.Start() | Out-Null
>> return $process.StandardOutput.ReadToEnd()
>> }
>> finally {
>> $process.Dispose()
>> }
>> }
PS C:\>
PS C:\> $result = Get-NetshInterfaces
PS C:\> $result

Idx Met MTU State Name
--- ---------- ---------- ------------ ---------------------------
1 75 4294967295 connected Loopback Pseudo-Interface 1
8 15 1500 connected イーサネット

専用の PowerShell コマンドレット (WMI オブジェクトを参照するコマンドレット) を使用する

目的の設定項目等に WMI クラスが用意されている場合は「WMI オブジェクトを使用する」あるいは「WMI オブジェクトを取得する PowerShell コマンドレットを使用する」ことで、netsh.exe の出力文字列に依存せず処理を行うことが可能です。

1
2
3
4
5
6
7
8
9
PS C:\> $result = Get-NetIpInterface
PS C:\> $result

ifIndex InterfaceAlias AddressFamily NlMtu(Bytes) InterfaceMetric Dhcp ConnectionState PolicyStore
------- -------------- ------------- ------------ --------------- ---- --------------- -----------
8 イーサネット IPv6 1500 15 Enabled Connected ActiveStore
1 Loopback Pseudo-Interface 1 IPv6 4294967295 75 Disabled Connected ActiveStore
8 イーサネット IPv4 1500 15 Enabled Connected ActiveStore
1 Loopback Pseudo-Interface 1 IPv4 4294967295 75 Disabled Connected ActiveStore

更新履歴

2025/03/11 : 本ブログ記事の公開

特記事項

本情報の内容(添付文書、リンク先などを含む)は作成日時点でのものであり、予告なく変更される場合があります。