Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn Sie die gleichen PowerShell-Einzeilen oder Skripts häufig verwenden, ist die Umwandlung in wiederverwendbare Tools noch wichtiger. Durch das Verpacken Ihrer Funktionen in einem Skriptmodul wirkt es professioneller und erleichtert die Unterstützung und das Teilen mit anderen.
Dot-Sourcing-Funktionen
Eine Sache, die wir im vorherigen Kapitel nicht behandelt haben, sind Dot-Sourcing-Funktionen. Wenn Sie eine Funktion in einem Skript definieren, die aber nicht zu einem Modul gehört, ist die einzige Möglichkeit, sie in den Arbeitsspeicher zu laden, das Dot-Sourcing der .ps1
Datei.
Speichern Sie beispielsweise die folgende Funktion in einer Datei mit dem Namen Get-MrPSVersion.ps1
.
function Get-MrPSVersion {
$PSVersionTable
}
Wenn Sie das Skript ausführen, wird angezeigt, dass nichts passiert.
.\Get-MrPSVersion.ps1
Der Versuch, die Funktion aufzurufen, führt zu einem Fehler, da sie nicht in den Arbeitsspeicher geladen wird.
Get-MrPSVersion
Get-MrPSVersion : The term 'Get-MrPSVersion' is not recognized as the name
of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and
try again.
At line:1 char:1
+ Get-MrPSVersion
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrPSVersion:String) [],
CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Sie können überprüfen, ob Funktionen in den Arbeitsspeicher geladen werden, indem Sie ihr Vorhandensein auf der Funktion "PSDrive" überprüfen.
Get-ChildItem -Path Function:\Get-MrPSVersion
Get-ChildItem : Cannot find path 'Get-MrPSVersion' because it does not
exist.
At line:1 char:1
+ Get-ChildItem -Path Function:\Get-MrPSVersion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrPSVersion:String) [Get
-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.Ge
tChildItemCommand
Das Problem beim Ausführen des Skripts, das die Funktion definiert, besteht darin, dass es in den Skriptbereich geladen wird. Nach Abschluss der Ausführung des Skripts verwirft PowerShell diesen Bereich zusammen mit der Funktion.
Damit die Funktion nach der Ausführung des Skripts verfügbar bleibt, muss sie in den globalen Bereich geladen werden. Sie können dies erreichen, indem Sie die Skriptdatei per Dot-Sourcing einbinden. Sie können zu diesem Zweck einen relativen Pfad verwenden.
. .\Get-MrPSVersion.ps1
Sie können auch den vollständigen Pfad zum Skript verwenden, wenn Sie es mit Dot-Sourcing aufrufen.
. C:\Demo\Get-MrPSVersion.ps1
Wenn ein Teil des Pfads in einer Variablen gespeichert ist, können Sie ihn mit dem Rest des Pfads kombinieren. Es ist nicht nötig, Zeichenfolgen zu verketteten, um dies zu tun.
$Path = 'C:\'
. $Path\Get-MrPSVersion.ps1
Wenn Sie nun die Funktion PSDrive überprüfen, wird angezeigt, dass die Get-MrPSVersion
Funktion verfügbar ist.
Get-ChildItem -Path Function:\Get-MrPSVersion
CommandType Name Version
----------- ---- -------
Function Get-MrPSVersion
Skriptmodule
In PowerShell ist ein Skriptmodul einfach eine .psm1
Datei, die eine oder mehrere Funktionen enthält, genau wie ein normales Skript, aber mit einer anderen Dateierweiterung.
Wie erstellen Sie ein Skriptmodul? Sie könnten annehmen, dass ein Befehl so etwas wie New-Module
heißt. Diese Annahme ist eine vernünftige Vermutung, aber dieser Befehl erstellt tatsächlich ein dynamisches Modul, nicht ein Skriptmodul.
Dieses Szenario ist eine gute Erinnerung daran, die Hilfedokumentation immer zu lesen, auch wenn ein Befehlsname genau so aussieht, wie Sie es brauchen.
help New-Module
NAME
New-Module
SYNOPSIS
Creates a new dynamic module that exists only in memory.
SYNTAX
New-Module [-Name] <System.String> [-ScriptBlock]
<System.Management.Automation.ScriptBlock> [-ArgumentList
<System.Object[]>] [-AsCustomObject] [-Cmdlet <System.String[]>]
[-Function <System.String[]>] [-ReturnResult] [<CommonParameters>]
DESCRIPTION
The `New-Module` cmdlet creates a dynamic module from a script block.
The members of the dynamic module, such as functions and variables, are
immediately available in the session and remain available until you
close the session.
Like static modules, by default, the cmdlets and functions in a dynamic
module are exported and the variables and aliases are not. However, you
can use the Export-ModuleMember cmdlet and the parameters of
`New-Module` to override the defaults.
You can also use the **AsCustomObject** parameter of `New-Module` to return
the dynamic module as a custom object. The members of the modules, such
as functions, are implemented as script methods of the custom object
instead of being imported into the session.
Dynamic modules exist only in memory, not on disk. Like all modules,
the members of dynamic modules run in a private module scope that is a
child of the global scope. Get-Module cannot get a dynamic module, but
Get-Command can get the exported members.
To make a dynamic module available to `Get-Module`, pipe a `New-Module`
command to Import-Module, or pipe the module object that `New-Module`
returns to `Import-Module`. This action adds the dynamic module to the
`Get-Module` list, but it does not save the module to disk or make it
persistent.
RELATED LINKS
Online Version: https://learn.microsoft.com/powershell/module/microsoft.
powershell.core/new-module?view=powershell-5.1&WT.mc_id=ps-gethelp
Export-ModuleMember
Get-Module
Import-Module
Remove-Module
about_Modules
REMARKS
To see the examples, type: "Get-Help New-Module -Examples".
For more information, type: "Get-Help New-Module -Detailed".
For technical information, type: "Get-Help New-Module -Full".
For online help, type: "Get-Help New-Module -Online"
Im vorherigen Kapitel wurde erwähnt, dass Funktionen genehmigte Verben verwenden sollten. Andernfalls generiert PowerShell eine Warnung, wenn das Modul importiert wird.
Im folgenden Beispiel wird das New-Module
Cmdlet verwendet, um ein dynamisches Modul im Arbeitsspeicher zu erstellen, insbesondere, um zu veranschaulichen, was passiert, wenn Sie kein genehmigtes Verb verwenden.
New-Module -Name MyModule -ScriptBlock {
function Return-MrOsVersion {
Get-CimInstance -ClassName Win32_OperatingSystem |
Select-Object -Property @{Label='OperatingSystem';Expression={$_.Caption}}
}
Export-ModuleMember -Function Return-MrOsVersion
} | Import-Module
WARNING: The names of some imported commands from the module 'MyModule' include
unapproved verbs that might make them less discoverable. To find the commands with
unapproved verbs, run the Import-Module command again with the Verbose parameter. For a
list of approved verbs, type Get-Verb.
Obwohl Sie das New-Module
Cmdlet im vorherigen Beispiel verwendet haben, wie bereits erwähnt, ist es nicht der Befehl zum Erstellen von Skriptmodulen in PowerShell.
Wenn Sie ein Skriptmodul erstellen möchten, speichern Sie Ihre Funktionen in einer .psm1
Datei. Speichern Sie beispielsweise die folgenden beiden Funktionen in einer Datei mit dem Namen MyScriptModule.psm1
.
function Get-MrPSVersion {
$PSVersionTable
}
function Get-MrComputerName {
$env:COMPUTERNAME
}
Versuchen Sie, eine der Funktionen auszuführen.
Get-MrComputerName
Wenn Sie die Funktion aufrufen, wird eine Fehlermeldung angezeigt, die besagt, dass PowerShell sie nicht finden kann. Wie zuvor zeigt die Überprüfung der Funktion: PSDrive, dass sie nicht in den Arbeitsspeicher geladen wurde.
Get-MrComputerName : The term 'Get-MrComputerName' is not recognized as the
name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is
correct and try again.
At line:1 char:1
+ Get-MrComputerName
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-MrComputerName:String) [
], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Um die Funktion verfügbar zu machen, können Sie die MyScriptModule.psm1
Datei mithilfe des Import-Module
Cmdlets manuell importieren.
Import-Module C:\MyScriptModule.psm1
PowerShell hat das automatische Laden von Modulen in Version 3 eingeführt. Um dieses Feature nutzen zu können, muss das Skriptmodul in einem Ordner mit demselben Basisnamen wie die .psm1
Datei gespeichert werden. Dieser Ordner muss sich in einem der Verzeichnisse befinden, die in der Umgebungsvariable $env:PSModulePath
angegeben sind.
$env:PSModulePath
Die Ausgabe von $env:PSModulePath
ist schwer zu lesen.
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules;C:\Program Files\Wind
owsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\
Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
Um die Ergebnisse besser lesbar zu machen, teilen Sie die Pfade anhand des Semikolons als Trennzeichen, sodass jeder auf seiner eigenen Zeile erscheint.
$env:PSModulePath -split ';'
Die ersten drei Pfade in der Liste sind die standardmäßigen Modulstandorte. SQL Server Management Studio hat den letzten Pfad hinzugefügt, wenn Sie ihn installiert haben.
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\Windows\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
Damit das Modulautoladen funktioniert, muss die MyScriptModule.psm1
-Datei in einem Ordner mit dem Namen MyScriptModule
platziert werden, und dieser Ordner muss sich direkt innerhalb eines der aufgelisteten Pfade befinden.
$env:PSModulePath
.
Nicht alle diese Pfade sind gleichermaßen nützlich. Beispielsweise ist der aktuelle Benutzerpfad auf meinem System nicht der erste in der Liste. Das liegt daran, dass ich mich bei Windows mit einem anderen Konto anmeldee als das, das ich zum Ausführen von PowerShell verwende. Es verweist also nicht auf den Ordner "Dokumente" meines Benutzers.
Der zweite Pfad ist der AllUsers-Pfad , in dem ich alle meine Module speichern kann.
Der dritte Pfad verweist auf C:\Windows\System32
einen geschützten Systemspeicherort. Nur Microsoft sollte Module dort platzieren, da sie unter die Verzeichnisstruktur des Betriebssystems fällt.
Nachdem Sie die .psm1
Datei in einem entsprechenden Ordner in einem dieser Pfade platziert haben, lädt PowerShell das Modul automatisch, wenn Sie einen seiner Befehle zum ersten Mal aufrufen.
Modulmanifeste
Jedes Modul sollte ein Modulmanifest enthalten, bei dem es sich um eine .psd1
Datei handelt, die Metadaten zum Modul enthält. Während die .psd1
Erweiterung für Manifeste verwendet wird, sind nicht alle .psd1
Dateien Modulmanifeste. Sie können sie auch für andere Zwecke verwenden, z. B. das Definieren von Umgebungsdaten in einem DSC
Konfiguration.
Sie können ein Modulmanifest mithilfe des New-ModuleManifest
Cmdlets erstellen. Der einzige erforderliche Parameter ist "Path", aber damit das Modul ordnungsgemäß funktioniert, müssen Sie auch den Parameter "RootModule " angeben.
Es empfiehlt sich, Werte wie "Autor" und " Beschreibung" einzuschließen, insbesondere, wenn Sie ihr Modul mit PowerShellGet in einem NuGet-Repository veröffentlichen möchten. Diese Felder sind in diesem Szenario erforderlich.
Eine schnelle Möglichkeit, um festzustellen, ob ein Modul über kein Manifest verfügt, besteht darin, seine Version zu überprüfen.
Get-Module -Name MyScriptModule
Eine Versionsnummer von 0.0
ist ein klares Zeichen dafür, dass ein Modul kein Manifest besitzt.
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 MyScriptModule {Get-MrComputer...
Sie sollten alle empfohlenen Details beim Erstellen eines Modulmanifests einschließen, um sicherzustellen, dass Ihr Modul gut dokumentiert ist und bereit für die Freigabe oder Veröffentlichung ist.
$moduleManifestParams = @{
Path = "$env:ProgramFiles\WindowsPowerShell\Modules\MyScriptModule\MyScriptModule.psd1"
RootModule = 'MyScriptModule'
Author = 'Mike F. Robbins'
Description = 'MyScriptModule'
CompanyName = 'mikefrobbins.com'
}
New-ModuleManifest @moduleManifestParams
Wenn Sie beim anfänglichen Erstellen des Modulmanifests Werte weglassen, können Sie sie später mithilfe des Update-ModuleManifest
Cmdlets hinzufügen oder aktualisieren. Vermeiden Sie, das Manifest neu zu erstellen, sobald New-ModuleManifest
Sie es erstellt haben, da dadurch eine neue GUID generiert wird.
Definieren öffentlicher und privater Funktionen
Manchmal enthält Ihr Modul möglicherweise Hilfsfunktionen, die Sie benutzern nicht zur Verfügung stellen möchten. Diese privaten Funktionen werden intern von anderen Funktionen im Modul verwendet, jedoch nicht für Benutzer verfügbar gemacht. Es gibt einige Möglichkeiten, dieses Szenario zu behandeln.
Wenn Sie keine bewährten Methoden ausführen und nur über eine .psm1
Datei ohne ordnungsgemäße Modulstruktur verfügen, besteht die einzige Option darin, die Sichtbarkeit mithilfe des Export-ModuleMember
Cmdlets zu steuern. Mit dieser Option können Sie explizit definieren, welche Funktionen direkt in der .psm1
Skriptmoduldatei verfügbar gemacht werden sollen, wobei alles andere standardmäßig privat bleibt.
Im folgenden Beispiel wird nur die Get-MrPSVersion
Funktion benutzern Ihres Moduls verfügbar gemacht, während die Get-MrComputerName
Funktion intern für andere Funktionen innerhalb des Moduls zugänglich bleibt.
function Get-MrPSVersion {
$PSVersionTable
}
function Get-MrComputerName {
$env:COMPUTERNAME
}
Export-ModuleMember -Function Get-MrPSVersion
Bestimmen Sie, welche Befehle öffentlich im MyScriptModule-Modul verfügbar sind.
Get-Command -Module MyScriptModule
CommandType Name Version
----------- ---- -------
Function Get-MrPSVersion 1.0
Wenn Sie Ihrem Modul ein Modulmanifest hinzufügen, empfiehlt es sich, die Funktionen, die Sie exportieren möchten, explizit im Abschnitt "FunctionsToExport " auflisten. Mit dieser Option können Sie steuern, was Sie Benutzern aus der .psd1
Modulmanifestdatei zur Verfügung stellen.
FunctionsToExport = 'Get-MrPSVersion'
Sie müssen Export-ModuleMember
nicht sowohl in der .psm1
Datei als auch im FunctionsToExport
Abschnitt im Modulmanifest verwenden. Jeder Ansatz reicht allein aus.
Zusammenfassung
In diesem Kapitel haben Sie erfahren, wie Sie Ihre Funktionen in PowerShell in ein Skriptmodul umwandeln. Außerdem haben Sie bewährte Methoden zum Erstellen von Skriptmodulen untersucht, einschließlich der Wichtigkeit des Hinzufügens eines Modulmanifests zum Definieren von Metadaten und Zum Verwalten exportierter Befehle.
Rezension
- Wie erstellen Sie ein Skriptmodul in PowerShell?
- Warum ist es wichtig, genehmigte Verben für Ihre Funktionsnamen zu verwenden?
- Wie erstellen Sie ein Modulmanifest in PowerShell?
- Welche beiden Möglichkeiten gibt es, nur bestimmte Funktionen aus einem Modul zu exportieren?
- Welche Bedingungen müssen erfüllt sein, damit ein Modul automatisch laden kann, wenn Sie einen der zugehörigen Befehle ausführen?