Private/Wissen/C_Advance/C10_UserModules.ps1
<#
# User Module Eigene Module erstellen - **Hashtags** Module Repository Deployment PowerShellGallery - **Version** 2020.10.15 #> #region Vorbereitung # 1. Installationsort des Moduls festlegen (möglich sind: $env:PSModulePath -split ';') $destinationModulePath = Join-Path -Path $env:USERPROFILE -ChildPath '\OneDrive\Documents\WindowsPowerShell\Modules' # 2. Test-Cmdlet erzeugen @' function Get-Hello { param ([string]$Name = 'Du') "Hello $Name!" | Write-Output } '@ | Set-Content -Path 'C:\Temp\Get-Hello.ps1' # 3. OPTIONAL Ein Zertifikat zum signieren auswählen $cert = Get-ChildItem -Path 'C:\Temp\MyCodeSigningCert.pfx' | Get-PfxCertificate Set-AuthenticodeSignature -FilePath 'C:\Temp\Get-Hello.ps1' -Certificate $cert #endregion #region Module erstellen # ! 1. Jedes Module benötigt einen "eindeutigen" Namen: $moduleName = 'ABC' # ! 2. Für das neue Module den Modul-Ordner erstellen $destinationModulePath = Join-Path -Path $destinationModulePath -ChildPath $moduleName New-Item -Path $destinationModulePath -ItemType 'Directory' -Force Set-Location -Path $destinationModulePath New-Item -Path $destinationModulePath -Name 'Public' -ItemType Directory # ! Öffentlicher Teil des Module New-Item -Path $destinationModulePath -Name 'Private' -ItemType Directory # ! Interner Teil des Module, z.B. Hilfs-Funktion New-Item -Path $destinationModulePath -Name 'de-DE' -ItemType Directory # ! Sprach-Land-Bezogene Inhalte (weitere z.B. en-US, jp-JP, usw.) # ! 3. Eigene Cmdlets in den Modulordner kopieren Copy-Item -Path 'C:\Temp\Get-Hello.ps1' -Destination '.\Public\' -Force -Verbose # ! 4. .PSM1-Datei erstellen # ! Der darin enthaltene Code wird ausgeführt, wenn das Modul importiert wird. New-Item -Path .\$moduleName.psm1 -ItemType File -Force @' Get-ChildItem "$PSScriptRoot\Public\*.ps1" | ForEach-Object { . $_.FullName } '@ | Add-Content .\$moduleName.psm1 # ! OPTIONAL: Fügen Sie folgenden Code der .PSM1-Datei hinzu, um einen Ereignis-Handler für das # ! Entladen des Moduls hinzuzufügen. @' $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { 'Module wurde entladen.' | Write-Warning # TODO: Code z.B. zum Aufräumen bei entladen dieses Modules. } '@ | Add-Content -Path .\$moduleName.psm1 # ! OPTIONAL: PSM1-Datei signieren Set-AuthenticodeSignature -FilePath .\$moduleName.psm1 -Certificate $cert # ? Inhalt der .PSM1-Datei anzeigen Start-Process -FilePath .\$moduleName.psm1 # TODO Inhalt korrekt bzw. ergänzen # ! 5. .PSD1-Datei erstellen (Manifest-Informationen über das neue Modul) $params = @{ Path = ".\$moduleName.psd1" RootModule = $moduleName Guid = '38ed2cd7-d6ae-44fe-bb28-7a8a21247dfe' # Eine eindeutig GUID die das Modul ein lebenlang behält # TODO eine neue GUID erzeugen über: New-Guid Author = 'VORNAME NACHNAME' CompanyName = 'DIE FIRMA' Copyright = '(c) 2019 by DIE FIRMA' Description = 'Test-Module aus der PowerShell-Schulung - Aufbaukurs' ModuleVersion = [Version]::new(2020, 1, 30, 1109) # ! major.minor.build.revision => major.minor (Neue Feature), build (Bugfixing), revision (Ausroll-Varianten) CmdletsToExport = Get-ChildItem -Path '.\Public\*-*.ps1' | Select-Object -ExpandProperty 'BaseName' } New-ModuleManifest @params # TODO Die .psd1-Datei kann auch komfortabel per TXT-Editor bearbeitet werden: Start-Process -FilePath .\$moduleName.psd1 -Wait # TODO Inhalt korrekt bzw. ergänzen #endregion #region Erstelltes Module testen # ? Wird das Module in der Liste der installierten Module angezeigt: Get-Module -Name $moduleName -ListAvailable # ? Lässt sich das Modul manuell importiert? Remove-Module -Name $moduleName -Force -ErrorAction Ignore Import-Module -Name $moduleName -Verbose -Force Get-Module -Name $moduleName # ? Wird das Modul entladen? Remove-Module -Name $moduleName Get-Module -Name $moduleName # ? Werden alle Cmdlets, Aliase, Funktionen etc. aufgelistet? Get-Command -Module $moduleName -All # ? Können die Modul-Features genutzt werden? Get-Hello -Name 'Attila' # ? ABC-Module in Show-Command nutzbar? Show-Command -NoCommonParameter -ErrorPopup #region Pester-UTest zum Module ABC # Pester 5.1.0 # Abc.Tests.ps1 $AbcModulePath = Join-Path -Path $env:USERPROFILE -ChildPath '\OneDrive\Documents\WindowsPowerShell\Modules\ABC' Describe 'Modul ABC Test' { Context 'Ordner- und Datei-Struktur testen' { It 'Modul-Ordner heißt ABC und ist vorhanden' { Test-Path -Path $AbcModulePath | Should -Be $true } It '.PSD1-Dateiname heißt ABC.psd1' { Test-Path -Path "$AbcModulePath\ABC.psd1" | Should -Be $true } It '.PSM1-Dateiname heißt ABC.psd1' { Test-Path -Path "$AbcModulePath\ABC.psm1" | Should -Be $true } } Context 'Enthaltene Cmdlets testen' { It 'Das Module ABC enthält das Skript Get-Hello.ps1' { Test-Path -Path "$AbcModulePath\Public\Get-Hello.ps1" | Should -Be $true } } Context 'Modul-Manifest-Datei validieren' { It 'Manifest frei von Exceptions' { { $Script:Manifest = Test-ModuleManifest -Path "$AbcModulePath\ABC.psd1" -ErrorAction 'Stop' -WarningAction 'SilentlyContinue' } | Should -Not -Throw } It 'Manifest Name ist ABC' { $Script:Manifest.Name | Should -Be 'ABC' } It 'Manifest Version ist vom Typ [Version]' { $Script:Manifest.Version -as [Version] | Should -Not -BeNullOrEmpty } It 'Manifest Beschreibung gesetzt' { $Script:Manifest.Description | Should -Not -BeNullOrEmpty } It 'Manifest Root-Name ist ABC' { $Script:Manifest.RootModule | Should -Be 'ABC' } It 'Manifest GUID korrekt' { $Script:Manifest.Guid | Should -Be '38ed2cd7-d6ae-44fe-bb28-7a8a21247dfe' } It 'No Format File' { $Script:Manifest.ExportedFormatFiles | Should -BeNullOrEmpty } } Context 'Funktionstest' { It 'Modul in der Liste der installierten Module enthalten' { Get-Module -Name ABC -ListAvailable | Should -Not -BeNullOrEmpty} } } #endregion #endregion #region Ein privates Repository einrichten # ! Denkbar über bereits vorhandene Repositories wie z.B. Artefactory, Nexus, etc.) # ! Oder über eine Dateifreigabe (Modul-Autoren R/W-, Nutzer R-Rechte): # ? Repository erstellen New-Item -Path 'C:\Temp' -Name 'AbcGallery' -ItemType 'Directory' New-SmbShare -Name 'AbcGallery' -Path 'c:\temp\AbcGallery' -ReadAccess 'Benutzer' -FullAccess 'Administratoren' Register-PSRepository -Name 'AbcGallery' -SourceLocation '\\localhost\AbcGallery' -InstallationPolicy 'Trusted' -Verbose # TODO per GPO verteilen Get-PSRepository # ? Modul veröffentlichen Publish-Module -Name '..\ABC' -Repository 'AbcGallery' -Verbose # ? Modul installieren Find-Module -Name 'ABC' -Repository 'AbcGallery' -AllVersions -AllowPrerelease Install-Module -Name 'ABC' -Repository 'AbcGallery' -Scope CurrentUser -AllowClobber # ? Repository wieder löschen Uninstall-Module -Name 'ABC' -Force Unregister-PSRepository -Name 'AbcGallery' Remove-SmbShare -Name 'AbcGallery' -Force Remove-Item -Path 'c:\temp\AbcGallery' -Recurse -Force #endregion #region Ein eigenes Module in die https://www.powershellgallery.com veröffentlichen # ! 1. Folgende Pakete, Module und Dateien aktualisieren (ADMIN-Rechte): Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force Invoke-WebRequest -Uri https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -OutFile '$env:LocalAppData\Microsoft\Windows\PowerShell\PowerShellGet\NuGet.exe' Unblock-File -Path '$env:LocalAppData\Microsoft\Windows\PowerShell\PowerShellGet\NuGet.exe' Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force Install-Module –Name PowerShellGet –Force Update-Module –Name PowerShellGet Remove-Module -Name * -Force # ! 2. Den Deploy-Vorgang zuerst in einem privaten Repository testen New-Item -Path 'C:\Temp' -Name 'AbcRepository' -ItemType 'Directory' New-SmbShare -Name 'AbcRepository' -Path 'c:\temp\AbcRepository' -ReadAccess 'Benutzer' -FullAccess 'Administratoren' Register-PSRepository -Name 'AbcRepository' -SourceLocation '\\localhost\AbcRepository' -InstallationPolicy 'Trusted' -Verbose Publish-Module -Name '.\AKPT' -Repository 'AbcRepository' -Verbose Find-Module -Name 'AKPT' -Repository 'AbcRepository' | Select-Object -Property Name, Version, Description, Author, CompanyName, Copyright, ProjectUri, Tags, Dependencies, ReleaseNotes Install-Module -Name 'ABC' -Repository 'AbcRepository' -Scope CurrentUser Uninstall-Module -Name 'ABC' -Force Remove-SmbShare -Name 'AbcRepository' -Force Remove-Item -Path 'c:\temp\AbcRepository' -Recurse -Force # ! 3. Module in der PowerShellGallery veröffentlichen Publish-Module -Name '.\..\AKPT' -NuGetApiKey 'oy2akrjabrpzqk6ltolalx6uipdgdq7e3gaxuesvfhwwwi' -Repository 'PSGallery-Alternative' -Verbose #endregion #region Übungen <# TODO Übung 1 (User Module) 1. Erweitern Sie das Modul ABC um das folgende Cmdlet: function Get-About() { Get-Help -Name 'about_*' | Out-GridView -OutputMode Multiple -Title 'About-Seite(n) auswählen' | Get-Help -ShowWindow } 2. Testen Sie ihre ABC-Modul-Erweiterung. 3. OPTIONAL, um die Schritte 1. und 2. nachvollziehen zu können, implementieren Sie Ihre Lösung per PowerShell-Code. #> #endregion |