webentwicklung-frage-antwort-db.com.de

Wie definiere ich in PowerShell eine Funktion in einer Datei und rufe sie von der PowerShell-Befehlszeile aus auf?

Ich habe eine .ps1-Datei, in der ich benutzerdefinierte Funktionen definieren möchte.

Stellen Sie sich vor, die Datei heißt MyFunctions.ps1 und der Inhalt lautet wie folgt:

Write-Host "Installing functions"
function A1
{
    Write-Host "A1 is running!"
}
Write-Host "Done"

Um dieses Skript auszuführen und die A1-Funktion theoretisch zu registrieren, navigiere ich zu dem Ordner, in dem sich die .ps1-Datei befindet, und führe die Datei aus:

.\MyFunctions.ps1

Dies gibt aus:

Installing functions
Done

Wenn ich jedoch A1 anrufe, erhalte ich einfach die Fehlermeldung, dass es keinen Befehl/keine Funktion mit diesem Namen gibt:

The term 'A1' 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:3
+ A1 <<<<
    + CategoryInfo          : ObjectNotFound: (A1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Ich muss einige PowerShell-Konzepte missverstehen. Kann ich keine Funktionen in Skriptdateien definieren?

Hinweis dass ich meine Ausführungsrichtlinie bereits auf 'RemoteSigned' gesetzt habe. Und ich weiß, dass .ps1-Dateien mit einem Punkt vor dem Dateinamen ausgeführt werden:.\MyFile.ps1

182
willem

Versuchen Sie dies in der PowerShell-Befehlszeile:

. .\MyFunctions.ps1
A1

Der Punktoperator wird für das Script-Include verwendet.

204
rsc

Worüber Sie sprechen, heißt dot sourcing. Und es ist böse. Aber keine Sorge, es gibt eine bessere und einfachere Möglichkeit, mit modules das zu tun, was Sie wollen (es hört sich viel gruseliger an als es ist). Der Hauptvorteil der Verwendung von Modulen besteht darin, dass Sie sie bei Bedarf aus der Shell entfernen können. Dadurch wird verhindert, dass sich die Variablen in den Funktionen in die Shell schleichen Funktion in der Shell, und Sie werden sehen, was ich meine).

Benennen Sie daher zuerst die .ps1-Datei, die alle Funktionen enthält, in MyFunctions.psm1 um (Sie haben gerade ein Modul erstellt!). Damit ein Modul ordnungsgemäß geladen werden kann, müssen Sie einige spezifische Schritte mit der Datei ausführen. Damit Import-Module das Modul zuerst sehen kann (Sie verwenden dieses Cmdlet, um das Modul in die Shell zu laden), muss es sich an einem bestimmten Speicherort befinden. Der Standardpfad für den Modulordner lautet $ home\Documents\WindowsPowerShell\Modules.

Erstellen Sie in diesem Ordner einen Ordner mit dem Namen MyFunctions und platzieren Sie die Datei MyFunctions.psm1 darin (die Moduldatei muss sich in einem Ordner mit genau demselben Namen wie die PSM1-Datei befinden).

Sobald dies erledigt ist, öffnen Sie PowerShell und führen Sie den folgenden Befehl aus:

Get-Module -listavailable

Wenn Sie MyFunctions sehen, haben Sie es richtig gemacht, und Ihr Modul ist bereit zum Laden (um sicherzustellen, dass dies richtig eingerichtet ist, müssen Sie dies nur einmal tun).

Um das Modul zu verwenden, geben Sie Folgendes in die Shell ein (oder fügen Sie diese Zeile in Ihr $ -Profil ein oder setzen Sie diese als erste Zeile in ein Skript):

Import-Module MyFunctions

Sie können jetzt Ihre Funktionen ausführen. Das Coole daran ist, dass, wenn Sie erst einmal 10-15 Funktionen haben, Sie den Namen eines Paares vergessen werden. Wenn Sie sie in einem Modul haben, können Sie den folgenden Befehl ausführen, um eine Liste aller Funktionen in Ihrem Modul zu erhalten:

Get-Command -module MyFunctions

Es ist ziemlich süß, und die kleine Anstrengung, die man auf der Vorderseite aufsetzen muss, ist WAY wert.

183
JoeG

. "$PSScriptRoot\MyFunctions.ps1" MyA1Func

Verfügbar ab v3, davor siehe Wie erhalte ich den Dateisystemspeicherort eines PowerShell-Skripts? . Es ist sehr gängig. 

P.S. Ich abonniere nicht die Regel "Alles ist ein Modul". Meine Skripte werden von anderen Entwicklern außerhalb von GIT verwendet. Daher möchte ich keine Sachen an einem bestimmten Ort platzieren oder Systemumgebungsvariablen ändern, bevor mein Skript ausgeführt wird. Es ist nur ein Skript (oder zwei oder drei).

15
yzorg

Sie können sicherlich Funktionen in Skriptdateien definieren (ich neige dann dazu, sie beim Laden über mein Powershell-Profil zu laden).

Zuerst müssen Sie überprüfen, ob die Funktion geladen ist, indem Sie Folgendes ausführen:

ls function:\ | where { $_.Name -eq "A1"  }

Und überprüfen Sie, ob es in der Liste erscheint (sollte eine Liste von 1 sein!), Und lassen Sie uns wissen, welche Ausgabe Sie erhalten!

6
Jonny

Sie können folgende Funktionen hinzufügen:

c:\Users\David\Documents\WindowsPowerShell\profile.ps1

Eine Funktion wird verfügbar sein.

3
David Morrow

Wenn Ihre Datei nur eine Hauptfunktion hat, die Sie aufrufen/anzeigen möchten, können Sie die Datei auch mit folgendem Befehl starten:

Param($Param1)

Sie können es dann anrufen, z. wie folgt:

.\MyFunctions.ps1 -Param1 'value1'

Dies macht es viel bequemer, wenn Sie nur diese Funktion aufrufen möchten, ohne die Funktion importieren zu müssen.

2
bergmeister

Angenommen, Sie haben eine Moduldatei namens Dummy-Name.psm1, die eine Methode namens Function-Dumb () hat. 

Import-Module "Dummy-Name.psm1";
Get-Command -Module "Function-Dumb";
#
#
Function-Dumb;
0
Bytekoder