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

Geschrieben

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?

 

 

 

 

Geschrieben (bearbeitet)
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
Geschrieben
#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?

Geschrieben (bearbeitet)

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
Geschrieben
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...

Geschrieben (bearbeitet)
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
  • Danke 1
Geschrieben

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.

  • Danke 1
Geschrieben

Ja Danke fĂŒr die Antworten und Tipps, hat sich geklĂ€rt, hatte in anderen Skript das eingebunden wurde die Fuktion/MenĂŒ bereits aufgerufen, nach RĂŒckkehr hat er dann immer wieder die Funktion gestartet. Danke, ich arbeite am Ablauf...

Geschrieben

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

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

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto fĂŒr unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...