※PowerShell Ver3以降であれば、$PSScriptRoot で取れるようになったので以下の記事は過去のお話です。


実行しているスクリプトファイルのディレクトリパスを取得したい時が良くあります。
その配下のファイルやディレクトリにアクセスしたり別スクリプトを呼び出したり。

で、いろいろ調べて試したのですがやっと良い回答が見つかりました。
過去にいろいろ調べたりしましたが…
これ。

Split-Path $script:myInvocation.MyCommand.path -parent

または

Split-Path ( & { $myInvocation.ScriptName } ) -parent

カレントディレクトリーを移すなら

Set-Location (Split-Path $script:myInvocation.MyCommand.path -parent)

または

Set-Location (Split-Path ( & { $myInvocation.ScriptName } ) -parent)

Set-LocationではなくPop-Locationでも○ですね。



以下は過去の色々調査

$myInvocation を使うのは共通しているのですが、問題はどのメンバーを使うか… この3択に行きつくわけですが、値を取得する場所で動作が違うのです…

  • $myInvocation.InvocationName
  • $myInvocation.MyCommand.path
  • $myInvocation.ScriptName

答えは→ こちら ←にありました
ありがとうございます。

 & { $myInvocation.ScriptName }

で使い比べてみると…

サンプルソース

"InvocationName      : " + $myInvocation.InvocationName
"MyCommand.path      : " + $myInvocation.MyCommand.path 
"ScriptName          : " + $myInvocation.ScriptName
"& ScriptName        : " + ( & { $myInvocation.ScriptName } )
""
function func()
{
    "func InvocationName : " + $myInvocation.InvocationName
    "func MyCommand.path : " + $myInvocation.MyCommand.path 
    "func ScriptName     : " + $myInvocation.ScriptName
    "func & ScriptName   : " + ( & { $myInvocation.ScriptName } )
}

func

結果

スクリプト直下、関数内。どちらでも大丈夫なのは4つ目だけ。どれを使うべきかは決まる感じですね。 ちなみに他のスクリプトファイルを呼び出した場合(スクリプト呼び出し、関数呼び出しいずれも)も呼び出されたスクリプトファイルパスが返ります。

InvocationName      : C:\test\test.ps1  # OK
MyCommand.path      : C:\test\test.ps1  # OK
ScriptName          :                   # 取れない
& ScriptName        : C:\test\test.ps1  # OK

func InvocationName : func              # 関数名
func MyCommand.path :                   # 取れない
func ScriptName     : C:\test\test.ps1  # OK
func & ScriptName   : C:\test\test.ps1  # OK

とういわけで、スクリプトのディレクトリを取るためには

Split-Path ( & { $myInvocation.ScriptName } ) -parent

となりました。 Push-Location、Pop-Location とあわせて使えばバッチリですね。 めでたしめでたし。

タグ:

PowerShell
最終更新:2017年03月29日 16:15