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 會在針對目前工作階段中載入的所有項目執行命令時,會使用下列優先順序:
- Alias
- 函式
- Cmdlet
- 外部可執行檔 (程式和非 PowerShell 腳稿)
因此,如果您輸入 「help」,PowerShell 會先尋找名為 的別名,然後尋找名為 help
Help
的函式,最後是名為 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-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 Cmdlet 可將前置詞新增至命令名稱中的名詞。
例如,下列命令可避免匯入模組時DateFunctions
,與 PowerShell 隨附的 Get-Date
和 Set-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
環境變數。