none
Shutdown Script mit Interaktion und Zeit RRS feed

  • Frage

  • Moin Moin,

    ich ärgere mich seit 2 Tagen mit den Script rum (ich muss dazu sagen das ich absolut keine Ahnung habe was Programmierung oder Powershell angeht :D habe aber einiges gelesen und schon was gebastelt) und hoffe ihr könnt mir evtl sagen wo der Fehler liegt. Ich möchte ein Script schreiben in dem ich gefragt werde ob ich den PC herunterfahren möchte oder nicht das funktioniert soweit sogar grafisch. Allerdings hätte ich gerne das wenn ich 30 Sek nicht interagiere  oder bei der Abfrage auf Ja drücke das der PC herunterfährt, ich hab allerdings es nur geschafft das der PC ausgeht wenn ich auf ja drücke oder eben bei nein nicht runterfährt könnt ihr mir dort evtl en Tipp geben wie ich das am besten Umsetze.

    Anbei mein Code:


    $wPowerShell=new-object -comobject wscript.shell

    $Wartezeit = 0 # Dauer wie lang das Fenster offen bleibt bei keiner Eingabe
    $Schaltfläche = 4 # Schaltfläche Ja und Nein

    $Antwort=$wPowershell.popup("Soll der PC Heruntergefahren werden?",$Wartezeit,"Shutdown",$Schaltfläche)

    # Abfrage starten
    if ($Antwort-eq 6 )  # Fall "Ja" oder "Yes" gedrückt wurde...

    {
    shutdown -s -f
    }
    else  # Fall "Nein" oder "No" gedrückt wurde...
    {
    exit
    }

    # Code-Ende



    • Bearbeitet an-dre Mittwoch, 23. Juli 2014 10:08 Wartezeit Kommentar ändern
    Mittwoch, 23. Juli 2014 06:48

Antworten

  •   

    Ich befürchte so ganz einfach ist das ganze nicht. Du hast aber Glück, ich habe gerade sowas mit Winforms für meinen nächsten SnippetManager gebastelt.

    Ich habs mal für deine Bedürfnisse angepasst:
      

    cls
    $countdown = 30 # in seconds
    [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    
    #~~< Messagebox >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Messagebox = New-Object System.Windows.Forms.Form
    $Messagebox.ClientSize = "324, 166"
    $Messagebox.FormBorderStyle = "FixedToolWindow"
    $Messagebox.StartPosition = 1  # center sceen
    #~~< Button: No >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $ButtonNo = New-Object System.Windows.Forms.Button
    $ButtonNo.Location = "185, 115"
    $ButtonNo.Size = "75, 23"
    $ButtonNo.Text = "Nein"
    $ButtonNo.UseVisualStyleBackColor = $true
    $Messagebox.CancelButton = $ButtonNo
    #~~< Label: CountDownText >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $LabelCountDownText = New-Object System.Windows.Forms.Label
    $LabelCountDownText.Font =  "Segoe UI, 8pt"
    $LabelCountDownText.Location = "37, 59"
    $LabelCountDownText.Size = "223, 27"
    $LabelCountDownText.TabIndex = 3
    $LabelCountDownText.Text = "Der PC fährt automatisch in $countdown sekunden herunter..."
    #~~< Button:Yes >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $ButtonYes = New-Object System.Windows.Forms.Button
    $ButtonYes.Location = "67, 115"
    $ButtonYes.Size = "75, 23"
    $ButtonYes.Text = "Ja"
    $ButtonYes.UseVisualStyleBackColor = $true
    #~~< Label: MainMessage >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $LabelMainMessage = New-Object System.Windows.Forms.Label
    $LabelMainMessage.Font =  "Segoe UI, 11pt"
    $LabelMainMessage.Location = "34, 31"
    $LabelMainMessage.Size = "267, 28"
    $LabelMainMessage.Text = "Soll der PC heruntergefahren werden?"
    $Messagebox.Controls.Add($LabelCountDownText)
    $Messagebox.Controls.Add($ButtonNo)
    $Messagebox.Controls.Add($ButtonYes)
    $Messagebox.Controls.Add($LabelMainMessage)
    #~~< Timer >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Timer1 = New-Object System.Windows.Forms.Timer
    $Timer1.Interval = 1000  # in miliseconds
    #~~< Events >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Messagebox.add_shown({  $Timer1.Start() })
    $Messagebox.add_Closing({ FNcleanUp })
    $ButtonNo.add_click({ FNcleanUP })
    $ButtonYes.add_click({ FNcleanUp ; FNshutDown })
    $Timer1.add_Tick({ 
    		$script:countdown --
    		$LabelCountDownText.Text = "Der PC fährt automatisch in $countdown sekunden herunter..."
    		if ($countdown -le 0) {
    			FNcleanUp
    			FNshutDown
    		}
    	})
    	
    #~~< Functions >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
    Function FNcleanUp {
    	$Messagebox.dispose()
    	$Timer1.Dispose()
    }	
    
    Function FNshutDown { 
    	shutdown /s /f /t 0
    }
    #~~< Run the whole thing >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    [System.Windows.Forms.Application]::Run($Messagebox)
    
     

    Die Einstellungsmöglichkeiten sollten erkennbar sein. Bei deinen Vorkenntnissen wäre es leider zu umfangreich hier das komplette Script zu erklären. Gerade die Winforms-Event-logik muß man mal erklärt bekommen haben. Dann ist es aber ganz simpel.
    Du kannst dir z.b. in meinem Blog (s.u.) mal das kleine Tutorial über Winforms durchlesen. Falls du dann noch Fragen zu obigem Code hast, kannst du das hier gerne Posten.

    Grüße, Denniver

     


    Blog: http://bytecookie.wordpress.com
    Powershell Codesnippet Manager: Link

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Mittwoch, 23. Juli 2014 15:49
    Moderator
  • Ich benutze immer den folgenden Code, dann ist man unabhängig von der Startmethode. (einfach irgendwo am Anfang des Scriptes einfügen):

     

    #region Hide Console
    if ($Host.name -eq "ConsoleHost") {
    $script:showWindowAsync = Add-Type –memberDefinition @”
    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    “@ -name “Win32ShowWindowAsync” -namespace Win32Functions –passThru
     $null = $showWindowAsync::ShowWindowAsync((Get-Process –id $pid).MainWindowHandle, 0)
    }
    #endregion
      

    Das blendet die Konsole aus, wenn du das Script direkt, per Kommandozeile oder per Verknüpfung startest. (beim Start im ISE oder einem andern Editor nicht).
    Alternativ, falls du jederzeit volle Kontrolle über die Startmethode deines Scriptes hast, geht auch einfach der powershell.exe - Startparameter "-WindowStyle hidden".
    Das kurze aufblitzen der Konsole am Anfang lässt sich nicht unterdrücken.

    Was deine zweite Frage betrifft, im Fall eines Klick auf "Nein" (oder schließen des Fensters mit "x")  wird die Funktion FNCleanUp aufgerufen. Füge hier einfach unterhalb von

    $Timer1.Dispose()

     deinen gewünschten Befehl ein.
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com
    Powershell Codesnippet Manager: Link

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.


    Donnerstag, 24. Juli 2014 03:51
    Moderator

Alle Antworten

  • Hallo,

    ohne es getestet zu haben...

    if ($Antwort-eq 6)

    {shutdown}


    elseif (nein)

     {exit}

    else {
    exit}

    Gesetzt den Fall ich habe verstanden was Du erreichen willst.

    Grüße


    Best regards
    Andreas Ernst
    MCITP:EA, MCP, MCTS

    Mittwoch, 23. Juli 2014 07:49
  • HI Andreas,

    der Shutdown usw funktioniert in dem oberen Script aber danke für deine Hilfe :)

    Ich formuliere es nochmal anders :P Ich möchte das IF so erweitern das wenn nach 30 Sekunden keine Interaktion passiert der PC runterfährt.

    Mittwoch, 23. Juli 2014 08:20
  • Hallo,

    if ($Antwort-eq 6)

    {shutdown}


    elseif (nein)

     {exit}

    else {
    shutdown /s /f /t 0}

    funktioniert nicht?

    Best regards
    Andreas Ernst
    MCITP:EA, MCP, MCTS

    Mittwoch, 23. Juli 2014 08:48
  • Leider nicht, Das fenster bleibt offen und es passiert nichts. Ich habe über Countdowntimer mal gelesen kann es aber nicht implementieren wäre das evtl noch ne möglichkeit.


    • Bearbeitet an-dre Mittwoch, 23. Juli 2014 11:07
    Mittwoch, 23. Juli 2014 09:18
  •   

    Ich befürchte so ganz einfach ist das ganze nicht. Du hast aber Glück, ich habe gerade sowas mit Winforms für meinen nächsten SnippetManager gebastelt.

    Ich habs mal für deine Bedürfnisse angepasst:
      

    cls
    $countdown = 30 # in seconds
    [void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    
    #~~< Messagebox >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Messagebox = New-Object System.Windows.Forms.Form
    $Messagebox.ClientSize = "324, 166"
    $Messagebox.FormBorderStyle = "FixedToolWindow"
    $Messagebox.StartPosition = 1  # center sceen
    #~~< Button: No >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $ButtonNo = New-Object System.Windows.Forms.Button
    $ButtonNo.Location = "185, 115"
    $ButtonNo.Size = "75, 23"
    $ButtonNo.Text = "Nein"
    $ButtonNo.UseVisualStyleBackColor = $true
    $Messagebox.CancelButton = $ButtonNo
    #~~< Label: CountDownText >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $LabelCountDownText = New-Object System.Windows.Forms.Label
    $LabelCountDownText.Font =  "Segoe UI, 8pt"
    $LabelCountDownText.Location = "37, 59"
    $LabelCountDownText.Size = "223, 27"
    $LabelCountDownText.TabIndex = 3
    $LabelCountDownText.Text = "Der PC fährt automatisch in $countdown sekunden herunter..."
    #~~< Button:Yes >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $ButtonYes = New-Object System.Windows.Forms.Button
    $ButtonYes.Location = "67, 115"
    $ButtonYes.Size = "75, 23"
    $ButtonYes.Text = "Ja"
    $ButtonYes.UseVisualStyleBackColor = $true
    #~~< Label: MainMessage >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $LabelMainMessage = New-Object System.Windows.Forms.Label
    $LabelMainMessage.Font =  "Segoe UI, 11pt"
    $LabelMainMessage.Location = "34, 31"
    $LabelMainMessage.Size = "267, 28"
    $LabelMainMessage.Text = "Soll der PC heruntergefahren werden?"
    $Messagebox.Controls.Add($LabelCountDownText)
    $Messagebox.Controls.Add($ButtonNo)
    $Messagebox.Controls.Add($ButtonYes)
    $Messagebox.Controls.Add($LabelMainMessage)
    #~~< Timer >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Timer1 = New-Object System.Windows.Forms.Timer
    $Timer1.Interval = 1000  # in miliseconds
    #~~< Events >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    $Messagebox.add_shown({  $Timer1.Start() })
    $Messagebox.add_Closing({ FNcleanUp })
    $ButtonNo.add_click({ FNcleanUP })
    $ButtonYes.add_click({ FNcleanUp ; FNshutDown })
    $Timer1.add_Tick({ 
    		$script:countdown --
    		$LabelCountDownText.Text = "Der PC fährt automatisch in $countdown sekunden herunter..."
    		if ($countdown -le 0) {
    			FNcleanUp
    			FNshutDown
    		}
    	})
    	
    #~~< Functions >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~	
    Function FNcleanUp {
    	$Messagebox.dispose()
    	$Timer1.Dispose()
    }	
    
    Function FNshutDown { 
    	shutdown /s /f /t 0
    }
    #~~< Run the whole thing >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    [System.Windows.Forms.Application]::Run($Messagebox)
    
     

    Die Einstellungsmöglichkeiten sollten erkennbar sein. Bei deinen Vorkenntnissen wäre es leider zu umfangreich hier das komplette Script zu erklären. Gerade die Winforms-Event-logik muß man mal erklärt bekommen haben. Dann ist es aber ganz simpel.
    Du kannst dir z.b. in meinem Blog (s.u.) mal das kleine Tutorial über Winforms durchlesen. Falls du dann noch Fragen zu obigem Code hast, kannst du das hier gerne Posten.

    Grüße, Denniver

     


    Blog: http://bytecookie.wordpress.com
    Powershell Codesnippet Manager: Link

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Mittwoch, 23. Juli 2014 15:49
    Moderator
  • Es funktioniert du bist mein Retter danke dir :)

    Darf ich dir noch 2 Fragen stellen, wie blende ich das Konsolenfenster der Powershell aus und ist es möglich das wenn man nein Beantwortet wieder einen Prozess oder eine Anwendung in den Vordergrund holt?

    Mittwoch, 23. Juli 2014 20:23
  • Ich benutze immer den folgenden Code, dann ist man unabhängig von der Startmethode. (einfach irgendwo am Anfang des Scriptes einfügen):

     

    #region Hide Console
    if ($Host.name -eq "ConsoleHost") {
    $script:showWindowAsync = Add-Type –memberDefinition @”
    [DllImport("user32.dll")]
    public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    “@ -name “Win32ShowWindowAsync” -namespace Win32Functions –passThru
     $null = $showWindowAsync::ShowWindowAsync((Get-Process –id $pid).MainWindowHandle, 0)
    }
    #endregion
      

    Das blendet die Konsole aus, wenn du das Script direkt, per Kommandozeile oder per Verknüpfung startest. (beim Start im ISE oder einem andern Editor nicht).
    Alternativ, falls du jederzeit volle Kontrolle über die Startmethode deines Scriptes hast, geht auch einfach der powershell.exe - Startparameter "-WindowStyle hidden".
    Das kurze aufblitzen der Konsole am Anfang lässt sich nicht unterdrücken.

    Was deine zweite Frage betrifft, im Fall eines Klick auf "Nein" (oder schließen des Fensters mit "x")  wird die Funktion FNCleanUp aufgerufen. Füge hier einfach unterhalb von

    $Timer1.Dispose()

     deinen gewünschten Befehl ein.
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com
    Powershell Codesnippet Manager: Link

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.


    Donnerstag, 24. Juli 2014 03:51
    Moderator
  • Vielen Dank jetzt ist das Script so wie ich es mir gewünscht habe :) Da ich das Script Remote ausführen lassen möchte wenn der PC runterfährt habe ich mir eine .bat gemacht auf dem ersten Client mit dem BEfehl

    PSExec \\192.168.x.xxxx -i -u user-p password PowerShell C:\shutdown.ps1

    Und dieses Script soll ausgeführt werden beim herunterfahren des PC's das wurde so in der GPO eingestellt allerdings führt er den Befehl aus und der PC geht aus wartet aber nicht bis der Befehl vollständig gesendet wurde, kann ich dort noch irgendwie eine Pause oder ein warten einfügen das er 10 Sekunden wartet bis der PC nach abesenden des Befehls runterfährt oder wartet bis er eine Rückmeldung bekommt über den Befehl?
    Donnerstag, 24. Juli 2014 05:37
  • Kannst du das bitte nochmal genauer erklären:

    - Was genau möchtest du eigentlich erreichen? Soll das ganze eine Art Sicherheitsabfrage ala "sind Sie sicher das Sie den PC herunterfahren wollen" werden?

    - Was genau funktioniert und was nicht?

     

    Grüße, Denniver

    Blog: http://bytecookie.wordpress.com
    Powershell Codesnippet Manager: Link

    Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
    Warum das Ganze? Hier gibts die Antwort.

    Donnerstag, 24. Juli 2014 22:27
    Moderator
  • Hallo Denniver,

    das Script an sich funktioniert super :)

    Ich habe 2 PC's die beide auf die gleichen Daten zugreifen die auf PC A liegen. Beide PCs sind aber nicht immer an. Ich möchte das wenn ich PC B einschalte das PC A hochgefahren wird, das klappt ohne Probleme per WOL. Wenn PC B runtergefahren wird soll an PC A dein Script gestartet werden und das soll automatisch passieren. Hast du dafür ne Idee?

    Grüße

    André

    Sonntag, 27. Juli 2014 17:22