# Module

Irgendwann wird jedes Skript groß genug, um unübersichtlich zu werden. Module helfen dabei, Funktionen, Variablen und andere Bestandteile sinnvoll zu organisieren und wiederzuverwenden. Kurz gesagt: weniger Chaos, mehr Struktur. Meistens jedenfalls.

***Modules.psm1*** – Erweiterungen für das Skript, die zusätzliche Variablen , Funktionen oder Objekte beinhalten. Es kann nicht allein ausgeführt werden und muss von einem **Skript** oder [**Manifest**](https://doku.borinas.com/books/module/page/manifest-psd1 "Manifest") [importiert](https://doku.borinas.com/books/module/page/import-module "Import (Modul laden)") werden .

Es gibt auch → **modulqualifizierter Aufruf**

# Get-Module

`Get-Module` listet PowerShell-Module auf. Standardmäßig werden **nur bereits geladene Module** angezeigt.

Mit zusätzlichen Parametern lassen sich auch **installierte, aber noch nicht geladene Module** oder bestimmte Module anhand ihres Namens ermitteln.

Ein Modul stellt Funktionen, Cmdlets, Variablen, Aliase und weitere Inhalte bereit, die PowerShell erweitern.

---

## **Grundlagen**

#### Bereits geladene Module anzeigen

```powershell
Get-Module
```

Ausgabe (Beispiel)

```text
ModuleType Version Name
---------- ------- ----
Manifest   7.0.0.0 Microsoft.PowerShell.Management
Manifest   7.0.0.0 Microsoft.PowerShell.Utility
Script     2.2.5   PSReadLine
```

---

#### Alle installierten Module anzeigen

```powershell
Get-Module -ListAvailable
```

Hierbei werden auch Module angezeigt, die aktuell **nicht geladen** sind.

---

#### Ein bestimmtes Modul anzeigen

```powershell
Get-Module Microsoft.PowerShell.Utility
```

oder

```powershell
Get-Module -Name Microsoft.PowerShell.Utility
```

---

### Wildcards verwenden

```powershell
Get-Module Microsoft.*
```

---

## **Parameter**

<table id="bkmrk-parameter-beschreibu"><thead><tr><th>Parameter</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`-Name`</td><td>Gibt nur Module mit dem angegebenen Namen zurück. Wildcards sind möglich.</td></tr><tr><td>`-ListAvailable`</td><td>Zeigt alle installierten Module an.</td></tr><tr><td>`-All`</td><td>Zeigt alle Versionen eines geladenen Moduls an.</td></tr><tr><td>`-FullyQualifiedName`</td><td>Sucht anhand eines Modulnamens und optional einer Version oder GUID.</td></tr><tr><td>`-Refresh`</td><td>Aktualisiert Informationen über dynamische Module.</td></tr><tr><td>`-PSEdition`</td><td>Filtert nach der unterstützten PowerShell-Edition (`Desktop` oder `Core`).</td></tr></tbody></table>

---

# Eigenschaften

Die von `Get-Module` zurückgegebenen Objekte besitzen unter anderem folgende Eigenschaften.

<table id="bkmrk-eigenschaft-beschrei"><thead><tr><th>Eigenschaft</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`Name`</td><td>Name des Moduls</td></tr><tr><td>`Version`</td><td>Versionsnummer</td></tr><tr><td>`ModuleType`</td><td>Typ des Moduls</td></tr><tr><td>`Path`</td><td>Speicherort der Moduldatei</td></tr><tr><td>`Guid`</td><td>Eindeutige Modul-ID</td></tr><tr><td>`Description`</td><td>Beschreibung des Moduls</td></tr><tr><td>`Author`</td><td>Autor des Moduls</td></tr><tr><td>`CompanyName`</td><td>Herausgeber</td></tr><tr><td>`PowerShellVersion`</td><td>Erforderliche PowerShell-Version</td></tr><tr><td>`ClrVersion`</td><td>Erforderliche .NET-CLR-Version</td></tr><tr><td>`ExportedFunctions`</td><td>Exportierte Funktionen</td></tr><tr><td>`ExportedCmdlets`</td><td>Exportierte Cmdlets</td></tr><tr><td>`ExportedAliases`</td><td>Exportierte Aliase</td></tr><tr><td>`ExportedVariables`</td><td>Exportierte Variablen</td></tr></tbody></table>

---

# Beispiele

## Geladene Module anzeigen

```powershell
Get-Module

```

---

## Alle installierten Module anzeigen

```powershell
Get-Module -ListAvailable

```

---

## Nur Module eines Herstellers anzeigen

```powershell
Get-Module Microsoft.* -ListAvailable

```

---

## Informationen zu einem Modul abrufen

```powershell
Get-Module PSReadLine

```

---

## Alle installierten Versionen anzeigen

```powershell
Get-Module PSReadLine -ListAvailable -All

```

---

## Exportierte Funktionen eines Moduls anzeigen

```powershell
(Get-Module PSReadLine).ExportedFunctions.Keys

```

---

## Exportierte Cmdlets anzeigen

```powershell
(Get-Module Microsoft.PowerShell.Management).ExportedCmdlets.Keys

```

---

## Installationspfad eines Moduls anzeigen

```powershell
(Get-Module PSReadLine).Path

```

---

# ModuleType

Die Eigenschaft `ModuleType` beschreibt, aus welcher Art von Modul die Informationen stammen.

<table id="bkmrk-typ-beschreibung-man"><thead><tr><th>Typ</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`Manifest`</td><td>Modul basiert auf einer Manifestdatei (`.psd1`).</td></tr><tr><td>`Script`</td><td>PowerShell-Skriptmodul (`.psm1`).</td></tr><tr><td>`Binary`</td><td>Kompiliertes .NET-Modul (`.dll`).</td></tr><tr><td>`Dynamic`</td><td>Zur Laufzeit erzeugtes Modul.</td></tr><tr><td>`Cim`</td><td>CIM-Modul (selten verwendet).</td></tr></tbody></table>

---

# Hinweise

- Ohne Parameter werden **nur geladene Module** angezeigt.
- `-ListAvailable` durchsucht die Verzeichnisse aus `$env:PSModulePath`.
- Ein installiertes Modul erscheint erst ohne `-ListAvailable`, nachdem es mit `Import-Module` geladen wurde.
- Ein Modul kann in mehreren Versionen gleichzeitig installiert sein.
- `Get-Module` liefert Objekte vom Typ **`System.Management.Automation.PSModuleInfo`** zurück.

---

# Verwandte Befehle

<table id="bkmrk-befehl-beschreibung-"><thead><tr><th>Befehl</th><th>Beschreibung</th></tr></thead><tbody><tr><td>`Import-Module`</td><td>Lädt ein Modul in die aktuelle Sitzung.</td></tr><tr><td>`Remove-Module`</td><td>Entfernt ein geladenes Modul aus der Sitzung.</td></tr><tr><td>`Get-Command`</td><td>Zeigt die Befehle eines Moduls an.</td></tr><tr><td>`Get-InstalledModule`</td><td>Zeigt mit PowerShellGet installierte Module an.</td></tr><tr><td>`Find-Module`</td><td>Sucht Module in einem Repository (z. B. PSGallery).</td></tr></tbody></table>

---

## Typische Kombinationen

```powershell
# Alle installierten Module
Get-Module -ListAvailable

# Alle Befehle eines Moduls
Get-Command -Module Microsoft.PowerShell.Management

# Modul laden
Import-Module PSReadLine

# Danach prüfen, ob es geladen wurde
Get-Module PSReadLine

```

# Import-Module

Hier passiert das Offensichtliche, das trotzdem erstaunlich oft falsch gemacht wird: Du lädst dein Modul in die aktuelle Session.

Ohne Import bist du einfach nur jemand, der Code hortet.

---

### 🔧 Grundbefehl

```powershell
Import-Module ModulName
```

PowerShell sucht dein Modul automatisch in den bekannten Modulpfaden (`$env:PSModulePath`).

Dabei reicht es **nicht**, dass sich irgendwo eine `ModulName.psm1` oder `ModulName.psd1` befindet. Ein Modul muss folgende Struktur entsprechen:

```
ModulName\
    ├── ModulName.psm1
    └── ModulName.psd1 (optional)
```

Vorraussetzungen:

- In einem der Verzeichnisse aus `$env:PSModulePath` muss ein **Ordner** mit dem Modulnamen existieren.
- In diesem Ordner muss sich eine gleichnamige Moduldatei (`.psm1`) oder ein gleichnamiges Manifest (`.psd1`) befinden.
- Dateien, die direkt im Modulpfad liegen (ohne entsprechenden Unterordner), werden bei `Import-Module ModulName` **nicht** berücksichtigt.

##### **Manifest hat Vorrang**

Existieren sowohl `ModulName.psd1` als auch `ModulName.psm1`, wird das [**Manifest**](https://doku.borinas.com/books/module/page/manifest-psd1 "Manifest") importiert.

Dadurch können zusätzliche Informationen berücksichtigt werden, beispielsweise:

- weitere Module über `NestedModules`
- Abhängigkeiten über `RequiredModules`
- Exporte (`FunctionsToExport`, `AliasesToExport` usw.)
- Versions- und Kompatibilitätsinformationen

Deshalb ist ein Manifest der empfohlene Einstiegspunkt für größere Module.

---

### 📁 Import über Pfad

Wenn dein Modul irgendwo rumliegt, wo PowerShell es nicht findet:

```powershell
Import-Module "C:\MeinProjekt\MeinModul.psm1"
```

Oder direkt das Verzeichnis:

```powershell
Import-Module "C:\MeinProjekt\MeinModul"
```

PowerShell nimmt dann automatisch das [Manifest](https://doku.borinas.com/books/module/page/manifest-psd1 "Manifest (Modul.psd1)") (`.psd1`) oder die Moduldatei (`.psm1`).

---

### 🔁 Erneutes Laden (Reload)

Du änderst Code, aber PowerShell hängt noch am alten Stand fest? Überraschung.

```powershell
Import-Module MeinModul -Force
```

`-Force` lädt das Modul neu, auch wenn es schon geladen ist.

Pflicht beim Entwickeln, außer du stehst auf Selbstverwirrung.

---

### 🎯 Selektiver Import

Du musst nicht alles laden. Du kannst gezielt nur bestimmte Dinge importieren:

```powershell
Import-Module MeinModul -Function Get-Thing
```

Oder mehrere:

```powershell
Import-Module MeinModul -Function Get-Thing, Set-Thing
```

Funktioniert natürlich nur, wenn dein Manifest das auch erlaubt (`FunctionsToExport`).

---

### 🧠 Automatischer Import

Seit neueren PowerShell-Versionen gilt:

Wenn du eine Funktion aus einem Modul aufrufst, wird es automatisch importiert.

```powershell
Get-Thing
```

→ PowerShell denkt sich: „Kenn ich nicht… ach warte, da gibt’s ein Modul“

Klingt smart. Ist es auch.  
Bis es nicht mehr funktioniert und du nicht weißt warum.

---

### 🔍 Geladene Module anzeigen

```powershell
Get-Module
```

Alle verfügbaren Module anzeigen:

```powershell
Get-Module -ListAvailable
```

Wenn dein Modul hier nicht auftaucht, kannst du lange importieren. Wird nix.

---

### 🧹 Modul entfernen

Falls du es wieder loswerden willst:

```powershell
Remove-Module MeinModul
```

Hilfreich beim Entwickeln, wenn du nicht mit `-Force` arbeiten willst.

---

### ⚠️ Bereits geladenes Modul

Wenn ein Modul bereits geladen ist und du erneut `Import-Module` aufrufst, passiert… nichts.

```powershell
Import-Module MeinModul
```

PowerShell sagt sich: „Kenn ich schon“ und ignoriert dich stillschweigend.

Das bedeutet:

- Änderungen im Code werden **nicht** übernommen
- Du arbeitest weiter mit der alten Version

Wenn du sicherstellen willst, dass dein Modul wirklich neu geladen wird:

```powershell
Import-Module MeinModul -Force
```

Alternativ kannst du es vorher entfernen:

```powershell
Remove-Module MeinModul Import-Module MeinModul
```

**Wichtig beim Entwickeln:**  
Wenn sich „irgendwas komisch anfühlt“, ist es erstaunlich oft genau das hier.

Du debugst dann nicht deinen Code.  
Du debugst deine Vergangenheit.

---

## Der eigentliche Punkt (den wieder alle ignorieren)

**Import ist kein einmaliger Akt, sondern Teil deines Workflows.**

- Entwicklung → ständig `-Force`
- Debugging → bewusst laden/entladen
- Produktion → einmal sauber laden und fertig

Wenn dein Modul sich beim Import komisch verhält, liegt es fast nie am Import.  
Es liegt daran, was dein Modul beim Laden tut.

Und genau da trennt sich „läuft irgendwie“ von „ich hab verstanden, was ich da gebaut habe“.

# Manifest (.psd1)

#### Was ist ein Manifest?

Ein Manifest (`.psd1`) beschreibt ein PowerShell-Modul.

Während die eigentliche Programmlogik in einer `.psm1`-Datei liegt, enthält das Manifest Informationen über das Modul selbst.

Dazu gehören beispielsweise

- Version
- Autor
- Abhängigkeiten
- exportierte Befehle
- unterstützte PowerShell-Versionen
- Lizenzinformationen

Das Manifest enthält **keinen ausführbaren Programmcode**. Es dient ausschließlich als Beschreibung und Konfiguration eines Moduls.

---

## **Allgemein**

Das ist die Identität deines Moduls. Ohne das bist du einfach nur irgendein Skript mit Existenzkrise.

```powershell
@{
    RootModule        = "TestModul.psm1"
    ModuleVersion     = "1.7.0"
    GUID              = "ege0799e-734e-451d-9bb1-34983dd82f05"
    Author            = "ProgramMaster"
    CompanyName       = "Microsoft"
    Copyright         = "Microsoft i guess"
    Description       = "Ich beschreibe wundervoll, was das für ein Modul es ist"
}
```

##### **RootModule**

Hauptdatei (`.psm1` oder `.dll`)

##### **ModuleVersion**

Version (z. B. `1.0.0`)

##### **GUID**

Eindeutige ID

##### **Author**

Ersteller/Entwickler des Moduls

##### **CompanyName**

Unternehmen

##### **Copyright**

Urheberrechte

##### **Description**

Beschreibung des Moduls

---

## **Abhängigkeiten**

Hier sagst du: „Ich funktioniere nicht alleine, ich brauche andere.“

- `RequiredModules`   
    → Externe Abhängigkeiten  
    → Angabe über **Modulnamen** (PowerShell sucht es selbst)  
    → Müssen im System vorhanden sein (installiert / auffindbar, z.B. über `$PSModulePath`)  
    → Gehören **nicht** zu deinem Modul
- `RequiredAssemblies` – DLLs
- `ScriptsToProcess` – Skripte, die beim Laden ausgeführt werden
- `ModuleList` – Nur die Meta-Information welche andere Module zugehörig sind
- `NestedModules`  
    → Angabe über **Dateien/Pfade** (du sagst konkret, was geladen wird)  
    → Interne Bausteine deines Moduls  
    → Werden zusammen mit deinem Modul geladen  
    → Gehören **zu deinem Modul dazu**

---

## 🚀 Export (was nach außen sichtbar ist)

Das ist der Teil, wo du entscheidest, was du der Welt zeigst. Oder versteckst.

- `FunctionsToExport`
- `CmdletsToExport`
- `VariablesToExport`
- `AliasesToExport`

👉 Klassiker:  
`'*'` = alles exportieren  
oder explizit = bessere Kontrolle

---

## 🧠 Kompatibilität &amp; Anforderungen

Hier wird’s picky.

- `PowerShellVersion`
- `PowerShellHostName`
- `PowerShellHostVersion`
- `DotNetFrameworkVersion`
- `CLRVersion`
- `ProcessorArchitecture`

---

## 📦 Private Daten (der geheime Keller)

Alles, was du selbst definierst.

- `PrivateData` – Hashtable für eigene Infos

Beispiel:

```powershell
PrivateData = @{
    PSData = @{
        Tags = @('UI','Forms')
        ProjectUri = 'https://...'
    }
}
```

---

## 🌐 PSData (wichtig für Gallery etc.)

Teil von `PrivateData`, aber so wichtig, dass es eigentlich sein eigenes Ding ist.

- `Tags`
- `LicenseUri`
- `ProjectUri`
- `IconUri`
- `ReleaseNotes`

---

## 🧩 Sonstiges (der „Warum gibt’s das?“ Bereich)

Selten gebraucht, aber existiert halt:

- `FileList`
- `TypesToProcess`
- `FormatsToProcess`
- `CompatiblePSEditions` (`Desktop`, `Core`)
- `HelpInfoURI`

---

## 🔧 Mini-Beispiel

Damit du nicht nur trockene Theorie hast:

```powershell
@{
    RootModule        = 'MeinModul.psm1'
    ModuleVersion     = '1.0.0'
    GUID              = '12345678-abcd-1234-abcd-1234567890ab'
    Author            = 'Jonny'
    Description       = 'Mein erstes Modul'

    FunctionsToExport = @('Get-Thing', 'Set-Thing')

    PowerShellVersion = '5.1'

    PrivateData = @{
        PSData = @{
            Tags = @('Example','Test')
        }
    }
}
```

---

## Der eigentliche Punkt (den viele übersehen)

Du brauchst vielleicht **30% davon wirklich**.

Der Rest ist:

- entweder für Publishing
- oder für Leute, die Kontrolle lieben (oder Angst haben)

Wenn du lokal entwickelst:  
→ `RootModule`, `ModuleVersion`, `FunctionsToExport`  
→ fertig, läuft.