PowerShell-Module intern verteilen und aktualisieren — PSResourceGet und ein internes Repository

· · PowerShell, Module, Verteilung, Versionsverwaltung, Betriebsoptimierung, Wartbarkeit, Informationssysteme, Automatisierung

„Ich habe ein praktisches Skript geschrieben, also habe ich es in den freigegebenen Ordner gelegt.“ Von diesem Moment an häuft sich still Wartungslast an. Jemand kopiert es, verändert die lokale Version, Korrekturen am Original erreichen ihn nie, und niemand weiß, welche Version wo läuft. Ein paar Jahre später liegen im freigegebenen Ordner aggregate.ps1, aggregate_v2.ps1 und aggregate_fixed_latest.ps1 nebeneinander.

In der PowerShell-Welt ist die Antwort auf dieses Problem klar: daraus ein Modul machen, ihm eine Version geben und es aus einem Repository verteilen. Allein damit lassen sich die Fragen „welche Version ist installiert?“ und „erreicht ein Update alle?“ beantworten. Und ab PowerShell 7.4 ist der dafür nötige Mechanismus (PSResourceGet) bereits ab Werk enthalten.

Dieser Artikel führt durch die Schritte, um intern geteilte Skripte in ein Modul zu verwandeln und ein internes Repository aufzusetzen, um sie zu verteilen und zu aktualisieren, mit einem realistischen Aufbau, der keinen dedizierten Server erfordert. Um zunächst Funktionen selbst zu modularisieren, sollte das vorherige Lesen von „Parameterdesign und Modularisierung in PowerShell“ den Einstieg erleichtern.

1. Das Wichtigste zuerst

  • PSResourceGet (Microsoft.PowerShell.PSResourceGet) ist ab Werk in PowerShell 7.4 enthalten. Es besteht neben dem herkömmlichen PowerShellGet 2.2.5, sodass Sie es verwenden können, ohne bestehende Skripte zu beschädigen. In Windows PowerShell 5.1 ist es nicht enthalten, daher benötigen sowohl Nutzer als auch Anbieter eine vorherige Installation (siehe nächster Abschnitt).1
  • Sie können ein internes Repository auf einer Dateifreigabe starten. Übergeben Sie einfach einen UNC-Pfad an Register-PSResourceRepository. Kein dedizierter Server erforderlich.2
  • Betrachten Sie das Manifest (.psd1) als zwingend erforderlich. Ohne Versionsnummer lassen sich weder Aktualisierungen noch die Eingrenzung eines Problems verwalten.3
  • Verwenden Sie für FunctionsToExport keinen Platzhalter — listen Sie sie explizit in einem Array auf. Die Befehlssuche wird schneller, und Sie vermeiden es, interne Funktionen unbeabsichtigt offenzulegen.3
  • Versionieren Sie mit semantischer Versionierung. Können Sie breaking Changes nicht in der Hauptversion ausdrücken, können Nutzer nicht mit Zuversicht aktualisieren.4
  • Veröffentlichen mit Publish-PSResource, abrufen mit Install-PSResource, aktualisieren mit Update-PSResource.56
  • Die Modulsuchpfade unterscheiden sich zwischen 5.1 und 7. Ohne den Unterschied bei $env:PSModulePath zu verstehen, stoßen Sie auf „installiert, aber nicht gefunden“.7
  • Ist die Ausführungsrichtlinie AllSigned, ist eine Authenticode-Signatur für jede Skriptdatei zwingend. Die Katalogsignierung dient der Überprüfung der Paketintegrität und erfüllt die Ausführungsrichtlinie nicht.8
  • Seien Sie vorsichtig beim automatischen Aktualisieren von Modulen, von denen unbeaufsichtigte Jobs abhängen. Erst verifizieren, dann die Version geplant anheben — das ist das sichere Modell.

2. Die Probleme mit „ps1-Dateien in einem freigegebenen Ordner“

Zunächst wollen wir klären, was wir eigentlich lösen möchten.

Symptom Grundursache
Niemand weiß, welche Version läuft Es gibt kein Konzept einer Versionsnummer
Korrekturen erreichen nicht alle Jeder hält seine eigene Kopie
Niemand weiß, wer es verwendet Es wird keine Aufzeichnung des Abrufs geführt (wie unten besprochen, erfordert allein dies eine Wahl der Verteilungsmethode)
Es bricht nur in manchen Umgebungen Abhängigkeiten (benötigte Module, PS-Version) sind nicht deklariert
Wir möchten korrigieren, können aber die Auswirkung nicht abschätzen Es gibt keine Unterscheidung zwischen veröffentlichten und internen Funktionen

Modularisierung und die Verteilung über ein Repository wirken direkt auf die oberen vier davon. Nur „wer es verwendet“ hängt vom Verteilungsmechanismus ab. Das in den folgenden Abschnitten vorgestellte Dateifreigabe-Repository ist praktisch, führt aber keine Aufzeichnung darüber, wer wann etwas abgerufen hat (Get-InstalledPSResource zeigt nur den Zustand der Maschine, auf der Sie den Befehl ausgeführt haben). Möchten Sie Einblick in die Nutzung, kombinieren Sie es mit einem der folgenden Ansätze.

3. Der minimale Modulaufbau

Die minimale Form eines verteilbaren Moduls besteht aus drei Dingen: einem Ordner, einer .psm1 und einer .psd1.

KsOps\
  KsOps.psd1     ← Manifest (Version, exportierte Funktionen, Abhängigkeiten)
  KsOps.psm1     ← Implementierung (oder Dot-Sourcing aus den Ordnern Public/Private)
  Public\
    Get-KsShareUsage.ps1
    Invoke-KsArchive.ps1
  Private\
    ConvertTo-KsSize.ps1

Erzeugen Sie die Manifestvorlage mit New-ModuleManifest und füllen Sie das Nötige aus.3

$manifest = @{
    Path              = '.\KsOps\KsOps.psd1'
    RootModule        = 'KsOps.psm1'
    ModuleVersion     = '1.0.0'
    GUID              = [guid]::NewGuid().Guid
    Author            = 'IT Department'
    CompanyName       = 'Sample Corporation'
    Description       = 'Shared module for in-house operations scripts (file server inventory and archiving)'
    PowerShellVersion = '5.1'
    CompatiblePSEditions = @('Desktop', 'Core')      # wenn es sowohl unter 5.1 als auch 7 verwendet wird
    # Keinen Platzhalter verwenden. Nur explizit angeben, was veröffentlicht wird
    FunctionsToExport = @('Get-KsShareUsage', 'Invoke-KsArchive')
    CmdletsToExport   = @()
    VariablesToExport = @()
    AliasesToExport   = @()
    RequiredModules   = @()                          # Abhängigkeiten hier deklarieren, falls vorhanden
    Tags              = @('internal', 'operations')
    ProjectUri        = 'https://git.example.co.jp/it/ksops'
}
New-ModuleManifest @manifest

Die .psm1 kann dem Standardmuster folgen, die Public-/Private-Skripte zu laden und nur die öffentlichen Funktionen zu exportieren.

# KsOps.psm1
$public  = @(Get-ChildItem -Path "$PSScriptRoot\Public\*.ps1"  -ErrorAction SilentlyContinue)
$private = @(Get-ChildItem -Path "$PSScriptRoot\Private\*.ps1" -ErrorAction SilentlyContinue)

foreach ($file in @($public + $private)) {
    try   { . $file.FullName }
    catch { throw "Failed to load module file: $($file.FullName)$_" }
}

# Nur die Funktionen unter Public veröffentlichen (dies konsistent mit der Manifest-Deklaration halten)
Export-ModuleMember -Function $public.BaseName

Es gibt zwei Gründe, FunctionsToExport keinen Platzhalter zu geben. Der eine ist die Leistung der Befehlssuche: Werden sie explizit angegeben, kann PowerShell bestimmen, „welcher Befehl wo liegt“, ohne den Modulrumpf zu analysieren. Der andere ist ein Designgrund: Lassen sich interne Hilfsfunktionen von außen aufrufen, werden sie zu einer faktisch öffentlichen API, und Sie können sie später nicht mehr ändern.3

4. Das Versionierungsschema festlegen

Ob Nutzer mit Zuversicht aktualisieren können, wird dadurch entschieden, wie Sie Versionsnummern vergeben. Übernehmen Sie semantische Versionierung (Hauptversion.Nebenversion.Patch) und drücken Sie breaking Changes stets in der Hauptversion aus.4

Art der Änderung Was anzuheben ist
Umbenennen eines Parameters, Entfernen einer Funktion, Ändern der Form eines Rückgabewerts Hauptversion (1.2.3 → 2.0.0)
Hinzufügen einer Funktion oder eines Parameters (bestehende Verwendung funktioniert weiter) Nebenversion (1.2.3 → 1.3.0)
Nur Fehlerkorrekturen Patch (1.2.3 → 1.2.4)

Möchten Sie eine Version zur Verifikation verteilen, stehen Prerelease-Versionen zur Verfügung. Das Setzen einer Zeichenkette wie beta1 in PrivateData.PSData.Prerelease des Manifests (der Bindestrich, der sie von der Version trennt, wird automatisch hinzugefügt, sodass 1.3.0-beta1 entsteht) bedeutet, dass sie bei einem normalen Abruf nicht herunterkommt und nur installiert wird, wenn Sie explizit -Prerelease angeben. Die Zeichenkette darf nur ASCII-Alphanumerik und Bindestriche enthalten; Punkte und + sind nicht erlaubt.4

Beim Umgang mit breaking Changes ist das Denken hinter dem Schnittstellendesign eine nützliche Referenz (siehe „Rückwärtskompatibilität von DLL- und COM-Schnittstellen“).

5. Ein internes Repository aufbauen — eine Dateifreigabe genügt

PSResourceGet kann einen Ordner auf einer Dateifreigabe als Repository behandeln.2 Das ist der kostengünstigste Aufbau, den man übernehmen kann.

Prüfen Sie zunächst die Voraussetzungen. Es ist ab PowerShell 7.4 und später enthalten, fehlt aber in Windows PowerShell 5.1. Um die folgenden Befehle (Register-PSResourceRepository usw.) unter 5.1 zu verwenden, installieren Sie das Modul vorab.1

# [Nur Windows PowerShell 5.1] PSResourceGet installieren.
# 5.1 und 7 laden aus unterschiedlichen Modulpfaden, daher in der verwendeten Edition ausführen
if (-not (Get-Module -ListAvailable -Name Microsoft.PowerShell.PSResourceGet)) {
    Install-Module -Name Microsoft.PowerShell.PSResourceGet -Scope AllUsers -Force
}
# [Einmal auf Anbieter- und Nutzerseite ausführen] Das interne Repository registrieren
# Trusted: es ist eine interne Verteilung, daher als vertrauenswürdig behandeln / Priority: vor PSGallery durchsuchen
$repo = @{
    Name     = 'KsInternal'
    Uri      = '\\fileserver\PSRepository'
    Trusted  = $true
    Priority = 10
}
Register-PSResourceRepository @repo

Get-PSResourceRepository | Format-Table Name, Uri, Trusted, Priority

Setzen Sie die Berechtigungen des freigegebenen Ordners auf „Schreibzugriff nur für die Verteilungsverantwortlichen, Nutzer nur lesend“. Ist das zu locker, wird es zu einem Weg, über den jeder beliebigen Code unternehmensweit verteilen kann. Zum Berechtigungsdesign auf freigegebenen Ordnern siehe auch „Einen Dateiserver mit PowerShell bestandsaufnehmen“.

Für einen ernsthafteren Einsatz registrieren Sie einen NuGet-kompatiblen Feed wie Azure Artifacts oder GitHub Packages. Für Repositorys, die eine Authentifizierung erfordern, können Sie es so einrichten, dass die Anmeldeinformationen aus einem SecretManagement-Tresor gelesen werden (siehe „Anmeldeinformationen in PowerShell sicher handhaben“).2

6. Veröffentlichen, Abrufen und Aktualisieren

# [Anbieter] Das Modul veröffentlichen
Publish-PSResource -Path .\KsOps -Repository 'KsInternal'

# [Nutzer] Suchen und installieren
Find-PSResource -Name 'KsOps' -Repository 'KsInternal'
Install-PSResource -Name 'KsOps' -Repository 'KsInternal' -Scope CurrentUser

# Eine fixierte Version installieren (für Produktivserver empfohlen)
Install-PSResource -Name 'KsOps' -Version '1.2.3' -Repository 'KsInternal' -Scope AllUsers

# Aktualisieren
Update-PSResource -Name 'KsOps' -Repository 'KsInternal'

# Prüfen, was installiert ist (streng genommen nur der Zustand *dieser* Maschine)
Get-InstalledPSResource -Name 'KsOps' | Format-Table Name, Version, Repository, InstalledDate

# Um den unternehmensweiten Installationsstatus zu kennen, auf jeder Maschine ausführen und aggregieren
Invoke-Command -ComputerName $servers -ScriptBlock {
    Get-InstalledPSResource -Name 'KsOps' -ErrorAction SilentlyContinue |
        Select-Object Name, Version
} | Sort-Object PSComputerName

Die richtige Wahl von -Scope ist wichtig. Module, die von unbeaufsichtigten Jobs der Aufgabenplanung verwendet werden, müssen in AllUsers (oder in der eigenen Umgebung des Dienstkontos) installiert werden. Die klassische Ursache für „es funktioniert in meiner Umgebung, aber der nächtliche Batch scheitert mit is not recognized as the name of a cmdlet“ ist eine Installation in den CurrentUser-Bereich.67

7. Modulsuchpfade und der Unterschied zwischen 5.1 und 7

PowerShell sucht nach Modulen in den in $env:PSModulePath aufgelisteten Ordnern. Die Standardpfade unterscheiden sich zwischen Windows PowerShell 5.1 und PowerShell 7.7

Edition Standardpfad im Benutzerbereich
Windows PowerShell 5.1 %USERPROFILE%\Documents\WindowsPowerShell\Modules
PowerShell 7 %USERPROFILE%\Documents\PowerShell\Modules

Deklarieren Sie für Module, die auf beiden verwendet werden, sowohl Desktop als auch Core in CompatiblePSEditions und testen Sie in beiden Umgebungen, bevor Sie verteilen. Die PSUseCompatibleSyntax von PSScriptAnalyzer hilft bei der Kompatibilitätsprüfung (siehe „Die Qualität von PowerShell-Skripten mit PSScriptAnalyzer schützen“).

Prüfen Sie bei der Fehlersuche diese drei Dinge.

$env:PSModulePath -split ';'                       # die Suchpfade
Get-Module -Name KsOps -ListAvailable              # wird es gefunden, und welche Version
(Get-Module KsOps -ListAvailable).ModuleBase       # von wo es tatsächlich geladen wird

8. Signierung und Ausführungsrichtlinie

Bei der Signierung gibt es zwei Mechanismen mit unterschiedlichem Zweck, und sie zu verwechseln führt zu „ich habe signiert, aber es läuft nicht“.8

Mechanismus Was er garantiert Erfüllt er die Ausführungsrichtlinie AllSigned?
Authenticode-Signatur (Set-AuthenticodeSignature) Herausgeber und Integrität einer einzelnen Skriptdatei Ja (jede Datei benötigt eine Signatur)
Katalogsignatur (New-FileCatalog + Signierung) Integrität des gesamten Moduls (des Pakets) Nein

Die Ausführungsrichtlinie überprüft die Authenticode-Signatur genau der .ps1 / .psm1, die gerade geladen werden soll. Signieren Sie die Katalogdatei (.cat), bleiben die darin enthaltenen Skriptdateien unsigniert, sodass die Ausführung in einer AllSigned-Umgebung blockiert wird. Betreiben Sie also AllSigned, ist es zwingend, jede tatsächlich ausgeführte Datei zu signieren.

# (1) In einer AllSigned-Umgebung zwingend: jede ausgeführte Datei mit Authenticode signieren
Get-ChildItem .\KsOps -Recurse -Include *.ps1, *.psm1, *.psd1 | ForEach-Object {
    Set-AuthenticodeSignature -FilePath $_.FullName -Certificate $cert `
        -TimestampServer 'http://timestamp.digicert.com'
}

# (2) Zusätzlich einen Katalog verwenden, um Manipulationen am gesamten Paket zu erkennen
New-FileCatalog -Path .\KsOps -CatalogFilePath .\KsOps\KsOps.cat -CatalogVersion 2
Set-AuthenticodeSignature -FilePath .\KsOps\KsOps.cat -Certificate $cert `
    -TimestampServer 'http://timestamp.digicert.com'

# Verifikation auf Nutzerseite (getrennt von der Ausführungsrichtlinie: ist das Paket unversehrt?)
Test-FileCatalog -Path .\KsOps -CatalogFilePath .\KsOps\KsOps.cat -Detailed

Der Wert eines Katalogs liegt darin, bestätigen zu können, dass „das abgerufene Modulpaket identisch mit dem verteilten ist“, und PSResourceGet besitzt eine Option -AuthenticodeCheck, die ebenfalls Signaturen und Kataloge überprüft.6 Verstehen Sie die Aufgabenteilung so: Authenticode-Signaturen entscheiden, ob es läuft, Kataloge über die Integrität des verteilten Pakets.

Das Anbringen eines Zeitstempels bedeutet, dass die Signatur auch nach Ablauf des Signaturzertifikats gültig bleibt. Das Gesamtbild von Ausführungsrichtlinie und Signaturpraxis wird in „PowerShells Ausführungsrichtlinie und Skriptsignierung“ behandelt.

9. Als Betriebsregeln festzulegende Entscheidungen

Der Betrieb ist wichtiger als die Technik. Legen Sie mindestens Folgendes fest.

  • Wer veröffentlichen darf. Wer Schreibrechte auf dem freigegebenen Ordner hat, ist jemand, der unternehmensweit Code verteilen kann
  • Wo die Änderungshistorie steht. Halten Sie breaking Changes in ReleaseNotes (unter PrivateData.PSData des Manifests) oder in einem CHANGELOG fest
  • Ob Produktivserver Versionen fixieren. Für Module, von denen unbeaufsichtigte Jobs abhängen, ist Fixierung mit geplanter Aktualisierung die sichere Option
  • Das Verfahren zur Außerdienststellung. Beim Entfernen einer Funktion die Hauptversion anheben und die Abschaffung vorab ankündigen
  • Tests und Lint vor der Veröffentlichung durchlaufen lassen. Idealerweise erfolgt die Veröffentlichung aus CI (siehe „PowerShell mit Pester testen“)

10. Praktische Faustregeln (Entscheidungstabelle)

Frage Optionen Richtlinie
Verteilungsform .ps1 in einem freigegebenen Ordner / Modul + Repository Die Trennlinie ist, ob sich Versionen und Aktualisierungen verwalten lassen
Modulverwaltung PowerShellGet 2.x / PSResourceGet Ab 7.4 mitgeliefert. Für alles Neue PSResourceGet verwenden1
Repository Dateifreigabe / NuGet-kompatibler Feed Mit einer Dateifreigabe beginnen. Zu einem Feed wechseln, wenn Authentifizierung und Auditing nötig sind2
Manifest Weglassen / Zwingend Ohne Version hält das Betriebsmodell nicht zusammen3
Exportierte Funktionen '*' / explizites Array Für die Suchleistung und um interne Funktionen privat zu halten3
Installationsort CurrentUser / AllUsers für unbeaufsichtigte Ausführung Das Kriterium ist, ob das Dienstkonto es sehen kann7
Aktualisierungen in der Produktion Automatische Aktualisierungen / fixierte Version + geplante Aktualisierungen Verhindert, dass der nächtliche Batch von selbst mit einer neuen Version läuft
Signierung Keine / Authenticode-Signatur je Datei (+ Katalog) In einer AllSigned-Umgebung ist die Signierung je Datei zwingend. Kataloge dienen der Integritätsprüfung8

11. Zusammenfassung

  • Das Verteilen von .ps1-Dateien über einen freigegebenen Ordner macht Versionen, Aktualisierungen, Abhängigkeiten und die öffentliche Oberfläche allesamt unverwaltbar. Modularisierung und Verteilung über ein Repository lösen das. Die eine Ausnahme ist „wer es verwendet“. Ein Dateifreigabe-Repository führt keine Aufzeichnung des Abrufs, kombinieren Sie es daher mit Leseüberwachung auf dem freigegebenen Ordner, einem Feed mit Download-Statistiken oder der Aggregation von Get-InstalledPSResource über mehrere Maschinen hinweg.
  • Ein Manifest ist zwingend. Geben Sie FunctionsToExport explizit als Array an und veröffentlichen Sie keine internen Funktionen.
  • Ein internes Repository lässt sich einfach durch Registrieren einer Dateifreigabe über einen UNC-Pfad starten. Die Verwaltung des Schreibrechts ist in der Praxis die Sicherheitsgrenze.
  • Veröffentlichen mit Publish-PSResource, abrufen mit Install-PSResource, aktualisieren mit Update-PSResource. Installieren Sie Module, die von unbeaufsichtigten Jobs verwendet werden, im Bereich AllUsers.
  • Die Suchpfade unterscheiden sich zwischen 5.1 und 7. Unterstützen Sie beide, deklarieren Sie CompatiblePSEditions und testen Sie in beiden.
  • In einer AllSigned-Umgebung benötigt jede Skriptdatei eine Authenticode-Signatur. Die Katalogsignierung dient der Überprüfung der Integrität des verteilten Pakets und ist eine andere Angelegenheit als die Frage, ob es läuft. Bringen Sie immer einen Zeitstempel an.

Beispielcode zum Download

Der in diesem Artikel behandelte Code wird als direkt ausführbares Paket verteilt. Er enthält ein vollständiges Modul mit getrennt gehaltenem öffentlichem und privatem Code sowie das Verfahren zur Verteilung in ein internes Repository.

Beispielcode herunterladen (zip)

Die Beispiele dieses Artikels wurden tatsächlich unter PowerShell 7.6 ausgeführt und verifiziert (16 Pester-Tests). Führen Sie das im zip enthaltene Invoke-SampleTests.ps1 aus, um dieselbe Verifikation auf Ihrer eigenen Maschine zu reproduzieren.

# Syntaxprüfung + statische Analyse + Pester-Tests
./Invoke-SampleTests.ps1

Die Konfigurationswerte (Pfade, Servernamen, Mandanten-IDs usw.) sind Beispiele. Führen Sie sie nicht unverändert in einer Produktivumgebung aus — passen Sie sie an Ihre eigene Umgebung an.

Verwandte Artikel

Verwandte Beratungsbereiche

Die KomuraSoft LLC übernimmt die Modularisierung interner Skript-Ressourcen und den Aufbau der Infrastruktur zu ihrer Verteilung, die Standardisierung von Betrieb, der von einer einzelnen Person abhängig geworden ist, sowie die Verbesserung der Wartbarkeit bestehender Skripte.

  1. Microsoft Learn, Package management for PowerShell. Dazu, dass Microsoft.PowerShell.PSResourceGet das Modul ist, das PowerShellGet und PackageManagement ersetzt; dazu, dass es ab Werk in PowerShell 7.4 enthalten ist und neben dem herkömmlichen PowerShellGet 2.2.5 besteht; sowie dazu, dass es sich auch unter Windows PowerShell 5.1 aus der PowerShell Gallery installieren lässt.  2 3

  2. Microsoft Learn, Register-PSResourceRepository. Dazu, dass sich ein Repository registrieren lässt, indem man -Uri einen lokalen Ordner, eine Dateifreigabe (UNC-Pfad) oder die URL eines NuGet-kompatiblen Feeds übergibt; zur Kennzeichnung als vertrauenswürdig mit -Trusted; zur durch -Priority festgelegten Suchreihenfolge; sowie zur Angabe von Anmeldeinformationen für Repositorys, die eine Authentifizierung erfordern.  2 3 4

  3. Microsoft Learn, How to write a PowerShell module manifest. Zur Erstellung eines Manifests mit New-ModuleManifest; zu den einzelnen Schlüsseln wie RootModule, ModuleVersion, GUID, PowerShellVersion, CompatiblePSEditions und RequiredModules; sowie dazu, warum Exportangaben wie FunctionsToExport explizit statt mit Platzhaltern erfolgen sollten (Leistung der Befehlssuche).  2 3 4 5 6

  4. Microsoft Learn, Prerelease module versions. Zur Versionierung auf Basis semantischer Versionierung; zur Angabe von Prerelease-Versionen über PrivateData.PSData.Prerelease; sowie dazu, dass Prerelease-Versionen nicht standardmäßig abgerufen werden.  2 3

  5. Microsoft Learn, Publish-PSResource. Zur Veröffentlichung des mit -Path angegebenen Modulordners in ein Repository; zur Angabe des Ziels mit -Repository; sowie zur Authentifizierung über -ApiKey. 

  6. Microsoft Learn, Install-PSResource. Zur Installation über -Name / -Version / -Repository; zur Wahl des Installationsorts mit -Scope (CurrentUser / AllUsers); sowie zum Überspringen der Bestätigung mit -TrustRepository. Siehe auch Update-PSResource zur Aktualisierung.  2 3

  7. Microsoft Learn, about_PSModulePath. Dazu, dass PowerShell in den in $env:PSModulePath aufgelisteten Ordnern nach Modulen sucht, und dazu, dass sich die Standardpfade im Benutzerbereich und im Bereich aller Benutzer zwischen Windows PowerShell und PowerShell 7 unterscheiden.  2 3 4

  8. Microsoft Learn, New-FileCatalog. Dazu, dass sich eine Katalogdatei (.cat) mit Hashes der Dateien unterhalb eines Ordners erzeugen lässt; zur Signierung des Katalogs mit Set-AuthenticodeSignature; sowie dazu, dass Test-FileCatalog Manipulationen erkennt, indem es den Katalog mit den Dateien abgleicht. Dass die Ausführungsrichtlinie die Authenticode-Signatur der auszuführenden Skriptdatei selbst überprüft, wird in about_Execution_Policies (dazu, dass AllSigned nur von einem vertrauenswürdigen Herausgeber signierte Skripte ausführen lässt) und Set-AuthenticodeSignature (zum Anbringen einer Authenticode-Signatur an einer Datei und zur Zeitstempelung über -TimestampServer) behandelt.  2 3

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Was ist der Unterschied zwischen PowerShellGet und PSResourceGet? Welches sollte ich verwenden?
PSResourceGet (Microsoft.PowerShell.PSResourceGet) ist der neue Mechanismus zur Modulverwaltung, der das ältere PowerShellGet und PackageManagement ersetzt, und ist ab Werk in PowerShell 7.4 enthalten. Es kann neben dem herkömmlichen PowerShellGet 2.2.5 bestehen, sodass Sie migrieren können, ohne bestehende Skripte zu beschädigen. Für alles Neue ist PSResourceGet — dessen Cmdlet-Namen die Form -PSResource haben (Install-PSResource, Publish-PSResource usw.) — die empfohlene Wahl. Es lässt sich auch unter Windows PowerShell 5.1 verwenden, wenn Sie es aus der PowerShell Gallery installieren.
Benötige ich einen dedizierten Server, um ein internes Repository aufzusetzen?
Nein. Der einfachste Ansatz ist, einen Ordner auf einer Dateifreigabe als Repository zu registrieren, was funktioniert, indem Sie Register-PSResourceRepository einen UNC-Pfad übergeben. Weder ein dedizierter Server noch eine Datenbank sind erforderlich. Möchte Ihre Organisation Zugriffskontrolle und Auditing, oder möchten Sie Pakete von außerhalb des Netzwerks abrufen, verwenden Sie einen NuGet-kompatiblen Feed wie Azure Artifacts oder GitHub Packages. Mit einer Dateifreigabe zu beginnen und bei Bedarf zu migrieren, ist der realistische Weg.
Ist ein Modulmanifest (.psd1) wirklich notwendig?
Betrachten Sie es in der Praxis als notwendig. Eine .psm1 allein lässt sich zwar als Modul laden, aber ohne Manifest kann sie keine Versionsnummer tragen, und Sie verlieren den Überblick darüber, welche Version wo installiert ist. Ohne Version lassen sich weder Aktualisierungen noch die Eingrenzung eines Fehlers verwalten, wenn einer auftritt. Zusätzlich lässt sich mit einem Manifest festlegen, welche Funktionen exportiert werden, abhängige Module deklarieren sowie die unterstützte PowerShell-Version und Edition angeben. New-ModuleManifest erzeugt eine Vorlage, sodass der Aufwand für die Erstellung gering ist.
Was ist das Problem, wenn ich '*' in FunctionsToExport eintrage?
Die automatische Befehlssuche wird langsamer, und interne Funktionen, die nie öffentlich sein sollten, werden es. PowerShell muss wissen, welcher Befehl zu welchem Modul gehört, bevor es das Modul lädt, und mit einem Platzhalter kann es das nicht wissen, ohne den Modulrumpf zu analysieren. Listen Sie die exportierten Funktionen explizit in einem Array auf, wird diese Analyse überflüssig. Außerdem: Lassen sich interne Hilfsfunktionen von außen aufrufen, werden sie zu einer faktisch öffentlichen API, und Sie können sie später nicht mehr ändern.
Können die von mir verteilten Module auf Seite der Nutzer automatisch aktualisiert werden?
Sie können mit Update-PSResource aktualisieren, aber gestalten Sie die automatische Aktualisierung von Modulen, von denen Geschäftsskripte abhängen, mit Sorgfalt. Es bedeutet, dass Ihr unbeaufsichtigter nächtlicher Batch beginnt, mit einer neuen Version zu laufen, ohne dass es jemand bemerkt. In der Praxis ist das sichere Betriebsmodell, eine neue Version zunächst in einer Testumgebung zu verifizieren und die Produktion dann geplant zu aktualisieren. Müssen Sie es unbedingt automatisieren, bauen Sie eine Bremse ein — fixieren Sie die Hauptversion und aktualisieren Sie innerhalb davon (mit einem Bereich wie -Version '1.*').

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog