【元記事をASCII.jpで読む】

そもそもPowerShellプロファイルとは

 PowerShellやWindows PowerShell(以下、PowerShellと総称)で、いつも同じオブジェクトを使うことがある。こうしたとき、Profileプロファイル)と呼ばれる機能を使うことで、起動時に変数や関数などを登録できる。

 Profileは、テキスト形式のスクリプトファイルであり、起動時に読み込まれて、その内容に従って、変数や関数、エイリアスなどの定義をする。

 プロファイルには、ユーザー、ホストにより4種類の組み合わせがある。

 ユーザーの種別は、すべてのユーザー用と現在のユーザー用の2つがある。またホストは、すべてのホスト用と現在のホスト用の2つがある。ホストの種別は、リモートシェル操作をするときに利用される。ローカルホストでは「すべてのホスト」と「現在のホスト」用が順に適用される。

 リモートシェルの場合には、リモート側ホストにある「現在のホスト」用のプロファイルが使われる。まずは「すべて」のユーザー、「すべて」のホストのプロファイルが適用され、表の上から下の順に適用されていく。

 企業などの組織内での利用では、これらを使い分ける必要があるが、個人利用では、「現在」のユーザー用、「現在」のホスト用だけを使えばよい。プロファイルのパスは、変数$PROFILEに登録されている。これは、PSCustomObjectであり、以下の表のような方法ですべてのプロファイルのパスを取得できる。

 このとき、現在のユーザー、現在のホストの場合だけ、プロパティ名を省略して「$PROFILE」とすることができる。このため、このプロファイルを編集するような場合、

notepad.exe $PROFILE

などと指定することが可能だ。なお、プロファイルは標準状態ではファイルが作られていない。もしプロファイル内で日本語を使う場合、日本語版Windows上のWindows PowerShellではシフトJIS、PowerShellではUTF-8エンコードにする必要がある。日本語がコメントだけであれば、どちらもUTF-8エンコードでかまわないが、PowerShellの文字列として扱う場合には、ファイルのエンコードに注意する必要がある。

 正しいパスにプロファイル(のファイル)が作成されると、PowerShellは起動時にこれを読み込む。ただし、「-noprofile」オプションが指定されているとプロファイルの読み込みはされない。

 プロファイルから実行されるコマンドは、通常のスクリプトコマンドと違い、PowerShell自体の状態を変更する。このため、プロファイルを再読込したいときには、ピリオド1文字の「ドットソーシング演算子」(Dot Sourcing operator)を使い、以下のように実行する。

. $PROFILE

 先頭にあるピリオドと「$PROFILE」の間にはスペースが必要である。これは、Unixのシェルにあるsourceコマンドが由来である。かつては、このコマンドは、ピリオド1文字のshの組み込みコマンドだった。WSLなどで使われているbashでは、sourceという別名がある。

 PowerShellでは、スクリプトファイルは、子プロセスで実行されるため、実行が終了すると、実行環境に対する変更がすべて破棄されてしまう。しかし、ドットソーシング演算子を使うと、スクリプトファイルは、子プロセスではなく現在のプロセス内で実行される。これにより、変数やエイリアス、カレントディレクトリなどのコマンドの効果がスクリプトの終了後にも残った状態となる。

実際のプロファイルでの設定方法など

 プロファイルでは、比較的よく使う定数などを変数にあらかじめ設定しておきたいことがある。このような場合、以下のように記述する。

remove-variable -ErrorAction SilentlyContinue -Force -Name <変数名>
Set-Variable -Option ReadOnly -Name <変数名> -Description '<変数の説明>' -Value <値>

 最初のremove-variableは、ドットソースでの読み込みを考慮したもの。ReadOnlyに設定した変数を再度設定しようとするとエラーになるので、先に削除しておく。未定義のときremove-variableがエラーになるが、「-ErrorAction SilentlyContinue」オプションが指定してあるため、エラーメッセージを表示せずに実行が継続する。

 プロンプト文字列を変更したいという用途もある。この場合、Prompt関数を記述する。注意点は、関数なので必ず何かを返すようにする。PowerShellはPrompt関数の戻り値が$nullだと、組み込みの文字列「PS>」を出力する。

 上のリストでは、Write-Hostでプロンプトを色付きで表示させている。しかし、Write-Hostはコンソールに直接書き込み、値を返さないので、最後の「" ";」でプロンプトの最後にスペースを出力させている。

 プロファイルをWindows PowerShellとPowerShellで共有したいとき、以下の方法でそれぞれを区別できる。

if($PSVersionTable.PSVersion.Major -eq 5) {
    "Windows PowerShell";
} else {
    "PowerShell";
}

 PowerShellが起動されたときのオプションを得るには、以下のようにして、自分のプロセスIDを探し、コマンドラインを得る。PowerShellの実行コマンドパス(スペースやハイフンなどが含まれる可能性がある)を""に置換したのち、スペースを区切り文字として分割(split演算子)する。

$myProcess= Get-CimInstance Win32_Process -Filter "ProcessID = $PID";
$myArg=($myProcess.CommandLine -replace ($myProcess.Path -replace "\\","\\"),"") -split " " ;

 PowerShellでは、関数の一覧は「Get-ChildItem -path function:」でできるが、面倒なので短い名前の関数を作っておく。筆者は、BASICから使い始めたので「LIST」という名前にしている。LISTは引数無しで、ユーザー登録関数の一覧を、関数名をつけるとその定義を表示する。

 なお、コンソールの背景色は、コンソールプログラム(conhost.exeやWindows Terminal)側で設定する。また、デフォルトの文字色に関してはPSReadLineで色分けを管理しているので、PSReadLine側で設定する。こちらについては別途記事にしたい。

 PowerShellプロファイルを使うことで、よく使うオブジェクトなどをあらかじめ変数に定義しておける。なお、関数や変数の定義はできるだけ最低限にして、絶対に忘れないような名前にしておく。

 プロファイルは、起動時に読み込まれるため、長ければ長いほど起動時間がかかる。使いもしない関数の定義に毎回時間を取られるのは無駄である。

WindowsのPowerShellのプロファイルを設定する