Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Редакционная заметка
Важно
Спецификация языка Windows PowerShell 3.0 была опубликована в декабре 2012 года и разработана с использованием Windows PowerShell 3.0. Эта спецификация не отражает текущее состояние PowerShell. Нет плана обновить эту документацию, чтобы отразить текущее состояние. Эта документация представлена здесь для получения исторической справки.
Документ спецификации доступен в виде документа Microsoft Word в Центре загрузки Майкрософт: https://www.microsoft.com/download/details.aspx?id=36389. Этот документ Word был преобразован для представления на портале Microsoft Learn. Во время преобразования некоторые редакционные изменения были внесены в соответствии с форматированием платформы Docs. Исправлены некоторые опечатки и незначительные ошибки.
Введение 11.1
Как указано в §3.14, модуль является автономной единицей повторного использования, которая позволяет секционировать, упорядочивать и абстрагировать код PowerShell. Модуль может содержать одного или более членов модуля , которые являются командами (например, командлетами и функциями) и элементами (такими как переменные и псевдонимы). Имена этих членов могут быть закрыты для модуля или они могут быть экспортированы в сеанс, в который модуль импортирован.
Существует три различных типа модуля : манифест, скрипт и двоичный файл. Модуль манифеста — это файл, содержащий сведения о модуле, и управляет определенными аспектами использования этого модуля. Модуль скрипта
Двоичный модуль — это сборка .NET (т. е. библиотека DLL), которая была скомпилирована с использованием библиотек PowerShell.
Модули могут вкладываться, то есть один модуль может импортировать другой модуль. Модуль, имеющий связанные вложенные модули, — это корневой модуль.
При создании сеанса PowerShell по умолчанию модули не импортируются.
При импорте модулей путь поиска, используемый для их поиска, определяется переменной среды PSModulePath.
Следующие командлеты имеют дело с модулями:
- Get-Module: определяет модули, которые были или могут быть импортированы
- импорт-модуль: добавляет один или несколько модулей в текущий сеанс (см. раздел §11.4)
- Export-ModuleMember: определяет элементы модуля, экспортируемые
- Remove-Module: Удаляет один или несколько модулей из текущего сеанса (см. §11.5)
- новый модуль: создает динамический модуль (см. §11.7)
11.2 Написание модуля скрипта
Модуль скрипта — это файл скрипта. Рассмотрим следующий модуль скрипта:
function Convert-CentigradeToFahrenheit ([double]$tempC) {
return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit
function Convert-FahrenheitToCentigrade ([double]$tempF) {
return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade
Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c
Этот модуль содержит две функции, каждая из которых имеет псевдоним. По умолчанию экспортируются все имена функций и только имена функций. Однако после использования командлета Export-ModuleMember для экспорта чего-либо будут экспортированы только те вещи, которые были экспортированы явным образом. Ряд команд и элементов можно экспортировать либо в одном, либо в нескольких вызовах этого командлета; такие вызовы накапливаются в течение текущего сеанса.
11.3. Установка модуля скрипта
Модуль скрипта определен в файле скрипта, и модули могут храниться в любом каталоге. Переменная среды PSModulePath указывает на набор каталогов, в которых следует выполнять поиск, когда командлеты, связанные с модулями, ищут модули, имена которых не содержат полный путь. Можно указать дополнительные пути поиска; Например
$Env:PSModulePath = $Env:PSModulePath + ";<additional-path>"
Любые дополнительные пути, добавленные, влияют только на текущий сеанс.
Кроме того, можно указать полный путь при импорте модуля.
11.4 Импорт модуля скрипта
Прежде чем использовать ресурсы в модуле, этот модуль необходимо импортировать в текущий сеанс с помощью командлета Import-Module.
Import-Module может ограничить ресурсы, которые он фактически импортирует.
При импорте модуля выполняется его файл скрипта. Этот процесс можно настроить путем определения одного или нескольких параметров в файле скрипта и передачи соответствующих аргументов с помощью параметра ArgumentList Import-Module.
Рассмотрим следующий сценарий, использующий эти функции и псевдонимы, определенные в §11.2:
Import-Module "E:\Scripts\Modules\PSTest_Temperature" -Verbose
"0 degrees C is " + (Convert-CentigradeToFahrenheit 0) + " degrees F"
"100 degrees C is " + (c2f 100) + " degrees F"
"32 degrees F is " + (Convert-FahrenheitToCentigrade 32) + " degrees C"
"212 degrees F is " + (f2c 212) + " degrees C"
Импорт модуля приводит к конфликту имен, когда команды или элементы в модуле имеют те же имена, что и команды или элементы в сеансе. Конфликт имен приводит к скрытию или замене имени. Параметр префикса Import-Module можно использовать для предотвращения конфликтов именования. Кроме того, параметры
Даже если команда скрыта, ее можно запустить, указав его имя с именем модуля, в котором она возникла. Например, & M\F 100 вызывает функцию F в модуле Mи передает аргумент 100.
Если сеанс включает команды одного типа с одинаковым именем, например два командлета с одинаковым именем, по умолчанию выполняется последняя добавленная команда.
См. §3.5.6 для обсуждения области, связанной с модулями.
11.5 Удаление модуля скрипта
Один или несколько модулей можно удалить из сеанса с помощью командлета Remove-Module.
Удаление модуля не деинсталлирует модуль.
В модуле скрипта можно указать код, который должен выполняться до удаления этого модуля, как показано ниже.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { *on-removal-code* }
Манифесты модуля 11.6
Как указано в §11.1, модуль манифеста — это файл, содержащий сведения о модуле, и управляет определенными аспектами использования этого модуля.
Модуль не должен иметь соответствующий манифест, но если он это делает, этот манифест имеет то же имя, что и модуль, который он описывает, но с расширением файла .psd1.
Манифест содержит ограниченное подмножество скрипта PowerShell, которое возвращает хэш-файл, содержащий набор ключей. Эти ключи и их значения указывают элементы манифеста для этого модуля. То есть они описывают содержимое и атрибуты модуля, определяют все предварительные требования и определяют способ обработки компонентов.
По сути, манифест — это файл данных; однако он может содержать ссылки на типы данных, оператор if и арифметические и операторы сравнения. (Назначения, определения функций и циклы не разрешены.) Манифест также имеет доступ на чтение к переменным среды, и он может содержать вызовы командлета Join-Path, чтобы можно было создавать пути.
Заметка
Примечание редактора. Исходный документ содержит список ключей, разрешенных в файле манифеста модуля. Этот список устарел и не является неполным. Полный список ключей в манифесте модуля см. в разделе New-ModuleManifest.
Единственный требующийся ключ — это ModuleVersion.
Ниже приведен пример простого манифеста:
@{
ModuleVersion = '1.0'
Author = 'John Doe'
RequiredModules = @()
FunctionsToExport = 'Set*','Get*','Process*'
}
Ключ GUID имеет значение string. Указан глобально уникальный идентификатор (GUID) для модуля.
GUID можно использовать для различения модулей с одинаковым именем. Чтобы создать новый GUID, вызовите метод [guid]::NewGuid().
Динамические модули 11.7
динамический модуль — это модуль, созданный в памяти во время выполнения командлетом New-Module; Он не загружается с диска. Рассмотрим следующий пример:
$sb = {
function Convert-CentigradeToFahrenheit ([double]$tempC) {
return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit
function Convert-FahrenheitToCentigrade ([double]$tempF) {
return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade
Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c
}
New-Module -Name MyDynMod -ScriptBlock $sb
Convert-CentigradeToFahrenheit 100
c2f 100
Блок скрипта $sb определяет содержимое модуля, в данном случае две функции и два псевдонима для этих функций. Как и в случае с модулем на диске, по умолчанию экспортируются только функции, поэтому вызовы командлетов Export-ModuleMember существуют для экспорта функций и псевдонимов.
После выполнения New-Module экспортируемые четыре имена доступны для использования в сеансе, как показано вызовами Convert-CentigradeToFahrenheit и c2f.
Как и все модули, члены динамических модулей выполняются в частной области модуля, которая является дочерним элементом глобальной области.
Get-Module не удается получить динамический модуль, но Get-Command может получить экспортированные члены.
Чтобы сделать динамический модуль доступным для Get-Module, передайте команду New-Module в Import-Moduleили передайте объект модуля, который возвращает New-Module, в Import-Module. Это действие добавляет динамический модуль в список Get-Module, но не сохраняет модуль на диск или делает его постоянным.
11.8 Закрытия
Динамический модуль можно использовать для создания замыкания— функции, связанной с данными. Рассмотрим следующий пример:
function Get-NextID ([int]$StartValue = 1) {
$nextID = $StartValue
{
($Script:nextID++)
}.GetNewClosure()
}
$v1 = Get-NextID # get a scriptblock with $StartValue of 0
& $v1 # invoke Get-NextID getting back 1
& $v1 # invoke Get-NextID getting back 2
$v2 = Get-NextID 100 # get a scriptblock with $StartValue of 100
& $v2 # invoke Get-NextID getting back 100
& $v2 # invoke Get-NextID getting back 101
Цель заключается в том, чтобы Get-NextID вернул следующий идентификатор в последовательности, начальное значение которой можно указать. Однако необходимо поддерживать несколько последовательностей, каждая из которых имеет собственный $StartValue и контекст $nextID. Это достигается вызовом метода [scriptblock]::GetNewClosure (§4.3.7).
Каждый раз, когда создается новое замыкание с помощью GetNewClosure, создается новый динамический модуль, и переменные в области видимости вызывающей функции (в данном случае блок скрипта, содержащий инкремент) копируются в этот новый модуль. Чтобы убедиться, что nextId, определенный внутри родительской функции (но за пределами блока скрипта), инкрементируется, требуется явный префикс области Script:.
Конечно, блок скрипта не должен быть именованной функцией; Например:
$v3 = & { # get a scriptblock with $StartValue of 200
param ([int]$StartValue = 1)
$nextID = $StartValue
{
($Script:nextID++)
}.GetNewClosure()
} 200
& $v3 # invoke script getting back 200
& $v3 # invoke script getting back 201
PowerShell