none
Scheduled Task mit PowerShell und PSShutdown

    Frage

  • Hallo zusammen,

    ich stehe gerade vor einem Rätsel:

    ich habe ein Powershellscript (siehe unten) geschrieben, das mittels PSShutdown alle Rechner die in einer bestimmten OU sind herunterfahren soll. Ich habe mich hier für PSShutdown entschieden, da ich dem User die Wahl lassen will ob er herunterfahren will oder nicht.

    Als Task führe ich das Script mittels der powershell.exe aus.("c:\Windows\System32\v1.0\powershell.exe -ExecutionPolicy ByPass -file \\<Server>\<Pfad>\clients_herunterfahren.ps1")
    Das Bypass habe ich eigentlich nur zum testen mit rein gemacht, da das eigentlich auf unseren Servern schon eingestellt ist.

    Im Großen und Ganzen funktioniert das Script auch (teilweise isses nicht schön aber es macht das was es soll)
    Nur wenn ich es als Task ausführe führt er die Zeile mit dem PSShutdown nicht aus (& 'N:\Scripte\Tasks-Scripte\Clients_herunterfahren\psshutdown.exe' \\$computer -accepteula -c -f -k -u toom\support -p koelle -m "Ihr Computer wird heruntergefahren. Bitte speichern Sie alle geöffneten Dateien. Drücken Sie 'Cancel' um das Herunterfahren abzubrechen." -t 3600 | out-file C:\logs\client_log.txt -Append)

    Langsam bin ich mit meinem Latein und meinem Googlefuu am ende und hab einfach keine Idee mehr. Ich hoffe Ihr könnt mir weiterhelfen warum er gerade DIESE Zeile nicht ausführt.

    Vielen Dank schonmal

    Mischa

    PS: solltet ihr für meine anderen etwas unschönen Lösungen (z.B. Abfrage ob das Feature installiert ist) eine bessere Alternative habt nehme ich auch hier gerne Tips entgegen.

    #Active Directory Modul wird geladen
    $feature = Get-WindowsFeature | ? {$_.Installed -eq $true -and $_.Name -like "*RSAT-AD-PowerShell*" }
    
    if ($feature.Count -eq 0){
        install-WindowsFeature RSAT-AD-PowerShell
        }
    
    Import-Module ActiveDirectory
        
    #die OU wird festgelegt (nur interessant wenn das Script auf einem Server ausgeführt wird)
    $Server = $env:COMPUTERNAME
    $OU = ("$Server" -split "-")[-2]
    echo  $OU | out-file C:\logs\client_log.txt -Append
    
    #die Rechner die neu gestartet werden sollen werden aus dem AD ausgelesen
    Get-ADComputer -filter {(name -like "*-inf*")} -SearchBase "OU=$OU,OU=<OrganisationalUnit>,DC=<Company>,DC=local" | select @{N='ComputerName'; E={$_.Name}} | Format-Table -HideTableHeaders | Out-File C:\logs\test.txt -Force
    
    
    (get-content C:\logs\test.txt) -match "\S" | Out-File c:\logs\test.txt
    (get-content C:\logs\test.txt) -replace " ","" | Out-File c:\logs\test.txt
    
        
    $clients = (get-content C:\logs\test.txt) -match "\S"
    
    echo $clients | out-file C:\logs\client_log.txt -Append
        
    foreach($computer in $clients)
    {
        if (Test-Connection $computer -Count 1 -Quiet)
        {
            echo $computer | out-file C:\logs\client_log.txt -Append
            & 'N:\Scripte\Tasks-Scripte\Clients_herunterfahren\psshutdown.exe' \\$computer -accepteula -c -f -k -u username -p pw -m "Ihr Computer wird heruntergefahren. Bitte speichern Sie alle geöffneten Dateien. Drücken Sie 'Cancel' um das Herunterfahren abzubrechen." -t 3600 | out-file C:\logs\client_log.txt -Append
        }
    } 



    Montag, 13. November 2017 14:03

Antworten

  • Hi BeatYa,

    erstmal vorweg, ich hatte den Fehler gefunden und er lag nicht im Script, aber dazu später.

    danke für den Tipp mit dem Usernamen und PW dachte eigentlich ich hätte alles anonymisiert und das wichtigste hab ich vergessen. Sei so gut und lösche das auch noch aus deinem Thread raus.

    Das Write-Host hatte ich ja stellenweise mit einem echo gelöst. Diese Echo-Befehle haben auch alle funktioniert nur der Befehl für das PSShutdown hat nicht geklappt..

    Das Get-ADComputer hatte ich zuerst auch so, leider kann PSShutdown nichts mit dem Datenformat von Powershell anfangen. Daher der unschöne Umweg über die Textdatei.

    Und zuletzt die Lösung des Problems war, dass der Task als System Nutzer ausgeführt wurde. Dieser durfte anscheinend den PSShutdown Befehl nicht ausführen oder nichts im Netzwerk machen.

    Vielen Dank auf jeden Fall für eure Hilfe.

    Mischa

    Mittwoch, 15. November 2017 16:54

Alle Antworten

  • Ist 'N:\Scripte\Tasks-Scripte\Clients_herunterfahren\psshutdown.exe' denn ein Laufwerk und ein Pfad, der auf allen betroffenen Computern zur Verfügung steht? Falls nicht, würde ich empfehlen anstatt eines Laufwerksbuchstaben einen UNC-Pfad zu benutzen.

    Best regards (79,108,97,102|%{[char]$_})-join''

    Montag, 13. November 2017 14:39
  • Danke für die schnelle Antwort.

    Das Script wird auf den Servern ausgeführt von wo aus die Clients runtergefahren werden sollen. Der Pfad liegt auf dem Server und ist für ihn auch erreichbar. Die Clients selber haben auf den Pfad keinen Zugriff. Müssen Sie aber doch auch nach meinem Verständnis nicht. Oder bin ich da auf dem Holzweg?

    Montag, 13. November 2017 14:59
  • > Das Script wird auf den Servern ausgeführt von wo aus die Clients runtergefahren werden sollen.

    Wenn Du das Skript als Task ausführst, hast Du keine vollständige Desktop-Session. Insbesondere stehen Dir gemappte Netzlaufwerke nicht zur Verfügung - oder ist das ein lokales Laufwerk?
    Wenn nein: Entweder lokal kopieren und aufrufen (besser) oder einen UNC-Pfad verwenden.

    Montag, 13. November 2017 16:25
  • Hallo Mischa,

    also zuerst würde ich mal <credentials im Post> löschen^^

    Bau mal ins script die Zeilen

    Write-Host "Test" >> c:\log1.txt
    Write-Host "Test" >> c:\log2.txt

    etc an verschiedenen Stellen ein und führ es über den Taskscheduler aus.
    Wenn unter c:\ keine .txt erscheint stimmt was mit der Einrichtung der Aufgabe nicht.

    Die ganze Operation würde auch mit stop-computer funktionieren.
    Wäre ein Workaround durch erstellen eines Tasks zu Uhrzeit+x Minuten.
    Zum informieren kannst du dann einfach noch nen Task hinterlegen, der alle x Minuten aufpoppt.

    Zu den vorherigen Antworten von wegen läuft das Script auf Client oder Server:
    Verstehe ich es falsch, oder übergibt er hier:

     & 'N:\Scripte\Tasks-Scripte\Clients_herunterfahren\psshutdown.exe' \\$computer

    nicht mit dem ersten Parameter \\$computer einzeln nacheinander die Computernamen, die er mit der Get-Content aus der .txt ausgelesen hat?

    Diese .txt würde ich übrigens gar nicht erstellen. Das Ganze kann man auch super mit der Verwendung von Variablen lösen.
    Die Clients werden ja in

    Get-ADComputer -filter {(name -like "*-inf*")} -SearchBase "OU=$OU,OU=<OrganisationalUnit>,DC=<Company>,DC=local" | select @{N='ComputerName'; E={$_.Name}} | Format-Table -HideTableHeaders | Out-File C:\logs\test.txt -Force

    ermittelt. Ein

    $Clients = Get-ADComputer -filter {(name -like "*-inf*")} -SearchBase "OU=$OU,OU=<OrganisationalUnit>,DC=<Company>,DC=local" | select @{N='ComputerName'; E={$_.Name}} 

    erledigt die Aufgabe genauso gut und muss nicht abgespeichert werden
    die weiteren Anpassungen können auch gleichermaßen über $Clients wie über die .txt bearbeitet werden. Verschlankt das Ganze dann etwas und man ist weniger angreifbar, da die Daten flüchtig sind.



    • Bearbeitet BeatYa Donnerstag, 16. November 2017 10:47
    Mittwoch, 15. November 2017 10:37
  • Hi BeatYa,

    erstmal vorweg, ich hatte den Fehler gefunden und er lag nicht im Script, aber dazu später.

    danke für den Tipp mit dem Usernamen und PW dachte eigentlich ich hätte alles anonymisiert und das wichtigste hab ich vergessen. Sei so gut und lösche das auch noch aus deinem Thread raus.

    Das Write-Host hatte ich ja stellenweise mit einem echo gelöst. Diese Echo-Befehle haben auch alle funktioniert nur der Befehl für das PSShutdown hat nicht geklappt..

    Das Get-ADComputer hatte ich zuerst auch so, leider kann PSShutdown nichts mit dem Datenformat von Powershell anfangen. Daher der unschöne Umweg über die Textdatei.

    Und zuletzt die Lösung des Problems war, dass der Task als System Nutzer ausgeführt wurde. Dieser durfte anscheinend den PSShutdown Befehl nicht ausführen oder nichts im Netzwerk machen.

    Vielen Dank auf jeden Fall für eure Hilfe.

    Mischa

    Mittwoch, 15. November 2017 16:54
  • Wenn PS nichts mit den Daten anfangen kann, aber der Umweg über eine Textdatei weiterhilft formatiere ich die genutzte Variable in String um:

    [string]$var = $var

    Lässt sich aber bestimmt auch noch ein stückchen schöner lösen.

    Auf die weitere Vorgehensweise wäre ich zu sprechen gekommen, wenn mit Write-Host klar gewesen wäre, dass das Script überhaupt läuft und dann gefragt bis zu welcher Stelle es läuft usw.

    Freut mich, dass es jetzt bei dir funktioniert.

    :-)

    Viele Grüße


    • Bearbeitet BeatYa Donnerstag, 16. November 2017 10:50
    Donnerstag, 16. November 2017 10:49