Сведения о приоритете команд
Краткое описание
Описывает, как PowerShell определяет выполняемую команду.
Подробное описание
Приоритет команд описывает, как PowerShell определяет, какую команду следует выполнять, если сеанс содержит несколько команд с одинаковыми именами. Команды в сеансе могут быть скрыты или заменены командами с тем же именем. В этой статье показано, как выполнять скрытые команды и как избежать конфликтов имен команд.
Приоритет команд
Если сеанс PowerShell содержит несколько команд с одинаковыми именами, PowerShell определяет, какую команду следует выполнить, используя следующие правила.
Если указать путь к команде, PowerShell выполняет команду в расположении, указанном путем.
Например, следующая команда запускает скрипт FindDocs.ps1 в каталоге C:\TechDocs:
C:\TechDocs\FindDocs.ps1
В качестве функции безопасности PowerShell не выполняет исполняемые (собственные) команды, включая скрипты PowerShell, если команда не находится в пути, указанном в переменной $env:path
среды 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 использует следующий порядок очередности при выполнении команд для всех элементов, загруженных в текущем сеансе:
- Псевдоним
- Функция
- Командлет
- Внешние исполняемые файлы (программы и скрипты, не относящиеся к PowerShell)
Таким образом, если ввести "help", PowerShell сначала ищет псевдоним с именем help
, затем функцию с именем Help
и, наконец, командлет с именем Help
. Он запускает первый help
найденный элемент.
Например, если сеанс содержит командлет и функцию с именем Get-Map
, при вводе Get-Map
powerShell запускает функцию .
Примечание
Это относится только к загруженным командам. При наличии исполняемого build
файла и псевдонима build
для функции с именем Invoke-Build
внутри модуля, который не загружается в текущий сеанс, PowerShell запускает исполняемый build
файл. Он не загружает модули автоматически, если в этом случае находит внешний исполняемый файл. Только в том случае, если внешний исполняемый файл не найден, вызывается псевдоним, функция или командлет с заданным именем, что активирует автоматическую загрузку модуля.
Если сеанс содержит элементы того же типа с одинаковым именем, PowerShell запускает новый элемент.
Например, при импорте другого Get-Date
командлета из модуля при вводе Get-Date
PowerShell запускает импортированную версию по сравнению с собственной.
Скрытые и замененные элементы
В результате выполнения этих правил элементы могут быть заменены или скрыты элементами с тем же именем.
Элементы будут "скрыты" или "затеняются", если вы по-прежнему можете получить доступ к исходному элементу, например путем указания имени элемента с помощью имени модуля или оснастки.
Например, если импортировать функцию с тем же именем, что и командлет в сеансе, командлет будет скрыт (но не заменен), так как он был импортирован из оснастки или модуля.
Элементы будут "заменены" или "перезаписаны", если вы больше не можете получить доступ к исходному элементу.
Например, если импортировать переменную с тем же именем, что и переменная в сеансе, исходная переменная заменяется и становится недоступной. Нельзя указать переменную с именем модуля.
Кроме того, если ввести функцию в командной строке, а затем импортировать функцию с тем же именем, исходная функция будет заменена и будет недоступна.
Поиск скрытых команд
Параметр All командлета Get-Command получает все команды с указанным именем, даже если они скрыты или заменены. Начиная с 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
Чтобы выполнить New-Map
команду, добавленную модулем MapFunctions
, используйте имя модуля:
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 для добавления префикса к существительным в именах команд.
Например, следующая команда позволяет избежать конфликтов с Get-Date
командлетами и Set-Date
, которые поставляются вместе с PowerShell при импорте DateFunctions
модуля.
Import-Module -Name DateFunctions -Prefix ZZ
Дополнительные сведения см Import-Module
. в разделе и Import-PSSession
ниже.