[PowerShell]文字コードと管理者権限を判定しウィンドウタイトルを変更
概要
日本語のWindows OSでPowerShellを使用する場合、文字コードの規定値が複雑で実行するとコマンドによっては文字化けしてしまう。なんてことがよくあります。
現状の設定値が把握しやすいようウィンドウタイトルに“PowerShellの各文字コードの設定”と“管理者として実行しているかの情報”を追加できるFunctionを作成してみました。
この記事のターゲット
- Windows ユーザーの方
- PowerShell ユーザーの方
- PowerShell の文字コードをウィンドウのタイトルで把握したい方
環境
OSのバージョン
Windows 10 Pro環境
PS C:\Users\"ユーザー名"> Get-CimInstance CIM_OperatingSystem
SystemDirectory Organization BuildNumber RegisteredUser SerialNumber Version
--------------- ------------ ----------- -------------- ------------ -------
C:\WINDOWS\system32 19045 XXXXX 00000-00000-00000-AAAAA 10.0.19045
^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^
↑マスク ↑マスク
PS C:\Users\"ユーザー名">
-
参考記事:PowerShell Core ではGet-WmiObjectからGet-CimInstanceに変更
https://www.vwnet.jp/windows/PowerShell/2021061301/PowerShellCore6xWMI.htm -
参考記事:Win32_OperatingSystem クラスは CIM_OperatingSystem に変更
https://learn.microsoft.com/ja-jp/windows/win32/cimwin32prov/cim-operatingsystem
PowerShell
PowerShell 5.x(PSEdition: Desktop)
PS C:\Users\"ユーザー名"> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.3930
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.3930
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\Users\"ユーザー名">
PowerShell 7.x(PSEdition: Core)
PS C:\Users\"ユーザー名"> $PSVersionTable
Name Value
---- -----
PSVersion 7.3.10
PSEdition Core
GitCommitId 7.3.10
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PS C:\Users\"ユーザー名">
Windows ターミナル(Microsoft Store版)
PS C:\Users\"ユーザー名"> winget list --id '9N0DX20HK701'
名前 ID バージョン ソース
----------------------------------------------------
Windows ターミナル 9N0DX20HK701 1.18.3181.0 msstore
PS C:\Users\"ユーザー名">
対応方法
作成したFunction
さっそく作成したPowerShellのコードを紹介します。コードの説明は後述します。
# 管理者として実行しているか確認(Trueの場合、“管理者として実行”していると判断)
Function Test-IsAdmin {
$win_id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$win_principal = new-object System.Security.Principal.WindowsPrincipal($win_id)
$admin_permission = [System.Security.Principal.WindowsBuiltInRole]::Administrator
return $win_principal.IsInRole($admin_permission)
}
# 現在、設定している文字コードを取得
Function GetPsCharcode {
[System.String[]]$ps_charcode = @()
$ps_charcode = @(
# コンソールに出力する文字コードの規定値
($PSDefaultParameterValues['*:Encoding']),
# PowerShellから外部プログラムに渡す文字エンコードの設定
($global:OutputEncoding).WebName,
# PowerShellのコンソールに出力する文字エンコードの設定
([console]::OutputEncoding).WebName
)
return $ps_charcode
}
# PowerShellウィンドウのタイトル変更
Function ChangeWindowTitle {
# 区切り文字の設定
[System.String]$pos1 = '|'
[System.String]$pos2 = ';'
# 現在のタイトルを取得
[System.String]$title = $Host.UI.RawUI.WindowTitle
[System.String]$base_title = $title
# すでにこのFunctionでタイトル変更している場合、一番左にある元のタイトル名のみ抽出
[System.String[]]$title_array = $title.Split($pos1)
if ($title_array.Length -ne 0) {
$base_title = ($title_array[0]).TrimEnd()
}
# 現在の文字コードを取得
[System.String[]]$ps_charcode = GetPsCharcode
# 管理者として実行しているかにより設定するタイトル名を分岐
[System.String]$change_title = $base_title
if (Test-IsAdmin) {
# PowerShellを管理者として実行している場合
$change_title = $base_title + " $pos1 " +
"DefaultParameter='$($ps_charcode[0])'" + " $pos2 " +
"GlobalEncoding='$($ps_charcode[1])'" + " $pos2 " +
"ConsoleEncoding='$($ps_charcode[2])'" + " $pos2 " +
"#Administrator"
}
else {
# していない場合
$change_title = $base_title + " $pos1 " +
"DefaultParameter='$($ps_charcode[0])'" + " $pos2 " +
"GlobalEncoding='$($ps_charcode[1])'" + " $pos2 " +
"ConsoleEncoding='$($ps_charcode[2])'" + " $pos2 " +
"#Not_Administrator"
}
$Host.UI.RawUI.WindowTitle = $change_title
# 完了メッセージ
Write-Host 'タイトルに“文字コード”と“管理者権限の有無”の情報を追加しました。' -ForegroundColor Cyan
}
コードの説明(作成したFunctionの流れ)
-
現在のタイトル名を取得
- (すでにこのFunctiondでタイトル変更済みの場合)元のタイトル名のみを抽出
-
文字コードを取得
-
$PSDefaultParameterValues['*:Encoding']
コンソールに出力する文字コードの規定値。
仮にこの設定値をutf8
にした場合、Out-File
コマンドレットのパラメーターEncoding
の規定値がutf8
となる。 -
$global:OutputEncoding
PowerShellから外部プログラムに渡す文字エンコードの設定。
PowerShellのコマンドからPythonなどの外部プログラムで文字列を表示する際に使用される。 -
[console]::OutputEncoding
PowerShellのコンソールに出力する文字エンコードの設定。
PowerShellのCLIウィンドウやWindows ターミナルなどで文字列を表示する際に使用される。
-
-
PowerShellを管理者として実行しているか確認
-
取得した情報を使用しタイトルを変更する
- 管理者として実行している場合
元のタイトル + 区切り文字1(|
) + 文字コード1(DefaultParameter='xxx'
) + 区切り文字2(;
) + 文字コード2(GlobalEncoding='xxx'
) + 区切り文字2(;
) + 文字コード3(ConsoleEncoding='xxx'
) + 区切り文字2(;
) +#Administrator
- 管理者として実行していない場合
元のタイトル + 区切り文字1(|
) + 文字コード1(DefaultParameter='xxx'
) + 区切り文字2(;
) + 文字コード2(GlobalEncoding='xxx'
) + 区切り文字2(;
) + 文字コード3(ConsoleEncoding='xxx'
) + 区切り文字2(;
) +#Not_Administrator
- 管理者として実行している場合
PowerShellバージョン毎の文字コードの規定値
PowerShell 5.x の場合
確認方法 - PowerShell 5.x
-
PowerShell 5.x のコンソールで確認
名前を指定して実行で“powershell”
(⊞スタートメニュー → Windows PowerShell フォルダー → Windows PowerShell)実行ファイルの場所:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
文字コードの規定値 - PowerShell 5.x
-
$PSDefaultParameterValues['*:Encoding']
`` ← 空文字で設定なし
※ 設定がないので各コマンドレットの規定値が設定される。
こちらの公式サイトによるとPowerShellの文字エンコードの規定値はutf8NoBOM
との事。 -
$global:OutputEncoding
us-ascii
-
[console]::OutputEncoding
shift_jis
PowerShell 7.x の場合
確認方法 - PowerShell 7.x
-
PowerShell 7.x のコンソールで確認
名前を指定して実行で“pwsh”
[⊞スタートメニュー → PowerShell フォルダー → PowerShell 7 (x64)]実行ファイルの場所:
C:\Program Files\PowerShell\7\pwsh.exe
-
Windows ターミナルで確認
名前を指定して実行で“wt”
(⊞スタートメニュー → ターミナル)実行ファイルの場所:
C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.18.3181.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
文字コードの規定値 - PowerShell 7.x
PowerShell 7.x のコンソール と Windows ターミナル 2つで確認すると同じ結果だった為、
結果をまとめて表示。
-
$PSDefaultParameterValues['*:Encoding']
`` ← 空文字で設定なし
※ 設定がないので各コマンドレットの規定値が設定される。
こちらの公式サイトによるとPowerShellの文字エンコードの規定値はutf8NoBOM
との事。 -
$global:OutputEncoding
utf-8
-
[console]::OutputEncoding
shift_jis
実際にタイトル変更のFunction実行してみる
Function実行 - PowerShell 5.x コンソール
管理者として実行した場合 - PowerShell 5.x コンソール
- タイトル変更前
- タイトル変更後
通常起動した場合 - PowerShell 5.x コンソール
通常起動した場合、つまりは管理者として実行していないパターンでFunctionを実行。
- タイトル変更前
- タイトル変更後
Function実行 - PowerShell 7.x コンソール
管理者として実行した場合 - PowerShell 7.x コンソール
-
タイトル変更前
-
タイトル変更後
タイトル名が長く見切れてしまったので、コマンドでタイトル名を取得してみました。
見切れたウィンドウのタイトル名を取得PS C:\Users\"ユーザー名"> Get-Process | Where-Object {$_.MainWindowTitle} | Select-Object Name, MainWindowTitle | Format-Table -AutoSize -Wrap Name MainWindowTitle ---- --------------- pwsh Administrator: C:\Program Files\PowerShell\7\pwsh.exe | DefaultParameter='' ; GlobalEncodi ng='utf-8' ; ConsoleEncoding='shift_jis' ; #Administrator PS C:\Users\"ユーザー名">
通常起動した場合 - PowerShell 7.x コンソール
通常起動した場合、つまりは管理者として実行していないパターンでFunctionを実行。
-
タイトル変更前
-
タイトル変更後
Windows ターミナル
管理者として実行した場合 - Windows ターミナル
- タイトル変更前
- タイトル変更後
通常起動した場合 - Windows ターミナル
通常起動した場合、つまりは管理者として実行していないパターンでFunctionを実行。
-
タイトル変更前
-
タイトル変更後
Windows ターミナルでウィンドウタイトルを表示する方法
初期状態のWindows ターミナルでは ウィンドウタイトルがなくタブのタイトルに反映されます。
タブのタイトルだけだと確実に見切れてしまうので、Windows ターミナルのウィンドウタイトルを表示する設定を行いました。
- Windows ターミナルの設定を開く
- 設定の項目「外観」を選択する
- “タイトル バーを非表示にする”をオンからオフに変更
- オン状態
- オフ状態
- オン状態
- 保存ボタンを押す
- Windows ターミナルを再起動
Windows ターミナル再起動後、ウィンドウタイトルが表示されました。
ウィンドウタイトルが表示された後、タイトル名変更のFunctionを実行し見切れず表示されている事を確認。
参考情報
現在のセッションが管理者権限で実行しているか確認する方法
まとめ
-
PowerShell CLIでコマンドをガシガシ実行する方は、タイトルに文字コードが見えると便利かも
ただ、タイトル名を変更後に文字コードを設定しなおした場合、
その都度、Functionを実行しないといけないのは不便。もう少し改良の余地があると思います。 -
このFunctionをProfileに設定しPowerShell起動時に実行すると再実行も簡単にできて便利かも
関連記事
Discussion