about_Command_Precedence
Краткое описание
Описывает, как PowerShell определяет, какую команду следует выполнить.
Подробное описание
Приоритет команд описывает, как PowerShell определяет, какая команда будет выполняться, если сеанс содержит несколько команд с одинаковыми именами. Команды в сеансе могут быть скрыты или заменены командами с тем же именем. В этой статье показано, как выполнять скрытые команды и как избежать конфликтов имен команд.
Приоритет команд
Если сеанс PowerShell включает несколько команд с одинаковыми именами, PowerShell определяет, какую команду следует выполнить, используя следующие правила.
Если указать путь к команде, PowerShell выполняет команду в расположении, указанном путем.
Например, следующая команда выполняет скрипт FindDocs.ps1 в каталоге C:\TechDocs
:
C:\TechDocs\FindDocs.ps1
Вы можете выполнить любую исполняемую команду, используя полный путь к ней. В качестве функции безопасности PowerShell не выполняет исполняемые команды, включая скрипты PowerShell и собственные команды, если только команда не находится в пути, указанном в переменной $env:Path
среды.
Чтобы запустить исполняемый файл, который находится в текущем каталоге, укажите полный путь или используйте относительный путь .\
для представления текущего каталога.
Например, чтобы запустить FindDocs.ps1
файл в текущем каталоге, введите:
.\FindDocs.ps1
Если путь не указан, PowerShell использует следующий порядок очередности при выполнении команд.
- Псевдоним
- Функция
- Командлет (см . раздел Разрешение имен командлетов)
- Внешние исполняемые файлы (включая файлы скриптов PowerShell)
Таким образом, если ввести help
, PowerShell сначала ищет псевдоним с именем help
, затем функцию с именем Help
и, наконец, командлет с именем Help
. Он запускает первый help
элемент, который он находит.
Например, если сеанс содержит командлет и функцию с именем Get-Map
, при вводе Get-Map
powerShell выполняет функцию .
Примечание
Это относится только к загруженным командам. При наличии исполняемого build
файла и псевдонима build
для функции с именем Invoke-Build
внутри модуля, который не загружается в текущий сеанс, PowerShell запускает исполняемый build
файл. Он не загружает модули автоматически, если находит внешний исполняемый файл. Псевдоним, функция или командлет с заданным именем вызывается только в том случае, если внешний исполняемый файл не найден.
Разрешение элементов с одинаковыми именами
Благодаря этим правилам элементы могут быть заменены или скрыты элементами с тем же именем.
Элементы скрыты или затеняются , если вы по-прежнему можете получить доступ к исходному элементу, например путем указания имени элемента с помощью имени модуля.
Например, если импортировать функцию, имя которой совпадает с именем командлета в сеансе, командлет будет скрыт, но не заменен. Командлет можно запустить, указав полное имя модуля.
При замене или перезаписи элементов вы больше не сможете получить доступ к исходному элементу.
Например, при импорте переменной с тем же именем, что и переменная в сеансе, будет заменена исходная переменная. Вы не можете указать переменную с именем модуля.
Если вы создаете функцию в командной строке, а затем импортируете функцию с тем же именем, то исходная функция будет заменена.
Поиск скрытых команд
Параметр All командлета Get-Command получает все команды с указанным именем, даже если они скрыты или заменены. Начиная с PowerShell 3.0, по умолчанию получает только команды, Get-Command
которые выполняются при вводе имени команды.
В следующих примерах сеанс включает функцию Get-Date
и командлет Get-Date . С помощью Get-Command
можно определить, какая команда выбрана в первую очередь.
Get-Command Get-Date
CommandType Name ModuleName
----------- ---- ----------
Function Get-Date
Использует параметр All для вывода списка доступных Get-Date
команд.
Get-Command Get-Date -All
CommandType Name Version Source
----------- ---- ------- ------
Function Get-Date
Cmdlet Get-Date 7.0.0.0 Microsoft.PowerShell.Utility
Get-Command where -All
CommandType Name Version Source
----------- ---- ------- ------
Alias where -> Where-Object
Application where.exe 10.0.22621.1 C:\Windows\system32\where.exe
Вы можете выполнять определенные команды, включив соответствующие сведения, которые отличают команду от других команд, которые могут иметь то же имя.
Для командлетов можно использовать полное имя модуля. Для исполняемых файлов можно включить расширение файла. Например, для запуска исполняемой версии where
используйте where.exe
.
Использование имен с указанием модулей
С помощью имени модуля командлета можно выполнять команды, скрытые элементом с таким же именем. Например, можно запустить Get-Date
командлет, указав в нем имя модуля Microsoft.PowerShell.Utility или путь к нему. При использовании имен с указанием модуля модуль может быть автоматически импортирован в сеанс в зависимости от значения $PSModuleAutoLoadingPreference
.
Примечание
Имена модулей нельзя использовать для определения переменных или псевдонимов.
Использование имен с указанием модулей гарантирует выполнение команды, которую планируете выполнить. Это рекомендуемый метод вызова командлетов при написании скриптов, которые планируется распространять.
В следующем примере показано, как квалифицировать команду, указав имя ее модуля.
Важно!
Квалификация модуля использует символ обратной косой черты (\
), чтобы отделить имя модуля от имени команды независимо от платформы.
New-Alias -Name "Get-Date" -Value "Get-ChildItem"
Microsoft.PowerShell.Utility\Get-Date
Tuesday, May 16, 2023 1:32:51 PM
Чтобы выполнить New-Map
команду из MapFunctions
модуля, используйте его имя с указанием модуля:
MapFunctions\New-Map
Чтобы найти модуль, из которого была импортирована команда, используйте свойство ModuleName команд.
(Get-Command <command-name>).ModuleName
Например, чтобы найти источник командлета, введите Get-Date
:
(Get-Command Get-Date).ModuleName
Microsoft.PowerShell.Utility
Если вы хотите определить имя команды, используя путь к модулю, необходимо использовать косую черту (/
) в качестве разделителя пути и символ обратной косой черты (\
) перед именем команды. Используйте следующий пример для запуска командлета Get-Date
:
//localhost/c$/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date
Путь может быть полным или относительным к текущему расположению.
В Windows нельзя использовать путь с указанием диска. Необходимо использовать UNC-путь, как показано в предыдущем примере, или путь относительно текущего диска.
В следующем примере предполагается, что ваше текущее расположение находится на C:
диске.
/Progra~1/PowerShell/7-preview/Modules/Microsoft.PowerShell.Utility\Get-Date
Использование оператора вызова
Оператор вызова (&
) также можно использовать для выполнения скрытых команд, объединяя его с вызовом 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 проверяет, загружен ли командлет в текущем сеансе. Если загружено несколько модулей с одинаковым именем командлета, PowerShell использует командлет из первого найденного модуля в алфавитном порядке.
Если командлет не загружен, PowerShell выполняет поиск установленных модулей и автоматически загружает первый модуль, содержащий командлет, и запускает его.
PowerShell выполняет поиск модулей по каждому пути, определенному в переменной $env:PSModulePath
среды. Поиск путей выполняется в порядке их перечисления в переменной. В каждом пути выполняется поиск модулей в алфавитном порядке. PowerShell использует командлет из первого найденного совпадения.
Предотвращение конфликтов имен
Лучший способ управления конфликтами имен команд — предотвратить их. При присвоении имени командам используйте уникальное имя. Например, добавьте свои инициалы или аббревиатуру названия компании к существительным в командах.
При импорте команд в сеанс из модуля PowerShell или другого сеанса можно использовать Prefix
параметр командлета Import-Module или Import-PSSession , чтобы добавить префикс к существительным в именах команд.
Например, следующая команда позволяет избежать конфликтов с Get-Date
командлетами и Set-Date
, которые поставляются с PowerShell при импорте DateFunctions
модуля.
Import-Module -Name DateFunctions -Prefix ZZ
Запуск внешних исполняемых файлов
В Windows. PowerShell рассматривает расширения файлов, перечисленные в переменной $env:PATHEXT
среды, как исполняемые файлы. Файлы, которые не являются исполняемыми файлами Windows, передаются в Windows для обработки. Windows ищет сопоставление файлов и выполняет команду оболочки Windows по умолчанию для расширения. Чтобы Windows поддерживала выполнение по расширению файла, связь должна быть зарегистрирована в системе.
Вы можете зарегистрировать исполняемый модуль для расширения файла с помощью ftype
команд и assoc
командной оболочки CMD. В PowerShell нет прямого метода для регистрации обработчика файлов. Дополнительные сведения см. в документации по команде ftype .
Чтобы powerShell видел расширение файла в качестве исполняемого файла в текущем сеансе, необходимо добавить расширение в $env:PATHEXT
переменную среды.