PowerShell スクリプト (.ps1) ファイルが配置されているフォルダのパスを格納した $PSScriptRoot 自動変数を用いることで、外部のバッチなどからその .ps1 ファイルが呼び出す際の相対パスによるエラーの発生を防ぐスクリプトと実行の例を紹介します。

※ Windows PowerShell PSVersion 5.1.19041.6093 を使用します。
サンプル a.ps1 スクリプトの説明
PowerShell (.ps1) ファイル a.ps1 は、同じフォルダにある、相対パスで指定した 1.txt と $PSScriptRoot による絶対パスで指定した 2.txt を C:\temp フォルダにコピーするスクリプトです。
この a.ps1 ファイルを、同じフォルダの run.bat から呼び出した場合と、違う場所(例では .\sub\)の run_from_sub.bat から呼び出した場合で、相対パス・絶対パスでコピーが正しく行われるかを確認します。

以下は a.ps1 スクリプトファイルの中身です。
Copy-Item コマンドレットにより、 -Path で指定したファイルを -Destination で指定したフォルダにコピーします。
# 相対パス指定
Copy-Item -Path ".\1.txt" -Destination "C:\temp\"
# スクリプトの場所基準
Copy-Item -Path "$PSScriptRoot\2.txt" -Destination "C:\temp\"
項目をある場所から別の場所にコピーします。
-Path
文字列配列として、コピーする項目へのパスを指定します。 ワイルドカード文字を使用できます。-Destination
Copy-Item (Microsoft.PowerShell.Management) – PowerShell | Microsoft Learn
新しい場所へのパスを指定します。 既定値は、現在のディレクトリです。
コピーする項目の名前を変更するには、 Destination パラメーターの値に新しい名前を指定します。
2つ目の Copy-Item では、コピー元ファイルのパスを $PSScriptRoot 自動変数で、このスクリプトファイルのあるフォルダを絶対パスで指定しています。
$PSScriptRoot
実行中のスクリプトの親ディレクトリの完全なパスが含まれています。
PowerShell 2.0 では、この変数はスクリプト モジュール (
about_Automatic_Variables – PowerShell | Microsoft Learn #$PSScriptRoot.psm1
) でのみ有効です。 PowerShell 3.0 以降では、すべてのスクリプトで有効です。
.ps1 と起動する .bat が同じフォルダの場合
同じフォルダにある run.bat をダブルクリックすることで、 a.ps1 スクリプトファイルを実行します。
@echo off
powershell -ExecutionPolicy Bypass -File "%~dp0a.ps1"
pause
a.ps1 の前の %~dp0 は、カレントディレクトリを指します。
「%~dp0」は、現在自分がいるフォルダ(カレントディレクトリ)のパスを取得します。
バッチファイルで「cd /d %~dp0」コマンドでカレントディレクトリを変更する | 技術的特異点
実行結果
実行すると、以下のメッセージが表示されたコマンドプロンプトが表示されます。
続行するには何かキーを押してください . . .
相対パスで指定した 1.txt も $PSScriptRoot 自動変数による絶対パスで指定した 2.txt も C:\temp フォルダにコピーできました。

コピー先フォルダがない場合のエラー
コピー先フォルダ C:\temp が存在しない場合は、 Copy-Item コマンドレットが失敗して、以下のエラーメッセージがバッチファイルを起動して表示されたコマンドプロンプトに表示されます。
このときは、コピーはどちらのファイルも行われません。
Copy-Item : ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
発生場所 G:\Dev\PowerShell\Study-PSScriptRoot\a.ps1:2 文字:1
+ Copy-Item -Path ".\1.txt" -Destination "C:\temp\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
Copy-Item : ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。
発生場所 G:\Dev\PowerShell\Study-PSScriptRoot\a.ps1:5 文字:1
+ Copy-Item -Path "$PSScriptRoot\2.txt" -Destination "C:\temp\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], IOException
+ FullyQualifiedErrorId : System.IO.IOException,Microsoft.PowerShell.Commands.CopyItemCommand
続行するには何かキーを押してください . . .
.ps1 と起動する .bat が異なるフォルダの場合
異なるフォルダ(例では .\sub\)にある run_from_sub.bat をダブルクリックすることで、別のフォルダにある a.ps1 スクリプトファイルを実行します。
以下は、run_from_sub.bat の内容です。
バッチファイルのカレントディレクトリを指す %~dp0 のあとに ..\ を加えて上位の a.ps1 を実行します。
@echo off
powershell -ExecutionPolicy Bypass -File "%~dp0..\a.ps1"
pause
.ps1 と異なるフォルダから実行した際の相対パスの不具合
a.ps1 ファイルと異なる場所から実行すると、カレントディレクトリが .ps1 のあるフォルダと異なるため、 a.ps1 のスクリプト内の相対パスで指定したファイルの位置が a.ps1 のあるフォルダと異なるため、コピーに失敗します。
$PSScriptRoot 自動変数による絶対パスで指定した 2.txt はコピーが成功しています。

Copy-Item : パス 'G:\Dev\PowerShell\Study-PSScriptRoot\sub\1.txt' が存在しないため検出できません。
発生場所 G:\Dev\PowerShell\Study-PSScriptRoot\a.ps1:2 文字:1
+ Copy-Item -Path ".\1.txt" -Destination "C:\temp\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (G:\Dev\PowerShe...tRoot\sub\1.txt:String) [Copy-Item], ItemNotFoundExce
ption
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
続行するには何かキーを押してください . . .
相対パスだと呼び出されるディレクトリによって結果が変わる
以上のことから、相対パスを用いる .ps1 スクリプトは、呼び出されるディレクトリ(カレントディレクトリ)によって結果が異なることがわかりました。
$PSScriptRoot 自動変数による絶対パスは、カレントディレクトリの影響を受けないため、より安全に動作することがわかりました。
まとめ
今回は、PowerShell スクリプト (.ps1) ファイルが配置されているフォルダのパスを格納した $PSScriptRoot 自動変数を用いることで、外部のバッチなどからその .ps1 ファイルが呼び出す際の相対パスによるエラーの発生を防ぐスクリプトと実行の例を紹介しました。
参照サイト Thank You!
- PowerShell とは – PowerShell | Microsoft Learn
- about_Automatic_Variables – PowerShell | Microsoft Learn #$PSScriptRoot
- Copy-Item (Microsoft.PowerShell.Management) – PowerShell | Microsoft Learn
- バッチファイルで「cd /d %~dp0」コマンドでカレントディレクトリを変更する | 技術的特異点
記事一覧 → Compota-Soft-Press
コメント