コマンドの優先順位について
簡単な説明
PowerShell で実行するコマンドを決定する方法について説明します。
長い説明
コマンドの優先順位では、セッションに同じ名前の複数のコマンドが含まれている場合に実行するコマンドを PowerShell で決定する方法について説明します。 セッション内のコマンドは、非表示にしたり、同じ名前のコマンドに置き換えたりできます。 この記事では、非表示のコマンドを実行する方法と、コマンド名の競合を回避する方法について説明します。
コマンドの優先順位
PowerShell セッションに同じ名前のコマンドが複数含まれている場合、PowerShell は次の規則を使用して実行するコマンドを決定します。
コマンドへのパスを指定すると、PowerShell はパスで指定された場所でコマンドを実行します。
たとえば、次のコマンドは、"C:\TechDocs" ディレクトリで FindDocs.ps1 スクリプトを実行します。
C:\TechDocs\FindDocs.ps1
セキュリティ機能として、PowerShell は実行可能 (ネイティブ) コマンド (PowerShell スクリプトを含む) を実行しません。ただし、コマンドが Path 環境変数 $env:path
に一覧表示されているパスに配置されている場合、またはスクリプト ファイルへのパスを指定しない限り実行されません。
現在のディレクトリにあるスクリプトを実行するには、完全なパスを指定するか、現在のディレクトリを表すドット .\
を入力します。
たとえば、現在のディレクトリで FindDocs.ps1 ファイルを実行するには、次のように入力します。
.\FindDocs.ps1
実行中のワイルドカードの使用
コマンドの実行にはワイルドカードを使用できます。 ワイルドカード文字の使用は globbing とも呼ばれます。
PowerShell は、ワイルドカード一致を持つファイルを、リテラル一致の前に実行します。
たとえば、次のファイルを含むディレクトリを考えてみましょう。
Get-ChildItem C:\temp\test
Directory: C:\temp\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/20/2019 2:29 PM 28 a.ps1
-a---- 5/20/2019 2:29 PM 28 [a1].ps1
両方のスクリプト ファイルの内容は同じです。 $MyInvocation.MyCommand.Path
このコマンドは、呼び出されたスクリプトの名前を表示します。
を実行 [a1].ps1
すると、ファイル a.ps1
がリテラル一致であってもファイル [a1].ps1
が実行されます。
C:\temp\test\[a1].ps1
C:\temp\test\a.ps1
次に、ファイルを a.ps1
削除して、もう一度実行してみましょう。
Remove-Item C:\temp\test\a.ps1
C:\temp\test\[a1].ps1
C:\temp\test\[a1].ps1
リテラル一致がその [a1].ps1
ワイルドカード パターンの唯一のファイル一致であるため、今回実行される出力から確認できます。
PowerShell でワイルドカードを使用する方法の詳細については、「 about_Wildcards」を参照してください。
注意
検索を相対パスに制限するには、スクリプト名の前にパスを付ける .\
必要があります。 これにより、コマンドの検索は、その相対パス内のファイルに制限されます。 このプレフィックスがないと、他の PowerShell 構文が競合する可能性があり、ファイルが見つかるという保証はほとんどありません。
パスを指定しない場合、PowerShell はコマンドの実行時に次の優先順位を使用します。
- エイリアス
- 機能
- コマンドレット
- ネイティブ Windows コマンド
そのため、「help」と入力すると、PowerShell は最初に という名前 help
のエイリアスを探し、次に という名前 Help
の関数を探し、最後に というコマンドレット Help
を探します。 見つけた最初 help
の項目が実行されます。
たとえば、セッションに コマンドレットと 関数 (両方とも という名前 Get-Map
) が含まれている場合、 と入力 Get-Map
すると、PowerShell によって関数が実行されます。
セッションに同じ名前の同じ種類のアイテムが含まれている場合、PowerShell は新しい項目を実行します。
たとえば、モジュールから別 Get-Date
のコマンドレットをインポートする場合、「 」と入力 Get-Date
すると、PowerShell はネイティブバージョンに対してインポートされたバージョンを実行します。
非表示のアイテムと置換されたアイテム
これらのルールの結果として、アイテムは同じ名前のアイテムに置き換えたり非表示にしたりすることができます。
項目名をモジュールまたはスナップイン名で修飾するなどして、元のアイテムに引き続きアクセスできる場合、アイテムは "非表示" または "影付き" になります。
たとえば、セッションでコマンドレットと同じ名前の関数をインポートすると、スナップインまたはモジュールからインポートされたため、コマンドレットは非表示になります (ただし、置き換えられません)。
元のアイテムにアクセスできなくなった場合、アイテムは "置換" または "上書き" されます。
たとえば、セッション内の変数と同じ名前の変数をインポートすると、元の変数が置き換えられ、アクセスできなくなります。 モジュール名で変数を修飾することはできません。
また、コマンド ラインで関数を入力し、同じ名前の関数をインポートすると、元の関数は置き換えられ、アクセスできなくなります。
非表示のコマンドの検索
Get-Command コマンドレットの All パラメーターは、非表示または置き換えられた場合でも、指定した名前のすべてのコマンドを取得します。 PowerShell 3.0 以降では、既定では、 Get-Command
コマンド名を入力したときに実行されるコマンドのみが取得されます。
次の例では、セッションに関数と Get-Date コマンドレットが含まれていますGet-Date
。
次のコマンドは、 を Get-Date
入力 Get-Date
したときに実行されるコマンドを取得します。
Get-Command Get-Date
CommandType Name ModuleName
----------- ---- ----------
Function Get-Date
次のコマンドでは、 All パラメーターを使用してすべての Get-Date
コマンドを取得します。
Get-Command Get-Date -All
CommandType Name ModuleName
----------- ---- ----------
Function Get-Date
Cmdlet Get-Date Microsoft.PowerShell.Utility
非表示のコマンドの実行
特定のコマンドを実行するには、コマンドを同じ名前の他のコマンドと区別する項目プロパティを指定します。 このメソッドを使用して任意のコマンドを実行できますが、非表示のコマンドを実行する場合に特に便利です。
修飾名
コマンドレットのモジュール修飾名を使用すると、同じ名前の項目で非表示のコマンドを実行できます。 たとえば、コマンドレットを Get-Date
実行するには、そのモジュール名 Microsoft.PowerShell.Utility で修飾します。
配布するスクリプトを記述する場合は、この推奨される方法を使用します。 スクリプトが実行されるセッションに存在する可能性のあるコマンドを予測することはできません。
New-Alias -Name "Get-Date" -Value "Get-ChildItem"
Microsoft.PowerShell.Utility\Get-Date
Tuesday, September 4, 2018 8:17:25 AM
モジュールによってMapFunctions
追加されたコマンドをNew-Map
実行するには、そのモジュール修飾名を使用します。
MapFunctions\New-Map
コマンドのインポート元のモジュールを見つけるには、コマンドの ModuleName プロパティを使用します。
(Get-Command <command-name>).ModuleName
たとえば、 コマンドレットの Get-Date
ソースを検索するには、次のように入力します。
(Get-Command Get-Date).ModuleName
Microsoft.PowerShell.Utility
注意
変数またはエイリアスを修飾することはできません。
呼び出し演算子
また、 演算子&
をCall
使用して、非表示のコマンドを Get-ChildItem (別名は "dir") Get-Command
または Get-Module の呼び出しと組み合わせて実行することもできます。
呼び出し演算子は、子スコープで文字列とスクリプト ブロックを実行します。 詳細については、「 about_Operators」を参照してください。
たとえば、 という名前の関数があり、 というMap
Map
名前のエイリアスによって非表示になっている場合は、次のコマンドを使用して関数を実行します。
&(Get-Command -Name Map -CommandType Function)
または
&(dir Function:\map)
非表示のコマンドを変数に保存して、実行を容易にすることもできます。
たとえば、次のコマンドは、 関数を Map
変数に $myMap
保存し、 演算子を Call
使用して実行します。
$myMap = (Get-Command -Name map -CommandType function)
&($myMap)
置換された項目
"置き換えられた" 項目は、アクセスできなくなったアイテムです。 同じ名前の項目をモジュールまたはスナップインからインポートすることで、項目を置き換えることができます。
たとえば、セッションに関数を Get-Map
入力し、 という関数 Get-Map
をインポートすると、元の関数が置き換えられます。 現在のセッションでは取得できません。
変数とエイリアスは、呼び出し演算子または修飾名を使用して実行できないため、非表示にすることはできません。 モジュールまたはスナップインから変数とエイリアスをインポートすると、セッション内の変数が同じ名前に置き換えられます。
名前の競合の回避
コマンド名の競合を管理する最善の方法は、競合を防ぐことです。 コマンドに名前を付ける場合は、一意の名前を使用します。 たとえば、コマンドの名詞にイニシャルまたは会社名の頭字語を追加します。
また、PowerShell モジュールまたは別のセッションからコマンドをセッションにインポートする場合は、Prefix
Import-Module または
コマンド名の名詞にプレフィックスを追加する Import-PSSession コマンドレット。
たとえば、次のコマンドは、モジュールをインポートするときに PowerShell に付属する コマンドレットと Set-Date
コマンドレットとのGet-Date
競合をDateFunctions
回避します。
Import-Module -Name DateFunctions -Prefix ZZ
詳細については、以下をImport-PSSession
参照してくださいImport-Module
。