Jump to content

Powershell - Skript beenden mit exit


Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Empfohlene Beiträge

Versuche mit PS ein paar Admin-Aufgaben zu erledigen, dazu habe ich ein Skript.ps1 mit Menü, welches dann ja nach Auswahl per Dot-Sourcing andere Skripts einbindet und davon Funktionen ausführt. Evtl. gibt es hier elegantere Wege, ich hab mal so angefangen, damit ich einen gewissen Überblick für die verschiedenen Bereiche bekomme.

 

Es ist nur "Kosmetik" aber mich interessiert weshalb bei mir im Skript.ps1 ein "exit" nach Switch-Auswahl nicht funktioniert. 

 

Write-Host "Hauptmenue"
Write-Host "=================================================="
Write-Host "1":" Benutzerverwaltung"
Write-Host "2":" Gruppenverwaltung"
Write-Host "--------------------------------------------------"
Write-Host "0":" zurück"
Write-Host "=================================================="
$input = Read-Host "Auswahl"

 

Bei 0 sollte er dann aus dem "Programm" gehen...:

Ich hätte es verschieden versucht, beim Switch mit: 

DEFAULT {exit}

oder eben explizit bei EIngabe von "0":

0 {exit}

 

Ich habe auch schon debugged, pause davor, was $input für einen Wert hat, alles passt, nur geht er bei allen anderen und vorallem auch nicht bei "0" komischer weise auf die Seite/Funktion welche eigentlich unter "1" geführt ist. Dies passiert aber nur wenn ich auch vorher irgendwo hinspringe, wenn ich das Skript öffne, die 0 drücke wird es sauber beendet mit exit, nur wenn ich vorher z.B. 1 drücke (hier kann ich dann mit 0 auch zurück zum Hauptmenue), dann geht hier das "exit" nicht und ich finde nicht heraus wieso.

 

Hat hier jemand Rat?

 

 

 

 

Link zu diesem Kommentar
vor 33 Minuten schrieb lisaluft:
 

Hat hier jemand Rat?

Yep ...  zeig uns bitte den relevanten Code. ;-)  ... ohne diesen, wird es bestenfalls "Raten auf hohem Niveau"!  ;-) 

 

Edit:

 

Nur schon mal als Tipp, wenn das vielleicht ein Projekt ist, welches Du in Zukunft ausbauen möchtest. Du könntest Dir die Arbeit erleichtern, wenn Du die Anzeige Deines Menüs etwas weniger statisch gestalltest:

$TaskList = @(
    'Benutzerverwaltung'
    'Gruppenverwaltung'
)

$Index = 1
$IndexedTaskList = foreach ($Task in $TaskList) {
    [PSCustomObject]@{
        Index = $Index
        Task = $Task
    }
    $Index++
}

Clear-Host
"`n`n`tAuswahl des Tasks:`n "
$IndexedTaskList | Format-Table -AutoSize -HideTableHeaders

Das mag für 2 auszuwählende Tasks etwas überkandidelt erschienen, aber wenn Dein Projekt wächst, wirst Du es vermutlich zu schätzen wissen. ;-) 

bearbeitet von BOfH_666
Link zu diesem Kommentar
#Einbindung Skripte
$m_benutzer = $PSScriptRoot + "\m_benutzer.ps1"
$m_gruppen = $PSScriptRoot + "\m_gruppen.ps1"

Function MyMain
{

#Hauptmenue
cls
Write-Host
Write-Host "Hauptmenue"
Write-Host "=================================================="
			Write-Host "1":" Benutzerverwaltung"
            Write-Host "2":" Gruppenverwaltung"
Write-Host "--------------------------------------------------"
            Write-Host "0":" EXIT"
Write-Host "=================================================="
$input = Read-Host "Auswahl"

Switch ($input)
0 {exit}
{
1 
{
. $m_benutzer
MyBenutzer
}
2
{
. $m_gruppen
MyGruppen
}
3
{
MyMain
}
DEFAULT {exit}
}

}
MyMain

 

0 oder DEFAULT funktionieren nicht nachdem ich zuvor auf 1 oder 2 war

 

Beispiel 1 schaut so aus damit ich auch wieder zurückkomme:

 

#Einbindung Skripte
$m_benutzer_neuanlage = $PSScriptRoot + "\m_benutzer_neuanlage.ps1"
$m_benutzer_namensaenderung = $PSScriptRoot + "\m_benutzer_namensaenderung.ps1"

Function MyBenutzer
{
cls
Write-Host
Write-Host "Benutzerverwaltung"
Write-Host "=================================================="
			Write-Host "1":" Neuanlage"
            Write-Host "2":" Namensänderung"
Write-Host "--------------------------------------------------"
            Write-Host "0":" zurück"
Write-Host "=================================================="
$input = Read-Host "Auswahl"

Switch ($input)
{
0 {MyMain}
1 
{
. $m_benutzer_neuanlage
MyBenutzerNeuanlage
}
2 
{
. $m_benutzer_namensaenderung
MyBenutzerAenderung
}
}
}

MyBenutzer

 

So komme ich mit 0 wieder zurück zum "Hauptmenü", aber dann geht dort 0 nicht, ich komme immer wieder zum Menü der Benutzer, dann wieder zurück und dann geht 0 im Hauptmenü, aber es sollte generell beim Hauptmenü funktionieren, oder was übersehe ich?

Link zu diesem Kommentar

OK.

Als erstes hast Du ihn Deinem MyMain einen Klammerfehler im switch-Statement. Das sollte so aussehen: 

Function MyMain {

    #Hauptmenue
    cls
    Write-Host
    Write-Host "Hauptmenue"
    Write-Host "=================================================="
    Write-Host "1":" Benutzerverwaltung"
    Write-Host "2":" Gruppenverwaltung"
    Write-Host "--------------------------------------------------"
    Write-Host "0":" EXIT"
    Write-Host "=================================================="
    $input = Read-Host "Auswahl"

    Switch ($input) {
        0 { exit }
        1 {
            . $m_benutzer
            MyBenutzer
        }
        2 {
            . $m_gruppen
            MyGruppen
        }
        3 {
            MyMain
        }
        DEFAULT { exit }
    }
}
MyMain

Darf ich fragen, welchen Code-Editor Du benutzt? Sowohl die Powershell_ISE als auch VSCode würden diesen Syntaxfehler entsprechend markieren.  ... oder ist das nur ein Copy-&-Paste-Fehler hier im Forum?  ;-) 

 

Jetzt wo die Klammern stimmen, solltest Du, auch wenn es vielleicht im Moment funktioniert, dringend die Variable $Input ändern. $Input ist eine für Powershell reservierte Variable, die nicht für eigene Zwecke benutzt/missbraucht werden sollte, ;-) 

 

vor 48 Minuten schrieb lisaluft:

0 oder DEFAULT funktionieren nicht nachdem ich zuvor auf 1 oder 2 war

Hmm ... das switch-Statement wird von oben nach unten abgearbeitet. Wenn Du die Option 1 wählst, bist Du über die 0 schon drüber. Das kann also nicht funktionieren. ;-)  ... und der Default-Zweig wird nur ausgeführt, wenn keine der zur Verfügung stehenden Optionen passt. 

Zitat

So komme ich mit 0 wieder zurück zum "Hauptmenü", aber dann geht dort 0 nicht, ich komme immer wieder zum Menü der Benutzer, dann wieder zurück und dann geht 0 im Hauptmenü, aber es sollte generell beim Hauptmenü funktionieren, oder was übersehe ich?

Wenn Du immer wieder in Dein Hauptmenü zurück möchtest, wirst Du eine while oder do Schleife benutzen müssen. 

 

Es macht übrigens nicht wirklich viel Sinn, die "extenen" Scripte erst mittels dot-Sourcing in Dein Hauptscript einzubinden, wenn der entsprechende Menüeintrag gewählt wird. Einfacher wäre es, wenn Du am Anfang Deines Scriptes einfach mittels: 

Get-ChildItem $PSScriptRoot -Filter *.ps1 |
    ForEach-Object {
        . $_.FullName
    }

alle weiteren Funktionen in den Scope Deines Hauptscriptes importiertest. Somit brauchst Du im Code nur noch mit den Funktionsnamen zu arbeiten.

 

Damit wären wir beim nächsten Thema: Funktionsnamen.

Wenn Du irgendwann mal Deine Scripte in Module umwandelst und diese vielleicht auch an Kollegen weitergeben möchtest, empfiehlt es sich, besonders für Funktionen, die direkt aufgerufen werden sollen, die gleiche Schreibweise zu benutzen, wie bei den eingebauten cmdlets - also <Verb>-<Nomen>. Das macht im Zweifel ihre Funktion direkt erkennbar und erleichtert das Verstehen und Debuggen. Empfehlenswerte Lektüre dazu ist The Unofficial PowerShell Best Practices and Style Guide.

 

 

bearbeitet von BOfH_666
Link zu diesem Kommentar
vor 54 Minuten schrieb BOfH_666:

OK.

Als erstes hast Du ihn Deinem MyMain einen Klammerfehler im switch-Statement. Das sollte so aussehen: 


Function MyMain {

    #Hauptmenue
    cls
    Write-Host
    Write-Host "Hauptmenue"
    Write-Host "=================================================="
    Write-Host "1":" Benutzerverwaltung"
    Write-Host "2":" Gruppenverwaltung"
    Write-Host "--------------------------------------------------"
    Write-Host "0":" EXIT"
    Write-Host "=================================================="
    $input = Read-Host "Auswahl"

    Switch ($input) {
        0 { exit }
        1 {
            . $m_benutzer
            MyBenutzer
        }
        2 {
            . $m_gruppen
            MyGruppen
        }
        3 {
            MyMain
        }
        DEFAULT { exit }
    }
}
MyMain

Darf ich fragen, welchen Code-Editor Du benutzt? Sowohl die Powershell_ISE als auch VSCode würden diesen Syntaxfehler entsprechend markieren.  ... oder ist das nur ein Copy-&-Paste-Fehler hier im Forum?  ;-) 

 

SORRY, Copy&Paste Fehler weil ich schon soviel rumprobiert habe, Klammer ist schon da.

 

vor 54 Minuten schrieb BOfH_666:

 

Jetzt wo die Klammern stimmen, solltest Du, auch wenn es vielleicht im Moment funktioniert, dringend die Variable $Input ändern. $Input ist eine für Powershell reservierte Variable, die nicht für eigene Zwecke benutzt/missbraucht werden sollte, ;-) 

 

Hab ich jetzt geändert.

 

vor 54 Minuten schrieb BOfH_666:

 

Hmm ... das switch-Statement wird von oben nach unten abgearbeitet. Wenn Du die Option 1 wählst, bist Du über die 0 schon drüber. Das kann also nicht funktionieren. ;-)  ... und der Default-Zweig wird nur ausgeführt, wenn keine der zur Verfügung stehenden Optionen passt. 

 

DAS verstehe ich nicht, ich bekomme doch das Menü, wähle dann aus und je nachdem geht er in die geswitchte Variabe, ist doch egal ob 0 vorher oder nachher kommt, den Code geht er doch mit der eingegebenen Auswahl durch, dann müsste er doch bei 0 exit machen?

 

vor 54 Minuten schrieb BOfH_666:

Wenn Du immer wieder in Dein Hauptmenü zurück möchtest, wirst Du eine while oder do Schleife benutzen müssen. 

 

Es macht übrigens nicht wirklich viel Sinn, die "extenen" Scripte erst mittels dot-Sourcing in Dein Hauptscript einzubinden, wenn der entsprechende Menüeintrag gewählt wird. Einfacher wäre es, wenn Du am Anfang Deines Scriptes einfach mittels: 


Get-ChildItem $PSScriptRoot -Filter *.ps1 |
    ForEach-Object {
        . $_.FullName
    }

alle weiteren Funktionen in den Scope Deines Hauptscriptes importiertest. Somit brauchst Du im Code nur noch mit den Funktionsnamen zu arbeiten.

 

Hab ich jetzt so gemacht, aber dann kommt nicht einmal mehr mein Hauptmenü, sondern es wird sofort das Menü vom anderen Skript für die Benuzterverwaltung (Funktion MyBenutzer) sofort geöffnet, ich bekomme das Hauptmenü gar nicht her.

 

#Einbindung Module
Get-ChildItem $PSScriptRoot -Filter *.ps1 | ForEach-Object {. $_.FullName}

Function MyMain
{

#Hauptmenue
cls
Write-Host
Write-Host "Hauptmenue"
Write-Host "=================================================="
			Write-Host "1":" Benutzerverwaltung"
            Write-Host "2":" Gruppenverwaltung"
Write-Host "--------------------------------------------------"
            Write-Host "0":" exit"
Write-Host "=================================================="
$auswahl = Read-Host "Auswahl"

Switch ($auswahl)
{
"0" {exit}
"1" 
{
MyBenutzer
}
"2"
{
MyGruppen
}
DEFAULT {exit}
}

}
MyMain

 

vor 54 Minuten schrieb BOfH_666:

 

Damit wären wir beim nächsten Thema: Funktionsnamen.

Wenn Du irgendwann mal Deine Scripte in Module umwandelst und diese vielleicht auch an Kollegen weitergeben möchtest, empfiehlt es sich, besonders für Funktionen, die direkt aufgerufen werden sollen, die gleiche Schreibweise zu benutzen, wie bei den eingebauten cmdlets - also <Verb>-<Nomen>. Das macht im Zweifel ihre Funktion direkt erkennbar und erleichtert das Verstehen und Debuggen. Empfehlenswerte Lektüre dazu ist The Unofficial PowerShell Best Practices and Style Guide.

 

 

 

Danke für den Tipp, das werde ich mir anschauen.

 

Hmm, hab jetzt nochmal getestet, ich bekomme dann mein Hauptmenue nicht mehr weil ich in den sonstigen *.ps1-Skripten die Funktionen gleich aufrufe, beim laden/einbinden schaut er sich die an und ruft dann gleich die Fuktion auf. Ich glaube ich muss hier mal an meinem Ablaufplan ein wenig arbeiten...

Link zu diesem Kommentar
vor 52 Minuten schrieb lisaluft:

SORRY, Copy&Paste Fehler weil ich schon soviel rumprobiert habe, Klammer ist schon da.

Cool. Ein Fehler weniger. ;-) 

Zitat

DAS verstehe ich nicht, ich bekomme doch das Menü,

Du erzeugst Dein "Menü" mit Write-Host. Damit ist das Menü vom eigentlichen Code völlig unabhängig. Das sind nur Pixel auf Deinem Bildschirm ohne weitere Funktion.  Wichtig ist der Code, den Du benutzt, um die Eingabe des Benutzers auszuwerten.  Davon hast Du aber bisher nur ein paar lose miteinander verbundene Schnipsel gezeigt. Damit kann ich leider nicht wirklich sehen, was Du in Deinem Code machst.

Zitat

wähle dann aus und je nachdem geht er in die geswitchte Variabe, ist doch egal ob 0 vorher oder nachher kommt, den Code geht er doch mit der eingegebenen Auswahl durch, dann müsste er doch bei 0 exit machen?

Aber nicht, wenn Du das switch-Statement bereits einmal erfolgreich durchlaufen hast. Dafür müsstest Du die Auswahl erneut erhalten - also das switch-Statement erneut ausführen - mit einer Schleife zum Beispiel.  ... es sei denn, ich habe Dich falsch verstanden.  ... kommt immer mal wieder vor ...  ;-) 

 

Vielleicht machst Du Dir einfach mal ein MockUp. Also ein Script-Gerüst, welches den Script-Ablauf zeigt, ohne die eigentlichen Funktionen auszuführen. So könntest Du die Menü-Struktur testen, ohne den Balast des Codes der Funktionen mitzuschleppen. Das macht es manchmal einfacher.

Zitat

Hab ich jetzt so gemacht, aber dann kommt nicht einmal mehr mein Hauptmenü, sondern es wird sofort das Menü vom anderen Skript für die Benuzterverwaltung (Funktion MyBenutzer) sofort geöffnet, ich bekomme das Hauptmenü gar nicht her.

Dann hast Du in Deinen externen Scripten irgendwo einen logischen Fehler. Hast Du eventuell im der Script-Datei mit der Funktionsdefinition für MyBenutzer, die Funktion MyBenutzer direkt aufgerufen?

 

Edit:

 

Hier mal ne kleine Demo:

$Menu = @'
Hauptmenue
==================================================
1 : Benutzerverwaltung
2 : Gruppenverwaltung
--------------------------------------------------
0 :  zurück
==================================================

'@
Clear-Host
Write-Host $Menu
function show-input {
    param (
        $BenutzerEingabe
    )
    "`n `t$BenutzerEingabe`n "
}

$Eingabe = Read-Host -Prompt "Bitte Zahl zwischen 1 und 5 eingeben "

switch ($Eingabe) {
    1 { show-input -BenutzerEingabe "Du hast wohl ne '1' eingegeben " }
    2 { show-input -BenutzerEingabe "Du hast wohl ne '2' eingegeben " }
    3 { show-input -BenutzerEingabe "Du hast wohl ne '3' eingegeben " }
    4 { show-input -BenutzerEingabe "Du hast wohl ne '4' eingegeben " }
    5 { show-input -BenutzerEingabe "Du hast wohl ne '5' eingegeben " }
    Default { show-input -BenutzerEingabe "Das muss irgendwas Anderes als 1 bis 5 gewesen sein!" }
}
}

Nachdem Du etwas Beliebiges an der Eingabeaufforderung eingegeben hast, wird das switch-Statement genau 1 mal durchlaufen und dann beendet.

bearbeitet von BOfH_666
Link zu diesem Kommentar

War mir jetzt zu viel zum Lesen - aber daß innerhalb von MyMain einfach immer wieder MyMain aufgerufen wird, habt Ihr schon geklärt? Damit landet man im Callstack immer tiefer, und jeder exit/return geht halt genau eine Ebene wieder zurück. 3 x die "2" ausgewählt heißt dann halt auch dreimal die 0 auszuwählen, um wieder "raus" zu kommen. Da wäre eine Do While $True Schleife besser.

Link zu diesem Kommentar

Hi,

 

ich glaube Olaf hatte es oben schon erwähnt. User-Input würde ich immer direkt validieren und nur gültige Eingaben akzeptieren:

# Do-Until
do{
	$Eingabe = Read-Host -Prompt "Bitte Zahl zwischen 1 und 5 eingeben "
}until($Eingabe in 1..5)

# While
$Eingabe = Read-Host -Prompt "Bitte Zahl zwischen 1 und 5 eingeben "
while (-not ($Eingabe -in 1..5)){
    Write-Host "Mööp! Falsche Eingabe!"
    $Eingabe = Read-Host -Prompt "Bitte Zahl zwischen 1 und 5 eingeben "    
}

Gruß

Jan

Link zu diesem Kommentar
Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Schreibe einen Kommentar

Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor-Fenster leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...