Skip to the main content.

ScriptRunner Blog

So erstellen Sie Ihr erstes PowerShell-Modul

Inhaltsverzeichnis

Post Featured Image

Bereits in der PowerShell-Kernsprache gibt es eine Vielzahl leistungsstarker Cmdlets. Die nativen Funktionen bringen Sie jedoch nur begrenzt weit, und für die meisten Projekte werden Sie mehr Funktionalität benötigen. Die PowerShell Gallery bietet eine große Auswahl an downloadbaren Modulen von Drittanbietern. Es gibt aber auch die Möglichkeit, benutzerdefinierte PowerShell-Module zu erstellen.

Dieser Artikel führt Sie durch den Erstellungsprozess Ihres ersten PowerShell-Moduls.

Was ist ein PowerShell-Modul?

Im einfachsten Fall besteht ein PowerShell-Modul aus zwei obligatorischen und einer optionalen Komponente. Diese Komponenten sind die Mindestbestandteile eines PowerShell-Moduls.

  • psd1 Datei – PowerShell-Definitionsdatei
  • psm1 Datei – PowerShell-Modul-Ladedatei
  • Funktionen

Es gibt zwei Arten von Modulen, Script-Module und binäre Module. In diesem Beispiel bauen wir ein Script-Modul.
Eine Scriptfunktion, die aus traditionellen PowerShell-Funktionen besteht, ist leicht zu erstellen. Ein binäres Modul ist eine mit dem .NET-Framework kompilierte Baugruppe. Cmdlets, die in .NET geschrieben sind, sind nicht so zugänglich wie Script-Module.

Im ersten Schritt müssen wir den Zweck des PowerShell-Moduls definieren. Nicht alle Aspekte eines Moduls müssen vor Beginn abgebildet werden, jedoch macht das Erstellen eines klaren Plans die Definition der erforderlichen Funktionen viel einfacher.

 

Zweck des PowerShell-Moduls definieren

Die Erstellung eines PowerShell-Moduls an sich ist nicht schwierig, die Strukturierung der exponierten Funktionalität kann es aber schon sein. Der Zweck dieses Artikels besteht darin, ein einfaches Modul mit drei Funktionen zu erstellen.

Oft enthalten Module Funktionen, die sich auf ein einzelnes Produkt oder Werkzeug beziehen. Die Funktionen in unserem Modul zielen auf drei verschiedene Produkte ab, unterstützen aber einen bestimmten Workflow. Der Workflow besteht darin, SharePoint-Teilnehmer abzurufen, einen Onboarding-Flow auszulösen und schließlich die Mitglieder der SharePoint-Gruppe in einer Team-Nachricht zu senden.

  • New-TeamsMessage
  • Invoke-PowerAutomateFlow
  • Get-SharePointMember

 

Struktur eines PowerShell-Moduls

Die Struktur des Moduls ist ziemlich einfach. Der Ordner und das Datei-Layout sind wie unten beschrieben. Sie fragen sich vielleicht, warum wir der Funktionsdatei „func_“ voranstellen.

Dies ist einzig und allein eine persönliche Vorliebe und nicht notwendig. Dieses Vorgehen ist nützlich, um fehlerhafte Scripte in den Verzeichnissen des Moduls zu vermeiden. Sie werden in der Ladedatei des Moduls sehen, wie man diese Technik verwendet.

Public

  • func_New-TeamsMessage.ps1
  • func_Invoke-PowerAutomateFlow.ps1
  • func_Get-SharePointMember.ps1

Private-Empty

  • UtilityModule.psd1
  • UtilityModule.psm1

Erstellung des PowerShell-Moduls

Der schnellste Weg, eine PowerShell-Definitionsdatei zu erstellen, ist der Befehl New-ModuleManifest. Im Folgenden definieren wir eine Handvoll Parameter, mit denen ein verwendbares Modul erstellt wird. CompatiblePSEditions definiert sowohl Desktop als auch Core als unterstützte PowerShell-Versionen. Die Befehlssuche funktioniert, wenn Sie den FunctionsToExport-Parameter auffüllen.

$Params = @{ 
		"Path" 				= 'D:\WorkingFolder\Articles\UtilityModule.psd1' 
		"Author" 			= 'Fake Author' 
		"CompanyName" 			= 'Fake Company' 
		"RootModule" 			= 'UtilityModule.psm1' 
		"CompatiblePSEditions" 		= @('Desktop','Core') 
		"FunctionsToExport" 		= @('Get-SharePointMember','Invoke-PowerAutomateFlow','New-TeamsMessage') 
		"CmdletsToExport" 		= @() 
		"VariablesToExport" 		= '' 
		"AliasesToExport" 		= @() 
		"Description" = 'Utility Module' 
	} 
New-ModuleManifest @Params

Wir exportieren Funktionen unter Verwendung von Export-ModuleMember, aber Performance Best Practices schreiben die Verwendung von leeren Arrays in der Moduldefinition vor. Aus unbekannten Gründen wird ein leeres Array unter VariablesToExport nicht korrekt exportiert, aber eine leere Zeichenfolge gibt ein leeres Array aus.
Durch Ausführen des Befehls New-ModuleManifest wird die Datei UtilityModule.psd1 erstellt. Viele Kommentarblöcke beziehen sich auf zusätzliche Konfigurationen. Im Folgenden haben wir alle zusätzlichen Kommentare entfernt, um die konfigurierten Parameter anzuzeigen.

UtilityModule.psd1

@{
	RootModule 		= 'UtilityModule.psm1' 
	ModuleVersion 		= '0.0.1' 
	CompatiblePSEditions 	= 'Desktop', 'Core' 
	GUID 			= 'dc18a919-f4bf-4da2-8c76-24b68fa33ef0' 
	Author 			= 'Fake Author' 
	CompanyName 		= 'Fake Company' 
	Copyright 		= '(c) Fake Author. All rights reserved.' 
	Description 		= 'UtilityModule'
	FunctionsToExport 	= 'Get-SharePointMember','Invoke-PowerAutomateFlow','New-TeamsMessage' 
	CmdletsToExport 	= @() 
	VariablesToExport 	= @() 
	AliasesToExport 	= @() 
	PrivateData 		= @{
	PSData 			= @{} 
	} 
}

Wenn alle Modulfunktionen dot-sourced sind, warum müssen wir dann die zu exportierenden Funktionen auflisten? Es gibt zwei Hauptgründe dafür, exportierte Funktionen explizit aufzulisten. Private Funktionen sollten nicht öffentlich gemacht werden, und exportierte Funktionen werden auf der Befehlszeile automatisch vervollständigt, auch wenn das Modul noch nicht geladen ist.

Als Nächstes müssen wir die Ladedatei des Moduls erstellen. Auch hier gibt es verschiedene Möglichkeiten, die unten beschriebene Methode hat sich aber als zuverlässig erwiesen. Im ersten Abschnitt werden nur Dateien mit func_-Präfixen abgerufen und mit dot-source versehen. Der zweite Abschnitt exportiert alle Funktionen im Public -Ordner

UtilityModule.psm1

Get-ChildItem (Split-Path $script:MyInvocation.MyCommand.Path) -Filter 'func_*.ps1' -Recurse | ForEach-Object { 
		. $_.FullName 
		} 
Get-ChildItem "$(Split-Path $script:MyInvocation.MyCommand.Path)\Public\*" -Filter 'func_*.ps1' -Recurse | ForEach-Object { 
		Export-ModuleMember -Function ($_.BaseName -Split "_")[1] 
		}

Die Funktionen erstellen

Nachdem wir das Modul erstellt haben, müssen wir unsere Funktionen definieren. In diesem Beispiel erstellen wir drei einfache Funktionen, die den beabsichtigten Workflow unterstützen.

New-TeamsMessage

Diese Funktion nimmt einen Nachrichten-String und eine Team-ID-String auf und erstellt den REST-Aufruf zur Erstellung einer Team-Nachricht. Dadurch wird die erforderliche JSON-Formatierung in einen vereinfachten API-Aufruf verpackt.

Function New-TeamsMessage { 
		[CmdletBinding()]
		Param( 
				[Parameter(Position = 0, Mandatory = $true)][String]$Message, 
				[Parameter(Position = 1, Mandatory = $true)][String]$Title, 
				[Parameter(Position = 2, Mandatory = $true)][String]$URI
		) 
		Process { 
				$Params = @{ 
						"URI" = 	$URI 
						"Method" = 	'POST' 
						"Body" = 	[PSCustomObject][Ordered]@{ 
									"@type" = 'MessageCard' 
									"@context" = 'http://schema.org/extension' 
									"summary" = $Title 
									"title" = $Title 
									"text" = ($Message | Out-String) 
								} 
						"ContentType" = 'application/json' 
						} 
				Invoke-RestMethod @Params | Out-Null 
		} 
	}

 

Invoke-PowerAutomateFlow

Als Nächstes definieren wir eine Power-AutomateFlow-Funktion. Am einfachsten geht dies mithilfe des HTTP-Triggers „Wenn eine HTTP-Anfrage empfangen wird“.

Function Invoke-PowerAutomateFlow { 
		[CmdletBinding()] 
		Param( 
				[Parameter(Position = 0, Mandatory = $true)][String]$URI 
				) 
				Process { 
					$Params = @{ 
							"URI" = $URI 
							"ContentType" = 'application/json' 
							"Method" = 'GET' 
					} 
					Invoke-WebRequest @Params 
				} 
}

 

Get-SharePointMember

Get-SharePointMember unterstützt unsere letzte Workflow-Anforderung, eine SharePoint-Mitgliederliste abzurufen.

Diese Funktion ruft alle SharePoint-Website-Mitglieder für eine bestimmte Website ab und zeigt die Ergebnisse an. Wenn die Ergebnisse in einer Gruppe weitergegeben werden, werden sie gefiltert.

Function Get-SharePointMember { 
		[CmdletBinding()] 
		Param( 
				[Parameter(Position = 0, Mandatory = $true)][String]$URI, 
				[Parameter(Position = 1)][String]$Group 
		) 
		
		Process { 
				$Params = @{ 
						"URI" = $URI 
				} 
				If ($Group) { 
						Get-SPOUser @Params | Where-Object -Contains $Group 
				} Else { 
						Get-SPOUser @Params 
				} 
		} 
}

 

Importieren und Testen des Moduls

Importieren Sie das Modul mit dem Befehl Import-Module und überprüfen Sie es auf Fehler. Als Nächstes verwenden wir den Befehl Get-Command, um alle exportierten Mitglieder zu sehen.

Import-Module -Name 'UtilityModule' 
Get-Command -Module 'UtilityModule'

Führen Sie zum Testen die verschiedenen Befehle aus und vergewissern Sie sich, dass sie so funktionieren, wie Sie es erwarten. Im folgenden Script führen wir die Funktionen aus und verwenden ihre Ausgabe.

# Get SharePoint Members 
$Members = Get-SharePointMember 
# Invoke 
Invoke-PowerAutomateFlow -URI 'https://...' 
New-TeamsMessage -Message $Groups -Title 'Group Members' -URI 'https://...'

Fazit

Das Erstellen eines Moduls könnte in PowerShell nicht einfacher sein. Das Bündeln von Funktionen in einem Modul erleichtert Systemadministratoren das Leben enorm. PowerShell-Module bieten eine Fülle von Möglichkeiten, und dieses Tutorial kratzt nur an der Oberfläche.

Ich kann Ihnen versprechen, wenn Sie diese Möglichkeiten ausschöpfen, werden Sie sich die Administration erheblich vereinfachen!

 

Zusammenhängende Posts

5 min read

Microsoft Exchange mit PowerShell managen

2 min read

VMUG Webcast: VMware Management meistern mit PowerCLI

Über den Autor: