Caminho do Módulo PowerShell: Código Reutilizável Sem Copiar e Colar

Trabalhar com módulos do PowerShell é uma peça importante da automação do PowerShell. Ao começar a aprender o PowerShell, os primeiros passos geralmente envolvem o uso de comandos individuais. Isso leva à construção de scripts, que por sua vez leva à criação de funções.

Ao usar funções, você pode tornar seus scripts mais modulares. Isso permite que você use o mesmo código em muitos lugares sem copiar e colar o código por toda parte. O uso de funções permite que você gaste menos tempo fazendo a mesma edição no mesmo código onde quer que seja usado. Em vez disso, você pode trabalhar para melhorar seu código em um único local.

Para levar as funções para o próximo nível, você pode combinar essas funções em um módulo.

A module is a collection of functions in a text file with a psm1 extension. There are some optional additions, such as a module manifest and comment-based or external help that may also be included. These will be covered later on.

Pré-requisitos

I’ll be using Windows PowerShell 5.1 in this article. If you’re using an older version or PowerShell Core, your mileage may vary as to results you see.

Interagindo com Módulos

Ao abrir uma sessão do PowerShell pela primeira vez, você começará com dois módulos. O primeiro é Microsoft.PowerShell.Utility, que contém muitas funções básicas do PowerShell que você já usa. O outro módulo é PSReadline. Você pode ver esses módulos iniciais usando o comando Get-Module.

Listing modules with Get-Module

Dito isso, esta não é uma lista completa de todos os módulos disponíveis. Desde o PowerShell 3, os módulos instalados serão importados conforme necessário. Se você estiver usando uma versão mais antiga do PowerShell, será necessário usar o comando Import-Module para primeiro importar o módulo antes de usar qualquer um dos comandos.

Há momentos em que você ainda desejará usar o Import-Module mesmo em versões posteriores. Se você quiser importar um módulo depois que ele já estiver instalado, você pode usar Import-Module assim:

Importing modules with Import-Module

Enquanto Get-Module mostrará todos os módulos que estão importados, você não verá os módulos que ainda não foram importados. Você pode então usar o parâmetro ListAvailable para mostrar todos os outros módulos disponíveis.

Listing all available modules with Get-Module -ListAvailable

Nem todos os Comandos são Mostrados por Padrão

A propriedade ExportedCommands contém uma lista de todos os comandos disponíveis que são exportados do módulo. Você pode observar algumas diferenças entre esta lista e o que está no arquivo do módulo. Comandos exportados é uma funcionalidade incorporada ao manifesto do módulo que permite ao escritor ocultar uma função. Os autores do módulo também podem usar o Export-ModuleMember cmdlet, mas isso está fora do escopo deste artigo.

Os autores do módulo podem querer ocultar uma função porque ela está destinada a dar suporte a outras funções, não ser de frente para o usuário. Para ocultar uma função, o autor a excluiria da matriz FunctionsToExport no manifesto. Aqui você pode ver uma visão expandida da propriedade ExportedCommands.

Viewing exported commands

Importando Módulos

Existem muitas maneiras de começar a usar módulos. Você pode importar manualmente o módulo usando o caminho para os arquivos do módulo. Isso permite que você teste e atualize o módulo sem ter que fazer muito trabalho. No entanto, isso não oferece muita portabilidade, pois você teria que usar o caminho exato para o módulo. O PowerShell também não importará automaticamente módulos que não estejam na variável $env:PSModulePath.

Importação Seletiva de Comandos

Você pode usar Import-Module para importar apenas funções específicas em vez do módulo inteiro, usando o parâmetro Function. Isso pode economizar tempo ao importar módulos de sistemas remotos, como os módulos do Office 365.

Todos os Módulos de Usuários

Os módulos instalados para todos os usuários são colocados em C:\Program Files\WindowsPowerShell\Modules. Este diretório contém muitos módulos pré-adicionados, incluindo quaisquer módulos instalados usando Install-Module com o escopo padrão AllUsers.

Módulos do Usuário Atual

Se você estiver instalando um módulo, mas deseja que apenas um usuário o use, existe um escopo CurrentUser. Isso coloca os arquivos do módulo na sua pasta de documentos em C:\Users\<username>\Documents\WindowsPowerShell\Modules. Isso pode ser útil em um ambiente onde você usa redirecionamento de pasta com a pasta de documentos.

Neste caso, você pode instalar um módulo em um computador e usá-lo em outro, pois ambos estariam compartilhando a mesma pasta de documentos.

Módulos do Sistema

Para completude, também há um diretório de módulos em C:\Windows\System32\WindowsPowerShell\1.0\Modules. Embora tecnicamente um módulo colocado neste caminho seja importado como um dos outros caminhos, não é recomendado, pois este é reservado para os módulos do sistema da Microsoft.

Nomear é Importante

Você pode colocar manualmente seu módulo em um desses caminhos para torná-lo disponível por padrão em uma nova sessão, mas deve garantir que siga a nomenclatura exigida para os módulos. A pasta em que os arquivos do módulo são colocados deve ter o mesmo nome do arquivo do módulo psm1 e do manifesto do módulo psd1, se houver.

Usando Get-Module -ListAvailable, que mencionamos anteriormente, faz referência a esses caminhos. Você pode ver todos os caminhos do módulo usando $env:PSModulePath -Split ';'. Você pode notar outros caminhos na lista além do que é mostrado aqui. Muitos programas adicionam seus próprios caminhos de módulo quando são instalados. Um dos exemplos disso é o SQL, que possui seus próprios módulos incluídos em seus próprios caminhos de módulo.

Viewing module paths with $env:PSModulePath

Também existem alguns módulos que você instalaria com um processo diferente. Um dos exemplos mais significativos disso é o módulo ActiveDirectory. Do Windows 7 até o Windows 10 1803, você o instalaria com o instalador das Ferramentas de Administração do Servidor Remoto (RSAT).

Nas versões mais recentes do Windows 10 (1809+), isso está disponível apenas por meio dos Recursos Sob Demanda. Instalar o RSAT instala os módulos ActiveDirectory e muitos outros que você usaria para administrar outras funções do Windows. Nos sistemas operacionais do servidor Windows, esses módulos são instalados por meio do Gerenciador do Servidor.

Importação de Módulos Remotos (Remoting Implícito)

Existem alguns casos em que não é prático ter um módulo sendo executado localmente. Em vez disso, é melhor se conectar a um dispositivo remoto e importar um módulo instalado nele. Quando você faz isso, os comandos são realmente executados na máquina remota. Isso é frequentemente usado com os módulos do Office 365 da Microsoft. Muitos deles se conectam a um servidor do Office 365 que então importa um módulo. Quando você executa qualquer um dos comandos, eles são executados no servidor remoto e depois a saída é enviada de volta para a sua sessão.

Outro uso da importação de módulos remotos é quando você não tem o módulo instalado localmente. Isso é o que aconteceria se você não tivesse o módulo ActiveDirectory instalado, mas tentasse importá-lo.

Module not installed

Para importar um módulo remoto, primeiro você precisa criar uma PSSession. Você pode usar New-PSSession para criar a sessão. Em seguida, você importaria o módulo disponível no dispositivo remoto usando o parâmetro PSSession com Import-Module.

PS51> $AdminServer = New-PSSession -ComputerName $AdminServerName -Credential (Get-Credential)
PS51> Import-Module -Name ActiveDirectory -PSSession $AdminServer -Prefix 'Rmt'

O uso deste método de importação de módulos remotos permite uma execução mais rápida do código em um ambiente distribuído. Por exemplo, se você estiver trabalhando do seu computador, mas os servidores em que está trabalhando estiverem nos Estados Unidos, pode demorar significativamente mais para executar determinados comandos localmente nos servidores. Enquanto executar os comandos em um servidor e enviar a saída de volta para sua sessão local é muito mais rápido.

Adicionando um Prefixo de Módulo

Você também pode adicionar um prefixo nas funções importadas da máquina remota. Essa opção está disponível ao importar módulos locais, mas raramente é usada fora do teste de diferentes versões de um módulo lado a lado.

Se você executasse o comando de importação acima, veria o seguinte ao examinar os comandos:

Viewing all available commands in a module

Nesse caso, você pode usar um prefixo para mostrar que não se trata de um módulo local. Isso pode ser usado em casos em que você está importando um módulo que também está disponível localmente. Adicionar o prefixo reduz a confusão sobre onde o código está sendo executado.

Removendo Módulos

Você também pode remover um módulo da sessão atual sem usar Remove-Module. Isso remove um módulo da sessão local sem excluir os arquivos do módulo. Você pode querer usar isso em um caso em que estava usando uma sessão remota para usar um módulo. Você poderia usar Remove-Module para limpar sua sessão e depois desconectar a sessão remota.

Removing a module from the session

Outro uso de Remove-Module é se você estiver fazendo alterações em um módulo e não quiser iniciar uma nova sessão do PowerShell. Nesse caso, você usaria Remove-Module seguido por Import-Module para recarregá-lo em sua sessão. Alternativamente, você pode usar o parâmetro Force com Import-Module. Isso concluirá a descarga e recarga do módulo para você.

O Que Compõe um Módulo do PowerShell

A module can consist of one or more files. To meet the minimum requirements for a module, you must have a module file. This can be a PSM1 file or any other module file such as a binary module file. To build upon that, your psm1 should have functions defined in it, or it will not be much use to anyone.

Embora não haja requisitos sobre como as funções devem parecer ou o que devem fazer, existem algumas diretrizes. Geralmente, é preferível ter todas as funções em um módulo construído em torno do mesmo conceito.

Módulos Contêm Funções de Mesmo Interesse

Por exemplo, o módulo ActiveDirectory inclui apenas funções que interagem de alguma forma com o Active Directory. Geralmente, os nomes das funções também contêm um prefixo. Voltando ao módulo ActiveDirectory como exemplo, todos os substantivos nos nomes das funções começam com AD.

Seguir essas diretrizes ajuda na descoberta das funções. Imagine que você acabou de importar este novo módulo e deseja percorrer as funções. Isso é muito mais fácil de fazer se todas as funções tiverem uma estrutura de nome semelhante. Embora você possa frequentemente ver módulos começando com PS, esse prefixo é oficialmente reservado apenas para os módulos da Microsoft. Provavelmente, você não causará problemas se usar PS no início do seu módulo, mas pode criar um conflito com o nome de outro módulo.

Seguindo essas diretrizes, se você tiver um monte de funções que tenham a ver com interagir com o registro, você poderia ter algo como:

function Get-ATARegistryKey {...}

function Set-ATARegistryKey {...}

Manifestos de Módulos

Para complementar o arquivo de texto do módulo, você também pode incluir um manifesto de módulo. Esses arquivos têm uma extensão PSD1 e contêm metadados sobre o módulo. Aqui é onde você incluiria informações sobre o autor, descrição do módulo, outros módulos necessários e muitos outros atributos. Para publicar em um repositório, é necessário ter os campos Author e Description preenchidos.

Aqui está um exemplo de manifesto que podemos ter para nosso módulo de registro:

#Manifesto do módulo para 'ATARegistry'
#Gerado por: Tyler
#Gerado em: 11/08/2019
@{
	#Módulo de script ou arquivo de módulo binário associado a este manifesto.
	RootModule = 'ATARegistry'
	#Número da versão deste módulo.
	ModuleVersion = '1.0'
	#Edições PSEditions suportadas
	#CompatiblePSEditions = @()
	#ID usado para identificar exclusivamente este módulo
	GUID = 'fef619fa-016d-4b11-a09d-b222e094de3e'
	#Autor deste módulo
	Author = 'Tyler Muir'
	#Empresa ou fornecedor deste módulo
	CompanyName = 'Adam the Automator'
	#Declaração de direitos autorais para este módulo
	Copyright = '(c) 2019 tyler. All rights reserved.'
	#Descrição da funcionalidade fornecida por este módulo
	Description = 'This is a test module.'
	#Versão mínima do mecanismo do Windows PowerShell exigida por este módulo
	#PowerShellVersion = ''
	#Nome do host do Windows PowerShell exigido por este módulo
	#PowerShellHostName = ''
	#Versão mínima do host do Windows PowerShell exigida por este módulo
	#PowerShellHostVersion = ''
	#Versão mínima do Microsoft .NET Framework exigida por este módulo. Este requisito é válido apenas para a edição PowerShell Desktop.
	#DotNetFrameworkVersion = ''
	#Versão mínima do tempo de execução de linguagem comum (CLR) exigida por este módulo. Este requisito é válido apenas para a edição PowerShell Desktop.
	#CLRVersion = ''
	#Arquitetura do processador (Nenhum, X86, Amd64) exigida por este módulo
	#ProcessorArchitecture = ''
	#Módulos que devem ser importados para o ambiente global antes de importar este módulo
	#RequiredModules = @()
	#Assemblies que devem ser carregadas antes de importar este módulo
	#RequiredAssemblies = @()
	#Arquivos de script (.ps1) que são executados no ambiente do chamador antes de importar este módulo.
	#ScriptsToProcess = @()
	#Arquivos de tipo (.ps1xml) a serem carregados ao importar este módulo
	#TypesToProcess = @()
	#Arquivos de formato (.ps1xml) a serem carregados ao importar este módulo
	#FormatsToProcess = @()
	#Módulos para importar como módulos aninhados do módulo especificado em RootModule/ModuleToProcess
	#NestedModules = @()
	#Funções para exportar deste módulo, para melhor desempenho, não use curingas e não exclua a entrada, use uma matriz vazia se não houver funções para exportar.
	FunctionsToExport = @('Get-RegistryKey','Set-RegistryKey')
	#Cmdlets para exportar deste módulo, para melhor desempenho, não use curingas e não exclua a entrada, use uma matriz vazia se não houver cmdlets para exportar.
	CmdletsToExport = @()
	#Variáveis para exportar deste móduloVariablesToExport = '*'
	#Aliases para exportar deste módulo, para melhor desempenho, não use curingas e não exclua a entrada, use uma matriz vazia se não houver aliases para exportar.
	AliasesToExport = @()
	#Recursos DSC para exportar deste módulo
	#DscResourcesToExport = @()
	#Lista de todos os módulos empacotados com este módulo
	#ModuleList = @()
	#Lista de todos os arquivos empacotados com este módulo
	#FileList = @()
	#Dados privados a serem passados para o módulo especificado em RootModule/ModuleToProcess. Isso também pode conter um hashtable PSData com metadados adicionais do módulo usados ​​pelo PowerShell.
	PrivateData = @{
		PSData = @{
			#Tags aplicadas a este módulo. Isso ajuda na descoberta de módulos em galerias online.
			#Tags = @()
			#URL para a licença deste módulo.
			#LicenseUri = ''
			#URL para o site principal deste projeto.
			#ProjectUri = ''
			#URL para um ícone que representa este módulo.
			#IconUri = ''
			#Notas de lançamento deste módulo
			#ReleaseNotes = ''
		} 
		#Fim do hashtable PSData
	} 
	#Fim do hashtable PrivateData
	#URI HelpInfo deste módulo
	#HelpInfoURI = ''
	#Prefixo padrão para comandos exportados deste módulo. Substitua o prefixo padrão usando Import-Module -Prefix.
	#DefaultCommandPrefix = ''
}

Embora isso possa parecer intimidante à primeira vista, a Microsoft tem um cmdlet útil que você pode usar para gerar um manifesto de módulo. O comando incluído é `New-ModuleManifest`. Para gerar o manifesto mostrado acima, você poderia usar:

PS51> New-ModuleManifest -Path .\Scripts\TestModule.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule 'TestModule.psm1' -FunctionsToExport @('Get-RegistryKey','Set-RegistryKey') -Description 'This is a test module.'

Arquivos de Ajuda Externa

Você também pode encontrar arquivos de ajuda externos em alguns módulos. Eles podem ser identificados pelo <NomeDoMódulo>-Ajuda.xml no final do nome do arquivo. Esses arquivos de ajuda externos contêm as mesmas informações que normalmente estariam contidas na ajuda baseada em comando que você pode encontrar em uma definição de função.

Isso também exigiria que você adicionasse `# .ExternalHelp <CaminhoDoMódulo>-Ajuda.xml` à sua função para que ela funcione corretamente ao usar o comando `Get-Help` após importar o módulo. Geralmente, só é comum ver arquivos de ajuda externos em módulos muito grandes e, devido a isso, eles estão fora do escopo.

Embora esses sejam os tipos de arquivos mais comuns que você verá em um módulo, esses não são os únicos arquivos. Às vezes, você verá arquivos binários além de um módulo de texto, pois existem outras dependências. Ao explorar pelos caminhos do módulo, você pode encontrar muitos exemplos de tipos de arquivo adicionais em módulos.

Para publicar corretamente arquivos de módulo não padrão, você incluiria outros arquivos no parâmetro `FileList` em seu manifesto de módulo.

Dentro do manifesto do módulo, você notará muitos outros parâmetros que estão atualmente vazios. Você pode usar esses para definir outros requisitos para usar seu módulo. Por exemplo, você pode definir as versões do PowerShell com as quais o módulo pode funcionar. Se você tentar importar o módulo em uma versão não suportada do PowerShell, é isso que você veria:

Requiring certain versions of PowerShell

PSRepositories

Uma das principais opções de distribuição para módulos é um PSRepository . Em uma visão geral, um PSRepository é um local onde várias pessoas ou vários dispositivos podem acessar os arquivos do módulo. Estes são frequentemente servidores web onde você pode publicar arquivos.

Você também pode usar um diretório para o repositório, mas isso limita você na funcionalidade do seu repositório. Você pode hospedar um PSRepository você mesmo, ou pode utilizar uma das muitas opções disponíveis na internet como o PowerShell Gallery. Você pode ver seus PSRepositories usando o comando Get-PSRepository .

Default PowerShell NuGet repositories

Por padrão, você terá apenas uma entrada e será para o PowerShell Gallery. Você pode notar que ele dirá que não é confiável. Isso ocorre porque o PowerShell o alerta que ao usar o PowerShell Gallery, você pode estar usando código não escrito e aprovado pela Microsoft. Isso significa que antes que quaisquer módulos sejam instalados a partir dele, você terá que dar permissão explícita.

Adicionando PSRepositories

Você também pode adicionar seus próprios repositórios. Para confiar no PowerShell Gallery, você pode executar Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trusted ou você pode aceitar o aviso na primeira vez que instalar um módulo do PowerShell Gallery.

Todos os comandos que você usaria para interagir com esses PSRepositories podem ser encontrados no módulo PowerShellGet. Você pode ver as funções aqui:

Commands in the PowerShellGet module

O módulo PowerShellGet pode precisar ser atualizado antes de interagir com certos repositórios.

Localizando Módulos

Outra característica importante ao usar um PSRepository é a capacidade de procurar por módulos. Isso é feito usando o comando Find-Module. Existem várias maneiras de filtrar e encontrar exatamente o que você procura, mas por enquanto, você pode procurar pelos módulos VMware assim:

Finding modules on the PowerShell Gallery

Isso mostrará todos os módulos que começam com VMware. Embora a maioria deles seja da VMware, é necessário verificar o atributo do autor para ver quem publicou o módulo.

Como qualquer pessoa pode fazer upload para o PowerShell Gallery, existem milhares de módulos disponíveis. Isso significa que você pode encontrar módulos que não funcionam adequadamente para o seu caso de uso. Muitos módulos que você encontrará são de código aberto, então você pode contribuir para melhorar a funcionalidade do módulo.

Instalando Módulos

Para usar o comando Install-Module, você precisa ter um PSRepository confiável que esteja hospedando o módulo. Isso pode ser o PowerShell Gallery, outro PSRepository na internet ou um site auto-hospedado. Você pode encadear a partir do comando Find-Module para confirmar facilmente o módulo antes de instalá-lo.

Finding modules installed from a PSRepository

Você também pode definir a versão de um módulo usando os parâmetros MinimumVersion, MaximumVersion ou RequiredVersion.

Para ver todos os módulos instalados usando Install-Module, você pode usar Get-InstalledModule. Isso listará todos os módulos instalados no escopo AllUsers ou no seu escopo CurrentUser.

Desinstalando Módulos

Assim como você pode instalar um módulo, também pode desinstalá-lo. Se o módulo não foi instalado via comando Install-Module, você não poderá desinstalá-lo com o comando Uninstall-Module.

Uninstalling modules installed from a PSRepository with Uninstall-Module

Como você pode ver aqui, estamos tentando desinstalar o módulo ActiveDirectory. Como este módulo não foi instalado com Install-Module, você receberia um erro ao tentar usar Uninstall-Module. Para desinstalar este módulo, seria necessário desfazer o que você usou para instalá-lo.

Para ver uma desinstalação bem-sucedida de um módulo, você pode desinstalar o módulo VMware.PowerCLI que você instalou anteriormente.

Uninstalling a module downloaded from the PowerShell Gallery

Mesmo que você tenha desinstalado VMware.PowerCLI, você pode ver que ainda há muitas dependências instaladas. Se você quisesse desinstalar todos os módulos, poderíamos usar Get-InstalledModule VMware.* | Uninstall-Module -Force.

A razão pela qual você teria dificuldades em desinstalar completamente este módulo é porque ele tem tantas dependências. Além disso, alguns desses módulos são dependentes entre si, o que é por que o parâmetro Force seria necessário.

Atualizando Módulos

Agora que você sabe como instalar e desinstalar um módulo, pode estar se perguntando como atualizar um módulo que você instalou.

Assim como em outros processos, se o módulo não foi instalado usando Install-Module, você não pode atualizá-lo usando comandos do PowerShell. Você pode usar Update-Module para atualizar um módulo para a versão mais recente ou para uma versão específica mais recente.

Há também um interruptor para AllowPreRelease, que permite a atualização para uma versão que ainda não foi oficialmente lançada. Às vezes, isso pode ser útil, pois pode haver uma correção para um bug que você está enfrentando ou um novo recurso que foi adicionado e que você gostaria de usar.

Updating modules with Update-Module

Inspeção/Salvamento de um Módulo

Um dos comandos menos utilizados, mas muito úteis ao avaliar módulos antes de usá-los, é o Save-Module. Usando esse comando, você pode baixar um módulo para um caminho sem instalá-lo.

Você pode então inspecionar os arquivos e, se o módulo não for um módulo binário, pode abri-lo e examinar o código que compõe o módulo. Isso não apenas ajuda a garantir que um módulo não esteja fazendo nada malicioso, mas também a aprender como os outros estruturam seus módulos.

Downloading modules with Save-Module

Neste exemplo, não apenas o módulo VMware.PowerCLI é baixado, mas também todas as dependências. Aqui está o que aparece na pasta VMware.PowerCLI:

VMware.PowerCLI module contents

Este é um bom exemplo de como às vezes existem arquivos de módulos não padrão incluídos no módulo, como o contrato de licença do usuário final.

Escrevendo seu Próprio Módulo

Agora você viu como interagir com o módulo de outra pessoa. Agora você quer aprender como criar o seu próprio para começar a otimizar seu código para escalabilidade.

Criar Arquivos de Modelo

Primeiro, você precisa criar uma pasta para todos os arquivos do seu módulo. Depois de ter o contêiner, você precisa criar o arquivo do seu módulo. Você precisa garantir que o arquivo do seu módulo tenha o mesmo nome que sua pasta, caso contrário, ao tentar publicar seu módulo, o PowerShell não irá descobrir o módulo corretamente.

PS51> New-Item -Path .\Scripts -Name ATARegistry -ItemType Directory
PS51> New-Item -Path .\Scripts\ATARegistry -Name ATARegistry.psm1

Agora você também deseja usar um manifesto, você precisará também nomeá-lo igual ao contêiner e ao arquivo do módulo.

PS51> New-ModuleManifest -Path .\Scripts\ATARegistry\ATARegistry.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule ATARegistry.psm1 -Description 'Used for interacting with registry keys'

Com o contêiner, arquivo do módulo e arquivo de manifesto, você tem um módulo totalmente funcional. Você poderia publicar este módulo em um PSRepository e começar a instalá-lo onde quiser. Embora o arquivo do módulo esteja vazio, provavelmente não será muito útil. Ainda assim, você pode usar esses arquivos para testar a publicação e garantir que seu repositório funcione.

Registrando um PSRepository

Antes de poder publicar seu módulo, você precisará adicionar outro PSRepository à sua sessão. Para testar, você pode usar um caminho local como seu PSRepository, já que será fácil de configurar e desativar.

Normalmente, se você fosse configurar um PSRepository com um diretório, você iria querer garantir que vários computadores possam acessá-lo. Você pode criar um repositório local assim:

PS51> New-Item -Path C:\ -Name Repo -ItemType Directory
PS51> Register-PSRepository -Name 'LocalRepo' -SourceLocation 'C:\Repo' -PublishLocation 'C:\Repo' -InstallationPolicy Trusted

Se você só estiver baixando do PSRepository e nunca publicando, poderia excluir o parâmetro PublishLocation.

Publicando seu Módulo

Desde que você já definiu a política de instalação como confiável, não receberá uma confirmação para permitir a instalação de um módulo do repositório. Agora que você possui um novo PSRepository disponível, pode publicar seu módulo usando Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

Após publicar seu módulo, você pode usar os comandos acima para encontrar o módulo e instalá-lo.

Agora que você instalou o módulo, pode usar Get-Module para ver o módulo importado em sua sessão local. Como você não adicionou nenhuma função à matriz FunctionsToExport no manifesto, a propriedade ExportedCommands está vazia.

No exported commands

Adicionando ao seu Módulo

Agora que você sabe que pode publicar e instalar seu módulo, pode começar a adicionar alguma funcionalidade a ele. Você poderia adicionar uma função para retornar uma chave de registro, então ficaria assim:

function Get-ATARegistryKey {
    param (
        [string]$Path
    )
    Get-Item $Path
}

Se deixasse o manifesto como está e tentasse enviar seu novo módulo, você enfrentaria dois problemas. O primeiro é que receberia um erro indicando que a versão do seu módulo já existe no seu repositório. Isso ocorre porque você não alterou a versão do módulo no arquivo manifesto.

Exportando Funções do Módulo

O outro problema seria que, depois de importar o módulo, você ainda não veria funções na propriedade ExportedCommands porque não adicionou sua nova função ao manifesto.

Embora sua função possa ser usada sem listá-la na lista FunctionsToExport, tornaria muito mais difícil localizá-la.

Contanto que você não defina um array vazio, @(), para suas FunctionsToExport, todas as funções, variáveis e aliases são exportados por padrão.

Para corrigir esses dois problemas, você pode atualizar o arquivo do seu módulo assim:

ModuleVersion = '1.1'
FunctionsToExport = 'Get-RegistryKey'

Agora que você adicionou uma função ao seu módulo e atualizou seu manifesto para refletir essas alterações, você pode publicar a nova versão do seu módulo usando o mesmo comando de antes.

PS51> Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

Decidindo entre FunctionsToExport e Export-ModuleMember

Há dois recursos semelhantes no PowerShell ao exportar membros do módulo. O desafio é decidir entre os dois. Ambos estão corretos, mas um pode funcionar melhor para você, dependendo das suas necessidades.

Quando você deseja controlar dinamicamente quais funções são exportadas, use Export-ModuleMember, pois você pode passar uma lista de funções para exportar. Normalmente, isso é usado ao carregar vários arquivos PS1 de função individual por ponto. Ao dividir as funções internas em uma pasta privada e as funções exportáveis em uma pasta pública, você pode facilmente exportá-las passando todas as funções públicas para a função Export-ModuleMember.

A few notes about Export-ModuleMember:

  • Substitui o comportamento de FunctionsToExport, portanto, se um comando Export-ModuleMember for usado, FunctionsToExport não terá efeito.
  • Export-ModuleMember não exporta variáveis e aliases sem definição explícita, ao contrário de FunctionsToExport, que exporta esses valores.
  • Múltiplos comandos Export-ModuleMember podem ser usados e se acumulam em vez de ter precedência.

Se você não espera ter alterações na lista de funções, usar a configuração FunctionsToExport no manifesto do módulo funciona bem e não exige que você exporte explicitamente variáveis e aliases.

Atualizando seu Módulo

O último passo seria atualizar seu módulo em sua sessão para poder usar os arquivos atualizados. Usando Update-Module ATARegistry, você baixa a atualização que acabou de publicar no repositório.

Exported commands now show up

Agora você pode ver que tem a nova versão do módulo e pode ver a função que definiu no manifesto.

Construindo Conteúdo de Ajuda

Uma das opções que foi mencionada anteriormente é o sistema de ajuda incorporado ao PowerShell. Em algum momento, você provavelmente usou o Get-Help em uma função. Essas informações podem ser adicionadas de duas maneiras principais.

A primeira é adicionar ajuda baseada em comentários à definição da função. Geralmente, é assim que muitos escritores de módulos implementam. A outra maneira é usar um arquivo de ajuda externo. Você pode usar o parâmetro Full para mostrar tudo o que a ajuda tem a oferecer.

Finding help with Get-Help

Como você pode ver, realmente não há muitas informações, e as poucas informações que você obtém provavelmente não seriam úteis para ninguém.

Você pode adicionar alguma ajuda baseada em comentários ao seu arquivo de módulo para preencher esses campos no sistema de ajuda. Você pode ler sobre todas as opções para ajuda baseada em comentários usando o Get-Help about_Comment_Based_Help.

Por enquanto, você pode atualizar sua função para ficar assim. Esta é uma lista dos parâmetros de ajuda mais comumente usados, mas todos eles ainda são opcionais e há outros que poderiam ser adicionados em vez disso.

Agora sua função fica assim:

 function Get-RegistryKey {
	<#
    .SYNOPSIS
    Retorna a chave do registro usando o caminho fornecido.
    .DESCRIPTION
    A função usa o comando Get-Item para retornar as informações de uma chave do registro fornecida.
    .PARAMETER Path
    O caminho que será pesquisado em busca de uma chave do registro.
    .EXAMPLE
    Get-RegistryKey -Path 'HKLM:\HARDWARE\DESCRIPTION\System'
    .INPUTS
    System.String
    .OUTPUTS
    Microsoft.Win32.RegistryKey
    .NOTES
    Este módulo é um exemplo de como uma função bem documentada pode ser.
    .LINK
    
ATA Learning
#>
param( [string]$Path ) Get-Item $Path }

Há alguns parâmetros de ajuda especiais, como .FORWARDHELPTARGETNAME. Essa opção encaminha todas as solicitações de ajuda recebidas para um comando diferente. Isso pode ser usado no caso em que a ajuda deve mostrar as mesmas informações para vários comandos.

Agora que você adicionou a ajuda, pode atualizar a versão no manifesto do módulo, publicar a nova versão e atualizar a versão instalada para sua sessão, como fez anteriormente.

Se você agora olhar a ajuda para a função, poderá ver que há muito mais informações disponíveis. Esta é uma ótima maneira de incluir documentação sobre como usar as funções, especialmente para alguém que tem menos experiência e pode não ser capaz de entender rapidamente o que o módulo está fazendo ao olhar para o código.

Getting full help content with Get-Help

No caso de um arquivo de ajuda externa, as informações adicionadas são as mesmas, mas são colocadas em um arquivo separado e vinculadas dentro da função.

Se você olhar no caminho do módulo AllUsers, poderá ver a versão do módulo e todos os arquivos do módulo que você instalou.

Folder name is the module version

Se voltar ao seu caminho PSRepository C:\Repo que você criou anteriormente, poderá ver um monte de arquivos NUPKG. Haverá um para cada versão que foi publicada. Essas são versões compactadas do que você publicou ao usar Publish-Module.

Resumo

Depois de se familiarizar com o console do PowerShell, PowerShell como linguagem e escrever scripts, construir seus próprios módulos é o último passo. Módulos permitem que você comece a desenvolver ferramentas úteis no PowerShell. Se projetados e construídos corretamente, criando módulos para um único propósito, você inevitavelmente se encontrará escrevendo menos e menos código com o tempo. Você começará a referenciar as funções do seu módulo em mais código e construir a partir daí.

Funções de módulo permitem que você abstraia o código que se repete em scripts. Elas representam “rótulos” para serem referenciados posteriormente no código, que podem ser chamados a qualquer momento, em vez de reinventar a roda e tentar descobrir como você já havia alcançado seu objetivo anteriormente. Módulos são a “embalagem” final do código PowerShell que agrupa código semelhante para evitar perder tempo com problemas que você já resolveu.

Source:
https://adamtheautomator.com/powershell-modules/