共通のモジュールやスクリプトを参照する必要があるときはいつでも、現在のスクリプトファイルからの相対パスを使用するのが好きです。そうすれば、私のスクリプトは常にライブラリ内の他のスクリプトを見つけることができます。
それでは、現在のスクリプトのディレクトリを決定するための最良の標準的な方法は何ですか?現在、やっています:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
私はモジュール(.psm1)でこの情報を得るために$PSScriptRoot
を使うことができることを知っていますが、それは通常のスクリプト(すなわち.ps1ファイル)では設定されません。
現在のPowerShellスクリプトファイルの場所を取得するための標準的な方法は何ですか?
# This is an automatic variable set to the current file's/module's directory
$PSScriptRoot
PowerShell 2
PowerShell 3より前のバージョンでは、一般的なスクリプトに対してMyInvocation.MyCommand.Definition
プロパティを照会するよりも良い方法はありませんでした。私が持っていた基本的にすべてのPowerShellスクリプトの先頭に次の行がありました。
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
V2モジュールを作成している場合は、$PSScriptRoot
という自動変数を使用できます。
PSから>ヘルプautomatic_variable
$ PSScriptRoot スクリプトモジュールが実行されているディレクトリを含みます。 この変数は、スクリプトがモジュールパスを使って他の リソースにアクセスすることを可能にします。 ____。]
PowerShell 3.0の場合
$PSCommandPath
Contains the full path and file name of the script that is being run.
This variable is valid in all scripts.
機能は次のとおりです。
function Get-ScriptDirectory {
Split-Path -Parent $PSCommandPath
}
たぶん私はここに何かが足りないかもしれません...しかし、あなたが現在の作業ディレクトリが欲しいならあなたはただこれを使うことができます:文字列のための(Get-Location).Path
、またはオブジェクトのためのGet-Location
。
このようなことに言及しているのでない限り、質問をもう一度読んだ後に理解します。
function Get-Script-Directory
{
$scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $scriptInvocation.MyCommand.Path
}
Powershell 3+用
function Get-ScriptDirectory {
if ($psise) {Split-Path $psise.CurrentFile.FullPath}
else {$global:PSScriptRoot}
}
私は自分のプロファイルにこの機能を追加しました。 ISEでF8/Run Selectionも使用できます。
自動変数 $ ExecutionContextを使います。PowerShell2以降で動作します。
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')
$ ExecutionContext Windows PowerShellホストの実行コンテキストを表すEngineIntrinsicsオブジェクトが含まれています。この変数を使用して、コマンドレットで使用可能な実行オブジェクトを見つけることができます。
すでに投稿されている回答と非常によく似ていますが、配管はよりPSに似ているようです。
$PSCommandPath | Split-Path -Parent
スクリプト名とその実行元を知る必要がありました。
MyInvocation構造体の先頭に "$ global:"を付けると、メインスクリプトとインポートされたPSM1ライブラリファイルのメイン行の両方から呼び出されたときに、フルパスとスクリプト名が返されます。インポートされたライブラリの関数内からも機能します。
いろんなことをやっていたので、私は$ global:MyInvocation.InvocationNameを使うことにしました。 CMDの起動、Run With Powershell、およびISEと確実に連携します。ローカルとUNCの両方の起動で正しいパスが返されます。
受け入れられた答えを取り、それを頑健な機能に変える何かを開発するためにしばらく時間がかかりました。
他人についてはわかりませんが、私はPowerShellバージョン2と3の両方のマシンがある環境で作業しているので、両方を処理する必要がありました。次の関数は適切なフォールバックを提供します。
Function Get-PSScriptRoot
{
$ScriptRoot = ""
Try
{
$ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
}
Catch
{
$ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
}
Write-Output $ScriptRoot
}
また、Michael Sorensが彼の blog で概説したように、関数が親のスコープではなくScriptスコープを参照することも意味します。
私はいつもPowershellとUSEに同じように働くこの小さな断片を使います:
# set active path to script-location:
$path = $MyInvocation.MyCommand.Path
if (!$path) {$path = $psISE.CurrentFile.Fullpath}
if ( $path) {$path = split-path $path -Parent}
set-location $path
他の方法のいずれかが失敗した場合、split-path -parent $psISE.CurrentFile.Fullpath
を検討することもできます。特に、ファイルを実行して一連の関数をロードしてからISEシェルでこれらの関数を実行した場合(または実行選択した場合)、上記のGet-Script-Directory
関数は機能しません。
ここに掲載されている古いソリューションは、PowerShell V5では機能しませんでした。私はこれを思い付きました:
try {
$scriptPath = $PSScriptRoot
if (!$scriptPath)
{
if ($psISE)
{
$scriptPath = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
} else {
Write-Host -ForegroundColor Red "Cannot resolve script file's path"
exit 1
}
}
} catch {
Write-Host -ForegroundColor Red "Caught Exception: $($Error[0].Exception.Message)"
exit 2
}
Write-Host "Path: $scriptPath"
HTH