Сегодня речь пойдёт про самодельные модули PowerShell и их установку в систему, чтобы не выполнять каждый раз Import-Module с ручной пропиской в параметр path координатов файла. Кстати, это последний пост в этом году, если не считать традиционного поздравления с наступающими праздниками. Это я к тому, что повествование может быть сумбурным, предпраздничным и суетливым. В общем, поскакали!
Где-то здесь я уже рассказывал про подключение к удалённому хосту с помощью PSRemoting. Штука отличная, если нужно провернуть что-то на удалённом хосте, не трогая пользователя и не занимая rdp. В моём случае, на момент публикации того поста, была проблема с падением службы WinRM на удалённых хостах, которую нужно было запускать вручную, а уже потом обращаться к командлету Enter-PSSession. Конечно, впоследствии эта проблема была решена, но даже до сих пор встречаются машины, на которых, в силу тех или иных факторов, упомянутая служба может быть выключена.
Для создания модуля, я взял именно кусок кода с запуском службы WinRM, который приходилось всегда держать под рукой в среде сценариев ISE. В итоге, получилась вот такая простенькая функция:
function PSConnection
{
Param(
[Parameter(Mandatory=$true)]
$ComputerName
)
try {
Set-Service -ComputerName $ComputerName -Name WinRM -Status Running -ErrorAction Stop -PassThru | Out-Null
Enter-PSSession -ComputerName $ComputerName -ErrorAction Stop
}
catch { return "Сonnection refused" }
}
Предсказуемо, у функции PSConnection только один принимаемый параметр — ComputerName. Просто говоришь куда хочешь подключиться и функция всё сделает за тебя. Если подключение будет невозможно — вернётся Сonnection refused.
Теперь эту функцию нужно сохранить в файл с расширением psm1. В принципе, модуль уже готов и его можно импортировать в консольную сессию PowerShell, но, как я и сказал выше, нужно автономное решение без дополнительных командлетов. Попробуем установить получившийся модуль. Кстати, для пытливых умов есть хорошая документация на эту тему.
Установка модуля, в том числе и кастомного, минуя галерею — весьма простая задача. Достаточно только получить папку с уже установленными модулями и поместить туда папку с нашим модулем, следуя внутренней иерархии. В среде PowerShell для данных целей предусмотрена отличная переменная $env:PSModulePath, которая выводит в одну строку с разделителем в виде «;» список директорий с модулями. Чтобы отмахнуться от разделителя, попробуем рассплитовать выдачу:
$env:PSModulePath -split ";"
Устанавливать модули я предпочёл в директорию:
C:\Program Files\WindowsPowerShell\Modules
Здесь нужно создать папку с именем нашего модуля и положить внутрь сам файл psm1. В принципе, установка завершена. Теперь давайте автоматизируем и эту задачу.
Для установки кастомных модулей я написал вот такую функцию:
function InstallCustomModule
{
Param(
[Parameter(Mandatory=$true)]
$ModulePath
)
$installpath = "$env:ProgramFiles\WindowsPowerShell\Modules"
$modulename = (Get-Item $ModulePath).Basename
$modulefile = (Get-Item $ModulePath).Name
try
{
New-Item -Name $modulename -Path $installpath -ItemType Directory -ErrorAction Stop -Force | Out-Null
Copy-Item -Path $ModulePath -Destination $installpath\$modulename\$modulefile -ErrorAction Stop -Force | Out-Null
return "Module $modulename installed!"
}
catch { return "Something wrong..." }
}
Которую, кстати, тоже можно запихнуть в файл psm1 и установить, как модуль.