Powershellをカスタマイズしてイケイケにする方法

皆さん、Powershell使ってますか？今時cmd.exeをメインで使っている人間はいないと思いますけれど、minttyあたりは使っている人がいるかもしれませんね。
もし、あなたがPowershellを使っていないとしたら、それはとてももったいないことです。Powershellは、Windowsでできることなら大抵のことができます。

## Powershellのカスタマイズを始めよう
では、早速Powershellをカスタマイズしていきましょう。まず、Powershellを開いてください。そして、次のコマンドを打ちます。

```powershell
Get-Item $PROFILE
```

このコマンドを打って、エラーが出た人は次のコマンドを続けて打ってください。

```powershell
New-Item $PROFILE
```

さて、これで準備は完了です。

`$PROFILE`という変数は、現在のホストにおける現在のユーザーのPowershellの初期化スクリプトのパスを示しています。つまり、このパスに好きなPowershellスクリプトを置いておけば、Powershellを起動するたびに自動で実行されるというわけ。

## 必要最低限のPowershellのカスタマイズ
まず、Powershellにはイケてない仕様があります。それは、現在のディレクトリ(カレントディレクトリ)がコマンド検索パスに入っていないというものです。そこで、それをまず変えます。

適当なエディタでPowershellのProfileを開いてください。パスは`echo $PROFILE`で見ることができます。開いたら、先頭に次のコマンドを追記してください。

```powershell
if(-not $env:path.Split(';').Contains('.')){
    $env:path += ";."
}
```

これで、現在のディレクトリがコマンド検索パスに入るようになりました。`$env:`というのは、Windowsの環境変数にアクセスするときにつけるプレフィクスです。`$env:環境変数名`とすると、任意の環境変数を参照できます。

続けて、「管理者権限でコマンドを実行」を簡単にできるようにしたいですね。やりましょう。PowershellのProfileには、関数の定義を書くこともできます。`Run-AsAdmin`関数の定義はこんな感じです。

```powershell
function Run-AsAdmin() {
    if($args.count -eq 0){
        Start-Process -Verb runas powershell
        return
    }
    Start-Process -Verb runas -ArgumentList @('-command', "$($args -join ' ')") powershell
}

Set-Alias -Name:"sudo" -Value:"Run-AsAdmin" -Description:"Start the certain process as administrator" -Option:"None"
```

1回Powershellの起動を挟んでいるのは、Powershellコマンドにも対応するためです。そのあとの`Set-Alias`行は、この関数を`sudo`で呼び出せるようにしているだけですね。

```powershell
sudo Some-Command -arg1 -arg2 value1
```

みたいな感じで呼び出せるようになります。

## プロンプト文字列を変えたい
PowershellはBashやcmd.exeなどのようにプロンプト文字列を変えることができます。どうやって変えるのでしょうか。簡単です。引数をとらない関数、`prompt`を定義すればいいのです。また、これはAliasでもいいので、適当にそれっぽい文字列を表示するプログラムを作って、`Set-Alias`で`prompt`という名前のaliasに設定することでも変えられます。

これは各自自由に変えればいいと思います。一例として、私の設定をおいておきます。

```powershell
function Get-PromptString {
    $suc = $?;
    $stat = "(*^^*)";
    $ui = $Host.UI.RawUI;
    $ui.WindowTitle = "PS " + $pwd.Path.Replace("\", "/");
    $ps = "$";
    
    if(!$suc){
        $stat = " (>_<)";
    }
    
    if(([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltinRole] "Administrator")){
        $ps = "#";
    }
    
    $cwd = $pwd.Path.Replace("\", "/");
    return "$cwd $stat $ps ";
}

Set-Alias -Name:"prompt" -Value:"Get-PromptString" -Description:"" -Option:"None"
```

`prompt`関数は、コマンドの実行が終了した直後に呼ばれます。この性質を利用すると、直前のコマンドの実行結果で表示内容を変えたりすることもできます。

## もっと深く

<span style="color: yellow;background: black"><b>WARNING!!</b></span>
このセクションにはレジストリの編集など、ちょっとヤバめの内容も含まれています。それでもいい方は読み進めてください。
　
　
　
　
　
　
### Powershellの色を変える
Powershell上で使える色は、次にあげる16色です。

```
Black
DarkBlue
DarkGreen
DarkCyan
DarkRed
DarkMagenta
DarkYellow
Gray
DarkGray
Blue
Green
Cyan
Red
Magenta
Yellow
White
```

さて、この色をRGBで表すと、それぞれどんな色なのでしょうか。その答えは、レジストリ上の`HKCU\Console`にあります。このキーの中の`ColorTable00`～`ColorTable15`に対応する色のrgb表現が入っています。私の環境では、こんな感じでした。ここで注意しなければいけないのは、普通のRGBの16進表記とは違い、BGRの順番だということです。

```
ColorTable00 : 0x000000
ColorTable01 : 0x800000
ColorTable02 : 0x008000
ColorTable03 : 0x808000
ColorTable04 : 0x000080
ColorTable05 : 0x800080
ColorTable06 : 0x008080
ColorTable07 : 0xc0c0c0
ColorTable08 : 0x808080
ColorTable09 : 0xff0000
ColorTable10 : 0x00ff00
ColorTable11 : 0xffff00
ColorTable12 : 0x0000ff
ColorTable13 : 0xff00ff
ColorTable14 : 0x00ffff
ColorTable15 : 0xffffff
```

さて、実際に色を変えてみましょう。まず、次のコマンドを打ってください。このセクションは、すべてこのコマンドを打った後に実行しているものとして話を進めます。

```powershell
cd "HKCU:/Console/$((Get-Command powershell).Source.Replace('C:\Windows', '%SystemRoot%').Replace('\', '_'))"
```

次に、ここの値を書き換えるコマンドを打っていきたいと思います。
Powershellのコンソールの色を決めているのは、このキーの`ScreenColors`というプロパティです。ここに、16進2桁でカラーテーブルから使う色の番号を入れます。
この値がたとえば`0x56`であれば、背景色にColorTable05の色を、文字色にColorTable06の色を使う、ということです。

この値を、0x06に変えてみます。

```powershell
Set-ItemProperty -Path:. -Name:ScreenColors -Value:0x06
```

1つだけ注意なのですが、これはレジストリを弄っているので、Powershellを再起動しないと変更が反映されません。なので現在のセッションではそのままだと思いますが、Powershellを新しく開くと背景色が黒くなっているはずです。

ところで、先に挙げたカラースキーマは、コンピュータ全体で共有なのでしょうか。いいえ、そんなことはありません。実は、これはコンソールアプリケーションごとにオーバーライドすることができます。

たとえば、次のようにするとBlackの色を0x000000から0x2e1e1eに変えられます。

```powershell
Set-ItemProperty -Path:. -Name:ColorTable00 -Value:0x2e1e1e
```

このようにして、自分の好きなカラースキーマを適用することができます。

## 設定を適用する
さて、最後に設定を適用しましょう。

```powershell
. $PROFILE
```
これで終わりです。お疲れさまでした。