Поделиться через


Сведения о приоритете команд

Краткое описание

Описывает, как 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 использует следующий порядок очередности при выполнении команд для всех элементов, загруженных в текущем сеансе:

  1. Псевдоним
  2. Функция
  3. Командлет
  4. Внешние исполняемые файлы (программы и скрипты, не относящиеся к PowerShell)

Таким образом, если ввести "help", PowerShell сначала ищет псевдоним с именем help, затем функцию с именем Helpи, наконец, командлет с именем Help. Он запускает первый help найденный элемент.

Например, если сеанс содержит командлет и функцию с именем Get-Map, при вводе Get-MappowerShell запускает функцию .

Примечание

Это относится только к загруженным командам. При наличии исполняемого build файла и псевдонима build для функции с именем Invoke-Build внутри модуля, который не загружается в текущий сеанс, PowerShell запускает исполняемый build файл. Он не загружает модули автоматически, если в этом случае находит внешний исполняемый файл. Только в том случае, если внешний исполняемый файл не найден, вызывается псевдоним, функция или командлет с заданным именем, что активирует автоматическую загрузку модуля.

Если сеанс содержит элементы того же типа с одинаковым именем, PowerShell запускает новый элемент.

Например, при импорте другого Get-Date командлета из модуля при вводе Get-DatePowerShell запускает импортированную версию по сравнению с собственной.

Скрытые и замененные элементы

В результате выполнения этих правил элементы могут быть заменены или скрыты элементами с тем же именем.

Элементы будут "скрыты" или "затеняются", если вы по-прежнему можете получить доступ к исходному элементу, например путем указания имени элемента с помощью имени модуля или оснастки.

Например, если импортировать функцию с тем же именем, что и командлет в сеансе, командлет будет скрыт (но не заменен), так как он был импортирован из оснастки или модуля.

Элементы будут "заменены" или "перезаписаны", если вы больше не можете получить доступ к исходному элементу.

Например, если импортировать переменную с тем же именем, что и переменная в сеансе, исходная переменная заменяется и становится недоступной. Нельзя указать переменную с именем модуля.

Кроме того, если ввести функцию в командной строке, а затем импортировать функцию с тем же именем, исходная функция будет заменена и будет недоступна.

Поиск скрытых команд

Параметр 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 ниже.

См. также раздел