共用方式為


about_Command_Precedence

簡短描述

描述 PowerShell 如何決定要執行的命令。

完整描述

命令優先順序描述當會話包含多個具有相同名稱的命令時,PowerShell 如何決定要執行的命令。 會話內的命令可以隱藏或由相同名稱的命令取代。 本文說明如何執行隱藏的命令,以及如何避免命令名稱衝突。

命令優先順序

當 PowerShell 工作階段包含多個具有相同名稱的命令時,PowerShell 會使用下列規則來決定要執行的命令。

如果您指定命令的路徑,PowerShell 會在路徑所指定的位置執行命令。

例如,下列命令會在 「C:\TechDocs」 目錄中執行 FindDocs.ps1 腳本:

C:\TechDocs\FindDocs.ps1

作為安全性功能,除非命令位於Path環境變數 $env:path 中所列的路徑,或除非您指定腳本檔案的路徑,否則PowerShell不會執行可執行檔 (原生) 命令。

若要執行目前目錄中的文稿,請指定完整路徑,或輸入代表目前目錄的點 .\

例如,若要在當前目錄中執行 FindDocs.ps1 檔案,請輸入:

.\FindDocs.ps1

在執行中使用通配符

您可以在命令執行中使用通配符。 使用通配符也稱為 通配符

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 會在針對目前工作階段中載入的所有項目執行命令時,會使用下列優先順序:

  1. Alias
  2. 函式
  3. Cmdlet
  4. 外部可執行檔 (程式和非 PowerShell 腳稿)

因此,如果您輸入 「help」,PowerShell 會先尋找名為 的別名,然後尋找名為 helpHelp的函式,最後是名為 Help的 Cmdlet。 它會執行找到的第一 help 個專案。

例如,如果您的會話包含 Cmdlet 和函式,則當您輸入 Get-Map時,兩者都名為 Get-Map,PowerShell 會執行函式。

注意

這隻適用於載入的命令。 如果函式具有build未載入目前會話之 模組內名稱的Invoke-Build可執行檔和別名build,PowerShell 會build改為執行可執行檔。 在此情況下,如果它找到外部可執行檔,則不會自動載入模組。 只有在找不到任何外部可執行檔時,才會叫用具有指定名稱的別名、函式或 Cmdlet,進而觸發其模組的自動載入。

當會話包含具有相同名稱之相同類型的專案時,PowerShell 會執行較新的專案。

例如,如果您從模組匯入另一個 Get-Date Cmdlet,當您輸入 Get-Date時,PowerShell 會透過原生版本執行匯入的版本。

隱藏和取代的專案

由於這些規則,專案可以由具有相同名稱的專案取代或隱藏。

如果您仍然可以存取原始專案,例如將專案名稱限定為模組或嵌入式管理單元名稱,則專案為「隱藏」或「陰影」。

例如,如果您匯入的函式名稱與會話中的 Cmdlet 相同,Cmdlet 會隱藏 (,但不會取代) ,因為它已從嵌入式管理單元或模組匯入。

如果您無法再存取原始專案,專案會「已取代」或「覆寫」。

例如,如果您匯入與會話中變數同名的變數,則會取代原始變數,且無法再存取。 您無法使用模組名稱限定變數。

此外,如果您在命令行輸入函式,然後匯入具有相同名稱的函式,則會取代原始函式,且無法再存取。

尋找隱藏的命令

Get-Command Cmdlet 的 All 參數會取得具有指定名稱的所有命令,即使它們已隱藏或取代也一樣。 從 PowerShell 3.0 開始,根據預設, Get-Command 只會取得當您輸入命令名稱時所執行的命令。

在下列範例中,會話包含函 Get-Date 式和 Get-Date Cmdlet。

下列命令會取得 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

執行隱藏的命令

您可以指定專案屬性來執行特定命令,以區別命令與其他可能具有相同名稱的命令。 您可以使用這個方法來執行任何命令,但對於執行隱藏命令特別有用。

使用限定名稱

使用 Cmdlet 的模組限定名稱,可讓您執行具有相同名稱的專案所隱藏的命令。 例如,您可以使用 Get-Date 其模組名稱 Microsoft.PowerShell.Utility 來限定 Cmdlet 來執行 Cmdlet。

撰寫您想要散發的腳本時,請使用這個慣用的方法。 您無法預測文稿執行所在的會話中可能會出現哪些命令。

New-Alias -Name "Get-Date" -Value "Get-ChildItem"
Microsoft.PowerShell.Utility\Get-Date
Tuesday, September 4, 2018 8:17:25 AM

若要執行 New-Map 模組新增的 MapFunctions 命令,請使用其模組限定名稱:

MapFunctions\New-Map

若要尋找匯入命令的模組,請使用命令的 ModuleName 屬性。

(Get-Command <command-name>).ModuleName

例如,若要尋找 Cmdlet 的來源 Get-Date ,請輸入:

(Get-Command Get-Date).ModuleName
Microsoft.PowerShell.Utility

注意

您無法限定變數或別名。

使用呼叫運算符

您也可以使用 Call 運算符 & 來執行隱藏的命令,方法是將它與 Get-ChildItem 的呼叫結合, (別名為 “dir”) Get-CommandGet-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 模組或其他會話將命令匯入工作階段時,請使用 PrefixImport-Module 的 參數或

Import-PSSession Cmdlet 可將前置詞新增至命令名稱中的名詞。

例如,下列命令可避免匯入模組時DateFunctions,與 PowerShell 隨附的 Get-DateSet-Date Cmdlet 發生任何衝突。

Import-Module -Name DateFunctions -Prefix ZZ

執行外部可執行檔

PowerShell 會將環境變數中列出的 $env:PATHEXT 擴展名視為可執行檔。 Windows 可執行檔是具有 .COM.CPL.EXE 擴展名的檔案。 Windows 可執行檔和中所列 $env:PATHEXT 擴展名的任何其他檔案,都是在目前的控制台會話中執行。

不是 Windows 可執行文件的檔案會交給 Windows 進行處理。 Windows 會查閱檔案關聯,並執行擴充功能的預設 Windows Shell 動詞命令。 若要讓 Windows 支援依擴展名執行,您必須向系統註冊關聯。

您可以使用 CMD 命令殼層的 和 assoc 命令,為擴展名ftype註冊可執行文件引擎。 PowerShell 沒有直接方法來註冊檔案處理程式。 如需詳細資訊,請參閱 ftype 命令的檔。

若要讓 PowerShell 將擴展名視為目前工作階段中的可執行檔,您必須將擴展名新增至 $env:PATHEXT 環境變數。

另請參閱