none
Abbrechen Button bei Read-Host abfragen ? RRS feed

  • Frage

  • Hallo zusammen,

    ich habe als Neuling gerade ein paar Abfragen in Powershell definiert, unter anderem wird man nach dem LogonName gefragt. Die Eingabe lasse ich dann auf Leerzeichen prüfen, solange das Eingabefeld leer ist und man "OK" drückt kommt die gewünschte Meldung.

    Jedoch möchte ich das wenn der "Abbrechen" Button gedrückt wird das Script beendet wird.

    Dazu habe ich aber leider bisher weder hier noch bei Google was gefunden, vielleicht könnt Ihr mir da helfen ??

    Hier der Scriptauszug:

    do{$User= Read-Host 'Bitte LogonName eingeben?'
    IF ($User -eq $null){$wshshell = New-Object -ComObject wscript.shell; $wshshell.Popup("Eingabefeld leer, bitte LogonName eingeben.")}}
    while ($User -eq $null)

    Gruß

    Adrian_F

    Mittwoch, 21. November 2012 10:22

Antworten

  • Ok, also erstmal gibt es keinen Grund hier VBscript zu benutzen wenn Powershell das auch kann. Eine Forms-Mesagebox liefert schöne Rückgabewerte, schau mal in den Code unten, ist eigentlich selbsterklärend.
     
    Desweiteren funktioniert deine Abfrage:

    ($User -eq $null)

    nicht wirklich, da $user auch bei leerer Box (oder nach Eingabe z.b. eines Leerzeichens) ein String ist, also nicht $null. Daher solltest du hier ein anderes Abfragekriterium benutzen. Da ich nicht weiß, wie genau dein Input aussehen kann, habe ich mal "Mindestlänge > 1" genommen. Je nachdem wie wichtig die Richtigkeit der Eingabe ist, würde ich hier aber sogar genauer auf gültige Logonnamen prüfen, z.b. mit einem Regex-Muster. (sag Bescheid wenn du dabei Hilfe brauchst)
     
    Was den Abbruch betrifft, ich habe mal "break" genommen, d.h. das Script wird nicht komplett beendet, sondern es wird nur die Schleife unterbrochen und das Script wird nach der while-Zeile weiter abgearbeitet. So könntest du diesen Fall noch weiter behandeln. Wenn du das nicht willst ersetze einfach das break durch exit.

    So sollte es gehen:

     

    do{
    	$User= Read-Host 'Bitte LogonName eingeben?'
    	If ($User.Length -le 1){
    		$mgsbox =  [Windows.Forms.MessageBox]::Show("Eingabefeld leer, bitte LogonName eingeben.", "Achtung!", [Windows.Forms.MessageBoxButtons]::OKCancel, [Windows.Forms.MessageBoxIcon]::Warning)
    		if( $mgsbox -eq [System.Windows.Forms.DialogResult]::CANCEL ) {
    			break
    		}
    	}
    }
    while ($User.Length -le 1)
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".


    Mittwoch, 21. November 2012 11:49
    Moderator
  • @Denniver
    Da ich meine Lösung auch grad fertig hatte poste ich sie auch mal :-)
    Ich bin auch der Meinung, dass man den Windows Scripting Host hinter sich lassen sollte (veraltet).
    Den DialogResult zu nutzen ging mir für diesen Fall zu weit in die Windows Forms, deshalb habe ich das verworfen und es etwas "rustikaler" angelegt.
    Außerdem wird in meinem Beispiel gezeigt wie man auf eine "Taste" (Eingabe von dem Buchstaben A) reagiert.

    @Adrian
    Eine Echte Tasten Abfrage wie z.B. das Abfragen der Taste ESC, ist in PowerShell zwar auch Möglich, ist aber entweder nicht zu empfehlen $host.UI.RawUI.ReadKey, da dies von dem PowerShell Programm (Host) abhängig ist oder sehr aufwendig mit .NET und Events zu machen ist.

    Do {
        
        # Schleife wird erst beendet wenn $SchleifeBeenden = $True ist !
        $SchleifeBeenden = $False
        
        # User abfragen die Variable User wird Immer als Typ String von Read-Host zurückgegeben, desshalb können wir nachher die Length abfragen
        $User= Read-Host 'Bitte LogonName eingeben? (A eingeben zum Abbrechen)'
        
        # Wenn der User A oder a eingegeben hat wird $SchleifeBeenden auf $True gesetzt
        IF (($User -eq 'A') -or ($User -eq 'a')){
            [windows.forms.messagebox]::Show('Abbruch gewählt! Und Tschüss!')
            # Die Variable $User wieder leeren (das A entfernen)
            $User = ''
            # $SchleifeBeenden auf $True setzen damit die Schleife beendet wird
            $SchleifeBeenden = $True        
        }
        
        # Wenn die String Variable $User einen Wert enthält (length grösser 0) dann wird $SchleifeBeenden auf $True gesetzt
        IF ($User.Length -gt 0){
            
            # User begrüssen
            [windows.forms.messagebox]::Show('Willkommen $User')
            
            # $SchleifeBeenden auf $True setzen damit die Schleife beendet wird
            $SchleifeBeenden = $True        
        }
    
        } # end switch
    } while ($SchleifeBeenden -eq $False) # Schleife wird beendet wenn $SchleifeBeenden = $True ist 


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Mittwoch, 21. November 2012 12:49
    • Als Antwort markiert Adrian_F Mittwoch, 21. November 2012 14:50
    Mittwoch, 21. November 2012 12:48
  • Du sprichst immer von Cancel Button der Read-Host Abfrage!
    Read-Host hat definitif KEINEN cancel Button!

    Das Verwirrende ist, wenn du Read-Host in der PowerShell ISE oder PowerGUI ausführst, dann wird dir eine Grafische Box angezeigt, die aber wenig mit Read-Host zu tun hat!
    Nimm Bitte mal eine "normale" PowerShell im Konsolen Fenster und gib dort folgendes ein:

    Read-Host 'Wie heißt du?'

    Du wirst sehen, dass keine GUI Box angezeigt wird! Dies ist das Normale verhalten! Deshalb gibt es kein Cancel Button obwohl du einen siehst! ;-))

    PowerShell ist sozusagen in 2 Teile aufgeteilt:
    1. die PowerShell Engine, die die Befehle ausführt und verarbeitet
    2. der PowerShell Host, ist "nur" das Programm das die Befehle entgegen nimmt, diese Befehle an die Engine zur Verarbeitung weiter gibt und dann wieder das Ergebnis der Engine anzeigt.

    Der Host ist ohne Engine also nur eine leere Hülle wie ein Auto ohne Motor!
    Die PowerShell ist der Motor!
    Der Host die Karosserie!
    Mit den XXX-Host Cmdlets wird dann der Host, das Programm z.B.  PowerGUI oder PowerShell ISE, oder PowerShell Plus angesprochen.
    Das Konsolenfenster ist auch "nur" so ein Host. Dieser Host hat aber nicht die Angewohnheit dir eine GUI Box zu präsentieren!
    Die GUI Box wird also vom Host Produziert und die PowerShell Engine hat davon keine Ahnung! Der Cancel Button wird ebenso vom Host-Programm verarbeitet, die PowerShell bekommt in diesem Fall nur einen Leeren String vom Host zurück!

    Leider kommst du auch nicht an den Cancel Button aus der VisualBasic Inputbox heran!

    Wenn du einen echten Cancel Button haben möchtest, dann musst du dir eine komplett eigenen Inputbox mit Windows Forms erstellen.
    SCHAU MEIN VIDEO AN! ;-))


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Freitag, 23. November 2012 09:42
    • Als Antwort markiert Adrian_F Dienstag, 27. November 2012 07:53
    Donnerstag, 22. November 2012 15:41

Alle Antworten

  • Ok, also erstmal gibt es keinen Grund hier VBscript zu benutzen wenn Powershell das auch kann. Eine Forms-Mesagebox liefert schöne Rückgabewerte, schau mal in den Code unten, ist eigentlich selbsterklärend.
     
    Desweiteren funktioniert deine Abfrage:

    ($User -eq $null)

    nicht wirklich, da $user auch bei leerer Box (oder nach Eingabe z.b. eines Leerzeichens) ein String ist, also nicht $null. Daher solltest du hier ein anderes Abfragekriterium benutzen. Da ich nicht weiß, wie genau dein Input aussehen kann, habe ich mal "Mindestlänge > 1" genommen. Je nachdem wie wichtig die Richtigkeit der Eingabe ist, würde ich hier aber sogar genauer auf gültige Logonnamen prüfen, z.b. mit einem Regex-Muster. (sag Bescheid wenn du dabei Hilfe brauchst)
     
    Was den Abbruch betrifft, ich habe mal "break" genommen, d.h. das Script wird nicht komplett beendet, sondern es wird nur die Schleife unterbrochen und das Script wird nach der while-Zeile weiter abgearbeitet. So könntest du diesen Fall noch weiter behandeln. Wenn du das nicht willst ersetze einfach das break durch exit.

    So sollte es gehen:

     

    do{
    	$User= Read-Host 'Bitte LogonName eingeben?'
    	If ($User.Length -le 1){
    		$mgsbox =  [Windows.Forms.MessageBox]::Show("Eingabefeld leer, bitte LogonName eingeben.", "Achtung!", [Windows.Forms.MessageBoxButtons]::OKCancel, [Windows.Forms.MessageBoxIcon]::Warning)
    		if( $mgsbox -eq [System.Windows.Forms.DialogResult]::CANCEL ) {
    			break
    		}
    	}
    }
    while ($User.Length -le 1)
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".


    Mittwoch, 21. November 2012 11:49
    Moderator
  • @Denniver
    Da ich meine Lösung auch grad fertig hatte poste ich sie auch mal :-)
    Ich bin auch der Meinung, dass man den Windows Scripting Host hinter sich lassen sollte (veraltet).
    Den DialogResult zu nutzen ging mir für diesen Fall zu weit in die Windows Forms, deshalb habe ich das verworfen und es etwas "rustikaler" angelegt.
    Außerdem wird in meinem Beispiel gezeigt wie man auf eine "Taste" (Eingabe von dem Buchstaben A) reagiert.

    @Adrian
    Eine Echte Tasten Abfrage wie z.B. das Abfragen der Taste ESC, ist in PowerShell zwar auch Möglich, ist aber entweder nicht zu empfehlen $host.UI.RawUI.ReadKey, da dies von dem PowerShell Programm (Host) abhängig ist oder sehr aufwendig mit .NET und Events zu machen ist.

    Do {
        
        # Schleife wird erst beendet wenn $SchleifeBeenden = $True ist !
        $SchleifeBeenden = $False
        
        # User abfragen die Variable User wird Immer als Typ String von Read-Host zurückgegeben, desshalb können wir nachher die Length abfragen
        $User= Read-Host 'Bitte LogonName eingeben? (A eingeben zum Abbrechen)'
        
        # Wenn der User A oder a eingegeben hat wird $SchleifeBeenden auf $True gesetzt
        IF (($User -eq 'A') -or ($User -eq 'a')){
            [windows.forms.messagebox]::Show('Abbruch gewählt! Und Tschüss!')
            # Die Variable $User wieder leeren (das A entfernen)
            $User = ''
            # $SchleifeBeenden auf $True setzen damit die Schleife beendet wird
            $SchleifeBeenden = $True        
        }
        
        # Wenn die String Variable $User einen Wert enthält (length grösser 0) dann wird $SchleifeBeenden auf $True gesetzt
        IF ($User.Length -gt 0){
            
            # User begrüssen
            [windows.forms.messagebox]::Show('Willkommen $User')
            
            # $SchleifeBeenden auf $True setzen damit die Schleife beendet wird
            $SchleifeBeenden = $True        
        }
    
        } # end switch
    } while ($SchleifeBeenden -eq $False) # Schleife wird beendet wenn $SchleifeBeenden = $True ist 


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Mittwoch, 21. November 2012 12:49
    • Als Antwort markiert Adrian_F Mittwoch, 21. November 2012 14:50
    Mittwoch, 21. November 2012 12:48
  • Vielen Dank für die Antworten,

    habe die Lösung von Denniver bei mir gut einsetzten können.

    @Peter: Danke für den Tip mit der Keyboardabfrage, den werde ich bei Zeiten mit Sicherheit einsetzten könne, aber meine Idee war es den "Abbrechen" Button der MSGBOX abzufragen, da liess sich die Lösung von Denniver besser umsetzen.

    Gruß

    Adrian_F

    Mittwoch, 21. November 2012 14:50
  • Dieses Vorgehen dem User zwei verschiedenen Techniken "zuzumuten" ist eher unüblich, da meist versucht wird dem User das Konsolen Fenster nicht zu präsentieren.

    Man kann gut textuelle Abfrage Menüs im Konsolen Fenster gestalten und in der Konsole das "Frage und Antwort Spiel" abwickeln.

    Man kann mit der PowerShell auch z.B. die Inputbox benutzen um Daten Abzufragen oder Windows Forms oder WPF benutzen, um dem User statt der Konsole eine GUI anzuzeigen.
    Dies sind aber fortgeschrittene Techniken, die man erst einsetzen sollte wenn man die PowerShell Grundbegriffe beherrscht.

    Zu der Inputbox und den Windows Forms habe ich ein Video auf Youtube gemacht, schau mal rein :-)
    http://www.youtube.com/watch?v=y76LO5VIN24

    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Donnerstag, 22. November 2012 06:44
  • Vielen Dank @Peter

    aber das ganze Script beruht auf einer GUI für den User, die Read-Host Abfrage wird auch grafisch Angezeigt.

    Der User bekommt die Konsole so nicht zu sehen, da ich aber momentan mir alles aus dem Internet selber zusammensuche kann es schon mal vorkommen das ich unbewusst in VBscript oder andere Sprachen abrutsche.

    Werde mir die Inputbox nochmal genauer anschauen.

    Gruß

    Adrian_F

    Donnerstag, 22. November 2012 07:28
  • Hallo Nochmal,

    was mir gerade aufgefallen ist, das ich mit der Lösung von Denniver nur den CANCEL Button  der Winows.Forms.MessageBox abfrage.

    Ich würde aber gerne den CANCEL Button der Read-Host abfrage abfangen, ist das auch möglich ?

    Gruß

    Adrian_F

    Donnerstag, 22. November 2012 08:13
  • Du sprichst immer von Cancel Button der Read-Host Abfrage!
    Read-Host hat definitif KEINEN cancel Button!

    Das Verwirrende ist, wenn du Read-Host in der PowerShell ISE oder PowerGUI ausführst, dann wird dir eine Grafische Box angezeigt, die aber wenig mit Read-Host zu tun hat!
    Nimm Bitte mal eine "normale" PowerShell im Konsolen Fenster und gib dort folgendes ein:

    Read-Host 'Wie heißt du?'

    Du wirst sehen, dass keine GUI Box angezeigt wird! Dies ist das Normale verhalten! Deshalb gibt es kein Cancel Button obwohl du einen siehst! ;-))

    PowerShell ist sozusagen in 2 Teile aufgeteilt:
    1. die PowerShell Engine, die die Befehle ausführt und verarbeitet
    2. der PowerShell Host, ist "nur" das Programm das die Befehle entgegen nimmt, diese Befehle an die Engine zur Verarbeitung weiter gibt und dann wieder das Ergebnis der Engine anzeigt.

    Der Host ist ohne Engine also nur eine leere Hülle wie ein Auto ohne Motor!
    Die PowerShell ist der Motor!
    Der Host die Karosserie!
    Mit den XXX-Host Cmdlets wird dann der Host, das Programm z.B.  PowerGUI oder PowerShell ISE, oder PowerShell Plus angesprochen.
    Das Konsolenfenster ist auch "nur" so ein Host. Dieser Host hat aber nicht die Angewohnheit dir eine GUI Box zu präsentieren!
    Die GUI Box wird also vom Host Produziert und die PowerShell Engine hat davon keine Ahnung! Der Cancel Button wird ebenso vom Host-Programm verarbeitet, die PowerShell bekommt in diesem Fall nur einen Leeren String vom Host zurück!

    Leider kommst du auch nicht an den Cancel Button aus der VisualBasic Inputbox heran!

    Wenn du einen echten Cancel Button haben möchtest, dann musst du dir eine komplett eigenen Inputbox mit Windows Forms erstellen.
    SCHAU MEIN VIDEO AN! ;-))


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Freitag, 23. November 2012 09:42
    • Als Antwort markiert Adrian_F Dienstag, 27. November 2012 07:53
    Donnerstag, 22. November 2012 15:41
  • Hallo Peter,

    habe mein Fehler dank deiner Antwort gefunden, ich benutze zum Scripten den PowerGUI und dieser öffnet bei der Read-Host abfrage eine GUI-Box die auch einen CANCEL-Button hat  :-/

    Werde mir jetzt erstmal dein Video anschauen und dann das Script anpassen.

    Besten dank und Gruß

    Adrian_F

    Dienstag, 27. November 2012 07:53
  • Eine gute Möglichkeit mit Windows Forms eine eigenen Inputbox zu gestalten.
    http://technet.microsoft.com/en-us/library/ff730941.aspx


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Dienstag, 27. November 2012 08:26