Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Если вы часто используете одни и те же однострочные команды или скрипты PowerShell, то преобразование их в повторно используемые инструменты становится еще более важным. Упаковка функций в модуле скрипта дает им более профессиональный вид и упрощает их поддержку и совместное использование с другими пользователями.
Функции точечного подключения
Одна вещь, которую мы не охватывали в предыдущей главе, — это функции dot-sourcing. Если вы определяете функцию в скрипте, но не в составе модуля, единственным способом его загрузки в память является dot-sourcing его .ps1 файл.
Например, сохраните следующую функцию в файле с именем Get-MrPSVersion.ps1.
function Get-MrPSVersion {
$PSVersionTable
}
При запуске скрипта кажется, что ничего не происходит.
.\Get-MrPSVersion.ps1
Попытка вызова функции приводит к ошибке, так как она не загружается в память.
Get-MrPSVersion
Get-MrPSVersion : The term 'Get-MrPSVersion' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Get-MrPSVersion
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrPSVersion:String) [],
CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Вы можете подтвердить, загружаются ли функции в память, проверяя их существование в функции: PSDrive.
Get-ChildItem -Path Function:\Get-MrPSVersion
Get-ChildItem : Cannot find path 'Get-MrPSVersion' because it does not
exist.
At line:1 char:1
+ Get-ChildItem -Path Function:\Get-MrPSVersion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrPSVersion:String) [Get
-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.Ge
tChildItemCommand
Проблема с запуском скрипта, определяющего функцию, заключается в том, что она загружает ее в область скрипта . После завершения выполнения скрипта PowerShell удаляет область, а также функцию.
Чтобы функция была доступна после выполнения скрипта, ее необходимо загрузить в глобальную область. Это можно сделать, положив точку в файл скрипта. Для этой цели можно использовать относительный путь.
. .\Get-MrPSVersion.ps1
Вы также можете использовать полный путь к скрипту при выполнении его с использованием dot-sourcing.
. C:\Demo\Get-MrPSVersion.ps1
Если часть пути хранится в переменной, ее можно объединить с остальной частью пути. Для этого не нужно использовать объединение строк.
$Path = 'C:\'
. $Path\Get-MrPSVersion.ps1
Теперь, если вы проверите Function PSDrive, вы увидите, что функция Get-MrPSVersion доступна.
Get-ChildItem -Path Function:\Get-MrPSVersion
CommandType Name Version
----------- ---- -------
Function Get-MrPSVersion
Модули скриптов
В PowerShell модуль скрипта — это просто .psm1 файл, содержащий одну или несколько функций, как обычный скрипт, но с другим расширением файла.
Как создать модуль скрипта? Вы можете предположить, что команда называется примерно так New-Module. Это предположение является разумным предположением, но эта команда фактически создает динамический модуль, а не модуль скрипта.
Этот сценарий является хорошим напоминанием, чтобы всегда читать справочную документацию, даже если имя команды кажется тем, что нужно.
help New-Module
NAME
New-Module
SYNOPSIS
Creates a new dynamic module that exists only in memory.
SYNTAX
New-Module [-Name] <System.String> [-ScriptBlock]
<System.Management.Automation.ScriptBlock> [-ArgumentList
<System.Object[]>] [-AsCustomObject] [-Cmdlet <System.String[]>]
[-Function <System.String[]>] [-ReturnResult] [<CommonParameters>]
DESCRIPTION
The `New-Module` cmdlet creates a dynamic module from a script block.
The members of the dynamic module, such as functions and variables, are
immediately available in the session and remain available until you
close the session.
Like static modules, by default, the cmdlets and functions in a dynamic
module are exported and the variables and aliases are not. However, you
can use the Export-ModuleMember cmdlet and the parameters of
`New-Module` to override the defaults.
You can also use the **AsCustomObject** parameter of `New-Module` to return
the dynamic module as a custom object. The members of the modules, such
as functions, are implemented as script methods of the custom object
instead of being imported into the session.
Dynamic modules exist only in memory, not on disk. Like all modules,
the members of dynamic modules run in a private module scope that is a
child of the global scope. Get-Module cannot get a dynamic module, but
Get-Command can get the exported members.
To make a dynamic module available to `Get-Module`, pipe a `New-Module`
command to Import-Module, or pipe the module object that `New-Module`
returns to `Import-Module`. This action adds the dynamic module to the
`Get-Module` list, but it does not save the module to disk or make it
persistent.
RELATED LINKS
Online Version: https://learn.microsoft.com/powershell/module/microsoft.
powershell.core/new-module?view=powershell-5.1&WT.mc_id=ps-gethelp
Export-ModuleMember
Get-Module
Import-Module
Remove-Module
about_Modules
REMARKS
To see the examples, type: "Get-Help New-Module -Examples".
For more information, type: "Get-Help New-Module -Detailed".
For technical information, type: "Get-Help New-Module -Full".
For online help, type: "Get-Help New-Module -Online"
В предыдущей главе упоминалось, что функции должны использовать утвержденные глаголы. В противном случае PowerShell создает предупреждение при импорте модуля.
В следующем примере используется командлет New-Module для создания динамического модуля в памяти, конкретно для демонстрации того, что происходит, если не использовать утвержденный глагол.
New-Module -Name MyModule -ScriptBlock {
function Return-MrOsVersion {
Get-CimInstance -ClassName Win32_OperatingSystem |
Select-Object -Property @{Label='OperatingSystem';Expression={$_.Caption}}
}
Export-ModuleMember -Function Return-MrOsVersion
} | Import-Module
WARNING: The names of some imported commands from the module 'MyModule' include
unapproved verbs that might make them less discoverable. To find the commands with
unapproved verbs, run the Import-Module command again with the Verbose parameter. For a
list of approved verbs, type Get-Verb.
Хотя вы использовали командлет New-Module в предыдущем примере, как упоминалось ранее, это не команда для создания модулей сценариев в PowerShell.
Чтобы создать модуль скрипта, сохраните функции в .psm1 файле. Например, сохраните следующие две функции в файле с именем MyScriptModule.psm1.
function Get-MrPSVersion {
$PSVersionTable
}
function Get-MrComputerName {
$env:COMPUTERNAME
}
Попробуйте запустить одну из функций.
Get-MrComputerName
При вызове функции вы получите сообщение об ошибке, указывая, что PowerShell не удается найти ее. Как и раньше, проверка функции: PSDrive подтверждает, что она не загружена в память.
Get-MrComputerName : The term 'Get-MrComputerName' is not recognized as the
name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is
correct and try again.
At line:1 char:1
+ Get-MrComputerName
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrComputerName:String) [
], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Чтобы сделать функцию доступной, можно вручную импортировать MyScriptModule.psm1 файл с помощью командлета Import-Module .
Import-Module C:\MyScriptModule.psm1
PowerShell представила автоматическую загрузку модуля в версии 3. Чтобы воспользоваться этой функцией, модуль скрипта должен быть сохранен в папке с тем же базовым именем, что .psm1 и файл. Эта папка должна находиться в одном из каталогов, указанных в переменной $env:PSModulePath среды.
$env:PSModulePath
Выходные $env:PSModulePath данные трудно прочитать.
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules;C:\Program Files\Wind
owsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\
Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
Чтобы сделать результаты более читаемыми, разделите пути на разделитель путей с запятой, чтобы каждый из них отображался в собственной строке.
$env:PSModulePath -split ';'
Первые три пути в списке — это расположения модулей по умолчанию. SQL Server Management Studio добавила последний путь при его установке.
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\Windows\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
Для автоматической загрузки модуля необходимо поместить MyScriptModule.psm1 файл в папку с именем MyScriptModule, и эта папка должна находиться непосредственно в одном из путей, перечисленных в
$env:PSModulePath.
Не все эти пути одинаково полезны. Например, текущий путь пользователя в моей системе не является первым в списке. Это связано с тем, что я вхожу в Windows с другой учетной записью, чем та, которую использую для запуска PowerShell. Таким образом, он не указывает на папку документов моего пользователя.
Второй путь — это путь AllUsers , где я сохраняю все мои модули.
Третий путь указывает на C:\Windows\System32защищенное расположение системы. Только корпорация Майкрософт должна размещать модули там, так как она находится под структурой каталогов операционной системы.
После размещения .psm1 файла в соответствующей папке в одном из этих путей PowerShell автоматически загружает модуль при первом вызове одной из его команд.
Манифесты модуля
Каждый модуль должен содержать манифест модуля, который представляет собой .psd1 файл, содержащий метаданные о модуле.
.psd1 Хотя расширение используется для манифестов, не все .psd1 файлы являются манифестами модуля. Их также можно использовать для других целей, таких как определение данных среды в DSC
конфигурация.
Манифест модуля можно создать с помощью командлета New-ModuleManifest . Единственным обязательным параметром является Path, но для правильной работы модуля необходимо также указать параметр RootModule .
Рекомендуется включить такие значения, как Author и Description, особенно если вы планируете опубликовать модуль в репозитории NuGet с помощью PowerShellGet. Эти поля необходимы в этом сценарии.
Один из быстрых способов определить, отсутствует ли у модуля манифест, — это проверить его версию.
Get-Module -Name MyScriptModule
Номер 0.0 версии является четким признаком отсутствия манифеста модуля.
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 MyScriptModule {Get-MrComputer...
При создании манифеста модуля следует включить все рекомендуемые сведения, чтобы убедиться, что модуль хорошо документирован и готов к совместному использованию или публикации.
$moduleManifestParams = @{
Path = "$env:ProgramFiles\WindowsPowerShell\Modules\MyScriptModule\MyScriptModule.psd1"
RootModule = 'MyScriptModule'
Author = 'Mike F. Robbins'
Description = 'MyScriptModule'
CompanyName = 'mikefrobbins.com'
}
New-ModuleManifest @moduleManifestParams
Если при первоначальном создании манифеста модуля опустить какие-либо значения, можно добавить или обновить его позже с помощью командлета Update-ModuleManifest . Избегайте повторного создания манифеста после того, как вы создадите его, так как это создает новый GUID.
Определение общедоступных и частных функций
Иногда модуль может включать вспомогательные функции, которые вы не хотите предоставлять пользователям. Эти частные функции используются внутренне другими функциями в модуле, но не предоставляются пользователям. Существует несколько способов обработки этого сценария.
Если вы не следуете лучшим практикам и имеете только файл .psm1 без манифеста модуля, единственным вариантом является управление видимостью с помощью командлета Export-ModuleMember. Этот параметр позволяет явно определить, какие функции следует предоставлять непосредственно из .psm1 файла модуля скрипта, сохраняя все остальные закрытые по умолчанию.
В следующем примере только Get-MrPSVersion функция предоставляется пользователям модуля, а Get-MrComputerName функция остается доступной внутренне другим функциям в модуле.
function Get-MrPSVersion {
$PSVersionTable
}
function Get-MrComputerName {
$env:COMPUTERNAME
}
Export-ModuleMember -Function Get-MrPSVersion
Определите, какие команды доступны публично в модуле MyScriptModule .
Get-Command -Module MyScriptModule
CommandType Name Version
----------- ---- -------
Function Get-MrPSVersion 1.0
При добавлении манифеста модуля в модуль рекомендуется явно перечислить функции, которые необходимо экспортировать в разделе FunctionsToExport . Этот параметр позволяет контролировать, что вы показываете пользователям из файла манифеста модуля .psd1.
FunctionsToExport = 'Get-MrPSVersion'
Вам не нужно использовать и Export-ModuleMember в файле, и .psm1 в разделе FunctionsToExport манифеста модуля. Каждый подход достаточен сам по себе.
Сводка
В этой главе вы узнали, как превратить функции в модуль скрипта в PowerShell. Вы также изучили рекомендации по созданию модулей скриптов, включая важность добавления манифеста модуля для определения метаданных и управления экспортируемыми командами.
Отзыв
- Как создать модуль скрипта в PowerShell?
- Почему важно использовать утвержденные глаголы в именах функций?
- Как создать манифест модуля в PowerShell?
- Каковы два способа экспорта только определенных функций из модуля?
- Какие условия необходимо выполнить для автоматической загрузки модуля при выполнении одной из ее команд?
Ссылки
PowerShell