しばたテックブログ

気分で書いている技術ブログです。

PowerShellからコマンドプロンプトを呼んだ時にちょっとだけ便利にする方法

需要は少ないと思いますが、地味に便利な方法です。

はじめに

突然ですが質問です。
下の画像は何のプログラムを起動していると思いますか?

f:id:stknohg:20160527120253p:plain

正解はPowerShellコンソールから起動したコマンドプロンプト(cmd.exe)でした。

f:id:stknohg:20160527120320p:plain

Process Explorerで見るとこんな感じになっています。

f:id:stknohg:20160527120342p:plain

よく見るとプロンプト左のPSの部分が無いので違いがわかります。

PowerShellからコマンドプロンプトを呼んだ時にちょっと便利にする方法

普段PowerShellのコンソールを使っていて調査などで一時的にコマンドプロンプトを使うことがあると思います。

PowerShellからコマンドプロンプトを起動すると上図の様になり、パッと見で自分が作業してるのがPowerShellコンソールなのかコマンドプロンプトなのか見分けが付かなくなります。

この状態でたまーにコマンドプロンプトなのにPowerShellのコマンドを実行してしまうことがあったりして、まあ大して実害はないのですが地味に嫌な気分になりますw

そんな時は以下のコードをプロファイルに仕込むと少しだけ便利になります。

# PowerShellからコマンドプロンプトを呼んだ際のプロンプト文字列をカスタマイズ
$ENV:PROMPT = "PS(CMD) `$P`$G"

コマンドプロンプトのプロンプトに表示される文字列はPROMPT環境変数で設定することができます。
このため、PowerShellを起動したときにこの環境変数を変更してやるとPowerShellからコマンドプロンプトを呼び出した時だけプロンプトに表示する文字列を変えることができるわけです。

仕込みを入れるとPowerShellからコマンドプロンプトを起動した場合以下の様になり、

f:id:stknohg:20160527121712p:plain

プロンプトの文字列がPS(CMD) ...と変わっていることがわかります。
この表示であれば最初のよりは大分わかりやすいかと思います。

【おまけ】PowerShellをネストして実行した場合にちょっとだけ便利にする方法

本エントリの趣旨からは外れるのですが、私の場合PowerShellからPowerShellをネストして呼び出すこともたまにあるので以下のファンクションを使ってプロンプトにネストの段数を表示させたりもしています。
雑なコードなのでpowersehll.exe → cmd.exe → powershell.exeみたいな呼び出しをした場合は対応できませんが、それなりに使えています。

#
#   現在のPowerShell.exeのネストを取得します。
#   環境によっては Get-WmiObject を Get-CimInstance に変えると良い感じになると思います。
#
function Get-PowerShellNest()
{
    $Nest = 0
    $ParentPID = (Get-WmiObject -Class Win32_Process -Property ParentProcessId -Filter "ProcessId = $PID").ParentProcessId
    $Parent = Get-WmiObject -Class Win32_Process -Property Name, ProcessID, ParentProcessId -Filter "ProcessId = $ParentPID"
    while( $Parent.Name -eq "powershell.exe" )
    {
        $Nest += 1
        $ParentPID = $Parent.ParentProcessId
        $Parent = Get-WmiObject -Class Win32_Process -Property Name, ProcessID, ParentProcessId -Filter "ProcessId = $ParentPID"
    }
    return $Nest
}

#
#   Promptファンクションをオーバーライドします。
#
$Nest = $null
function prompt()
{
    if( $null -eq $Nest )
    {
        $Nest = Get-PowerShellNest
        $NestValue = ""
        if( $Nest -gt 0 )
        {
            $NestValue = "({0})" -F $Nest
        }
        # PowerShellからCmd.exeが呼ばれた際にプロンプト文字列をカスタマイズするための設定
        $ENV:PROMPT = "PS{0}(CMD) `$P`$G" -F $NestValue
    }
    # プロンプト文字列を変更
    return "PS{0} {1}> " -F $NestValue, (Get-Location)
}

実行結果はこんな感じになります。

f:id:stknohg:20160527122744p:plain