AutoIt - Neuling benötigt Hilfe mit Batch

  • Hallo und viele Grüße von einem Neuling, sowohl im Forum, als auch in AutoIt.

    Zu meinem Problem. Ich habe eine Batch gebastelt, die nach Aufruf eine Aktion abfragt. Es soll ein Dienst neugestartet werden, dabei werden Username und Passwort übertragen:


    Es wird nun gewünscht, dass das Passwort des Admins nicht als Klartext übermittelt wird bzw. dass das Script keine temporären Dateien erstellt, aus denen das PW ausgelesen werden könnte.
    Ist es möglich, diese Anforderung mit AutoIt zu bewerkstelligen? Wenn ja, wo kann ich nach einer Lösung suchen bzw. wie würde die Syntax heißen, mit der dies möglich ist? Es müsste in diesem Fall psexec durch ein anderes Modul ersetzt werden, um den Task an den Remote-Computer zu übermitteln. Geht das mit AutoIt wie gewünscht?

    Ein weiterer Weg wäre evtl., diese Batch zu einer Exe zu kompilieren, jedoch bringt Aut2Exe die Fehlermeldung, dass ein String nicht geparsed werden konnte. Ist es mit AutoIt-Modulen generell nicht möglich, Batches zu ausführbaren Datein zu kompilieren?
    Danke vorab für jede Hilfe.

    MfG ibicis

    Einmal editiert, zuletzt von ibicis (20. Oktober 2011 um 21:54)

  • Naja also es besteht wie schon erwähnt die Möglichkeit die Batch Datei in eine ExE umzuwandeln, aber nicht über den von dir beschriebenen Weg..

    Die Aut2Exe soweit ich weiß nicht dafür geeignet schau mal unter
    Batch 2 exe Freeware

    Gruß Marvin

  • Hi ibicis ,

    hier Mal`ne ungetestete Idee:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Service-Restart", 290, 63, 193, 125)
    $Label1 = GUICtrlCreateLabel("Wollen Sie den Dienst neu starten ?", 8, 8, 174, 17)
    $Button1 = GUICtrlCreateButton("Ja", 8, 32, 75, 25, 0)
    $Button2 = GUICtrlCreateButton("Nein", 104, 32, 75, 25, 0)
    $Button3 = GUICtrlCreateButton("Abbruch", 200, 32, 75, 25, 0)
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $iResponse = MsgBox(36, "Neustart", "Sind Sie sicher? " & @CRLF & "Damit bestätigen Sie im folgenden Schritt, dass Sie den Support nicht erreichten! " & @CRLF & "Weiterhin wird eine E-Mail an Sie persönlich versendet.")
    If $iResponse = 6 Then
    ShellExecute("psexec.exe" & "\\sql-server1\ -u administrator -p passw0rd schtasks /run /TN restart-Druckwarteschlange", @SW_HIDE)
    Else
    MsgBox(64, "", "Der Neustart des Dienstes wurde abgebrochen")
    EndIf
    Case $Button2
    MsgBox(64, "", "Der Dienst wird nicht neu gestartet")
    Case $Button3
    Exit
    EndSwitch
    WEnd

    [/autoit]

    #EDIT: Btw, wenn Du im Skripttext auf den blauen oder rosafarbenen Text klickst, öffnet sich die Onlinehilfe mit einer Erklärung zum entsprechenden Eintrag
    - Hat bei mir`n bisserl gedauert bis ich dahintergestiegen bin ;)

    Gruß
    Mike

    3 Mal editiert, zuletzt von Mike280399 (12. Oktober 2011 um 15:38)

  • Wunderbar, danke sehr.
    Leider klappt der Aufrug von psexec offenbar nicht. Gebe ich in eine Batch "psexec \\sql-server1\ "C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\sql-restart\sql-restart.cmd" -u administrator -p passw0rd" (habe es der Einfachheit halber mal direkt mit der CMD ohne Umweg über den Taskplaner gemacht) ein und führe diese aus, wird der Dienst neugestartet. Beim Aufruf über AutoIt klappt es leider nicht.

    Noch eine Frage. Ist es möglich, das Script so anzupassen, dass beim Aufruf der psexec.exe beide UIs geschlossen werden?
    Danke vorab.

    MfG ibicis

  • Ubbala, naja, war ungetestet wie gesagt :D
    Das ist dann wohl eher was für diejenigen die sich schon länger mit AutoIT befassen :D
    Ich schaue, wenn ich`s zeitlich schaffe, später noch Mal drüber, ansonsten erst morgen.

    #EDIT: Mir ist grad aufgefallen das Du ja lt. Deinem ersten Post

    Code
    psexec.exe \\sql-server1\ -u administrator -p passw0rd schtasks /run /TN restart-dienst

    ausführen wolltest.
    Musst das ja dann jetzt entsprechend ändern im Skript :D
    Die sql-restart.cmd liegt auf Deinem Rechner nehme ich an ??
    Wenn ja, pack`se Mal in das gleiche Verzeichnis wie das Skript.
    Ach ja, wenn Du`s so änderst müsste es meiner Ansicht nach klappen.
    Auch die UI`s werden geschlossen :D

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Service-Restart", 290, 63, 193, 125)
    $Label1 = GUICtrlCreateLabel("Wollen Sie den Dienst neu starten ?", 8, 8, 174, 17)
    $Button1 = GUICtrlCreateButton("Ja", 8, 32, 75, 25, 0)
    $Button2 = GUICtrlCreateButton("Nein", 104, 32, 75, 25, 0)
    $Button3 = GUICtrlCreateButton("Abbruch", 200, 32, 75, 25, 0)
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $iResponse = MsgBox(36, "Neustart", "Sind Sie sicher? " & @CRLF & "Damit bestätigen Sie im folgenden Schritt, dass Sie den Support nicht erreichten! " & @CRLF & "Weiterhin wird eine E-Mail an Sie persönlich versendet.")
    If $iResponse = 6 Then
    ShellExecute("psexec", "\\sql-server1\ sql-restart.cmd -u administrator -p passw0rd", @ScriptDir, "", @SW_HIDE)
    Else
    EndIf
    $iResponse1 = MsgBox(64, "", "Der Neustart des Dienstes wurde abgebrochen")
    If $iResponse1 = 1 Then
    Exit
    EndIf
    Case $Button2
    $iResponse2 = MsgBox(64, "", "Der Dienst wird nicht neu gestartet")
    If $iResponse2 = 1 Then
    Exit
    EndIf
    Case $Button3
    Exit
    EndSwitch
    WEnd

    [/autoit]

    Ich weise nochmals ausdrücklich darauf hin, das auch ich erst Anfänger bin und keinerlei Gewähr für die Funktionalität gebe :D
    Wenn`s nu nich klappt weiss ich auch nich weiter :S

    Grüße

    Mike

    2 Mal editiert, zuletzt von Mike280399 (12. Oktober 2011 um 20:15)


  • ...
    #EDIT: Mir ist grad aufgefallen das Du ja lt. Deinem ersten Post

    Code
    psexec.exe \\sql-server1\ -u administrator -p passw0rd schtasks /run /TN restart-dienst

    ausführen wolltest.
    Musst das ja dann jetzt entsprechend ändern im Skript :D

    Jo, das habe ich natürlich gemacht. :)


    Die sql-restart.cmd liegt auf Deinem Rechner nehme ich an ??
    Wenn ja, pack`se Mal in das gleiche Verzeichnis wie das Skript.
    Ach ja, wenn Du`s so änderst müsste es meiner Ansicht nach klappen.
    Auch die UI`s werden geschlossen :D

    Nein, die SQL-Restart.cmd liegt auf dem Remote-Rechner. Lokal liegen nur Das Script selbst und PsExec.exe. Die Parameter werden also an das lokal befindliche psexec übergeben, das dann remote die SQL-Restart.cmd ausführt. Wie gesagt, das ganz am Anfang gepostete Script funktioniert einwandfrei, gefiel aber aus eingangs erwähnten Gründen meinem Vorgesetzten nicht.
    Trotzdem vielen Dank für deine Mühe, ich weiß das sehr zu schätzen. Invielen Foren wird so pragmatisch eher nicht geholfen, das kommen da eher so Komentare a la "Ja, lerne halt die Scriptsprache xyz." was mich dann auch nicht weiterbringt.

    Ich probiere deinen Vorschlag mal aus und werde sehen, wa sich ergibt.

    MfG ibicis

  • Sodele, hab mich wieder Mal festgebissen :D
    Habe das ganze Mal als Übung für mich missbraucht :D

    Hier das Skript:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #region ### START Koda GUI section ### Form=
    $Form1 = GUICreate("Service-Restart", 210, 63, 193, 100)
    $Label1 = GUICtrlCreateLabel("Wollen Sie den Dienst neu starten ?", 18, 8, 174, 17)
    $Button1 = GUICtrlCreateButton("Ja", 20, 32, 75, 25, 0)
    $Button2 = GUICtrlCreateButton("Nein", 110, 32, 75, 25, 0)
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button1
    $iResponse = MsgBox(36, "Neustart", "Sind Sie sicher? " & @CRLF & "Damit bestätigen Sie im folgenden Schritt, dass Sie den Support nicht erreichten! " & @CRLF & "Weiterhin wird eine E-Mail an Sie persönlich versendet.")
    If $iResponse = 7 Then
    MsgBox(64, "", "Abgebrochen !", 2)
    Exit
    ElseIf $iResponse = 6 Then
    $iResult = ShellExecuteWait("c:\psexec\psexec", "\\192.168.10.1 c:\Install\test.cmd -u domaene\Admin -p Password -n 10", "", "");, @SW_HIDE)
    If $iResult <> 0 Then
    MsgBox(16, "Fehler !", "Prüfen Sie ob:" & @CRLF & "-Eine Verbindung zum Server besteht" & @CRLF & "-Die Pfadangabe richtig ist" & @CRLF & "-Benutzername und Kennwort richtig sind")
    Else
    $iResponse_Y = MsgBox(64, "Erfolgreich", "Der Dienst wurde neu gestartet")
    If $iResponse_Y = 1 Then Exit
    EndIf
    EndIf
    Case $Button2
    $iResponse2 = MsgBox(64, "", "Der Vorgang wurde vom Benutzer abgebrochen")
    If $iResponse2 = 1 Then
    Exit
    EndIf
    EndSwitch
    WEnd

    [/autoit]

    Hab`s getestet, funzt bei mir ganz prima :D

    Beachte bitte das in

    [autoit]

    $iResult = ShellExecuteWait("c:\psexec\psexec", "\\192.168.10.1 c:\Install\test.cmd -u domaene\Admin -p Password -n 10", "", "");, @SW_HIDE)

    [/autoit]

    @SW_HIDE noch auskommentiert ist, zum nachvollziehen ob alles klappt.
    Dies solltest Du noch ändern, genau so wie den Pfad zur psexec, den Pfad zum Skript auf`m Server, -u, -p und -n :D
    Leg`das sql-restart.cmd - Dingens am besten in C:\ oder C:\Skript.
    -n würde ich auf jeden Fall drin lassen, da es sein kann das sich das Programm sonst "totläuft" :D

    Gruß
    Mike

  • Danke sehr, das probiere ich gleich mal aus.
    Frage: Wie kann ich dem Programm sagen, dass das remote auszuführende Script, in deinem Bsp. "c:\Install\test.cmd", Leerzeichen im Namen hat? Der Pfad wäre nämlich in meinem Fall "C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\...". Kann ich das, wie hier, mittels "" definieren? Falls es gar nicht geht, erstelle ich notfalls einen Pfad, der keine Leerzeichen enthält.

    MfG ibicis

  • In einem solchen Fall einfach mit einfachen Hochzeichen doppelten Hochzeichen arbeiten:

    Code
    '"C:\Dokumente und Einstellungen\Administrator\Eigene Dateien\..."'

    mfg autoBert

  • Immer gerne wieder :D
    Bin froh wenn ich die Möglichkeit bekomme dazuzulernen und gleichzeitig jemandem helfen zu können :D
    @ Bert: Kopf -> Tisch :wacko: Da hätt ich auch drauf kommen müssen eigentlich :D

    Wenn`s läuft, sei bitte so gut und bearbeite Deinen ersten Post dahingehend, das Du "Präfix" "auf Gelöst" umstellst.

    Grüße
    Mike

  • Jetzt hast du nur noch das "Problem", dass weiterhin das Admin-Passwort für jeden lesbar im Code steht. Auch in einer .exe ist das nicht sicher.

    Ich selbst verwende in solchen Fällen immer: runasspc mit einem cryptfile...

  • Mal im Ernst, derjenige der sich die Mühe macht die Exe zu dekompilieren um an das Admin-Passwort zu kommen, muss ja im lokalen Netzwerk unterwegs sein... da gibts einfachere Wege des zu erlangen ;)
    Ich finde man sollte da die Kirche im Dorf lassen.
    Sicherlich gibt es ja auch die Möglichkeit eine AutoIT-Exe zu verschlüsseln, meine hätte das iwo gesehen... aber ob des Sinn macht ?

  • Nun ist ein Problem aufgetaucht, mit dem ich gar nicht gerechnet hatte.
    Im Script wird PsExec aufgerufen, dieses verbindet sich mit dem Remotecomputer. Auf meinem PC läuft alles tadellos. Wird die Aktion jedoch auf einem Rechner getartet, der die PsTools noch niemals geöffnet hatte, muss man einmalig die EULA für jedes Tool abnicken, damit es weitergeht. Mit der Option "/accepteula" (ohne ") kann ich PsExec starten und die EULA trägt sich in die Registry ein. Binde ich diese Option in AI ein, startet es mit der Fehlermeldung "PsExec.exe /accepteula" konnte nicht gefunden werden.
    Ohne diese Option startet psexec ohne UI und wartet auf die EULA-Bestätigung.
    Wie kann ich die Option einbinden? Der String schaut aktuell so aus:
    ("PsExec.exe", "\\ziel-computer\ -u domain\Administrator -p password schtasks /run /TN dienst-neustart", "", "", @SW_HIDE)

    So müsste es aussehen mit der Option:

    ("PsExec.exe /accepteula", "\\ziel-computer\ -u domain\Administrator -p password schtasks /run /TN dienst-neustart", "", "", @SW_HIDE)

    Gibt es eine Möglichkeit, die Option einzubinden? Danke vorab.

    P.S.: So muss der String aussehen, dann klappt's auch mit dem Nachbarn!

    ("PsExec.exe", "\\ziel-computer\ -u domain\Administrator -p password -accepteula schtasks /run /TN dienst-neustart", "", "", @SW_HIDE)

    MfG ibicis

    Einmal editiert, zuletzt von ibicis (20. Oktober 2011 um 21:53)

  • Wer Paranoid oder eher vorsichtig ist sollte aber wie bereits erwähnt wurde darauf verzichten Admin Passwörter auf Clientrechnern zu speichern, sei es nun im Klartext wie ursprünglich oder auch kompiliert. Beides kann ausgelesen werden und birgt Risiken.
    Die bessere Lösung wäre auf dem Zielsystem einen Serverdienst einzurichten der Kommandos von Clienten annimmt und dann lokal als Admin ode System die Aktion auf dem Server ausführt. So wäre das Passwort nur auf dem Server gespeichert und von Ausserhalb nicht auslesbar.

    Hierzu sollte man sich dann am besten mit den TCP Funktionen befassen. Alternativ kann man aber auch mit eventtriggern arbeiten.

    Der Aufbau könnte dann so aussehen:

    Remotecomputer:

    Useraccount ohne nennenswerte Rechte anlegen
    Aufgabenplannung->Aufgabe anlegen die bei bestimmter TriggerId mit Admin Privilegien ausgeführt wird

    Clientcomputer

    Trigger remote auslösen, dazu werden Passwort und Username des eingeschränkten Users benötigt und im Script gespeichert

    Infos zu Eventcreate:
    http://technet.microsoft.com/en-us/library/bb490899.aspx


    Vorteil zur aktuellen Lösung ist, dass sich auf den Clients keine Accountdaten befinden mit dennen man Schaden anrichten könnte. Desweiteren gestalten sich Updates leichter, da hierzu nicht auf jedem Client eine aktuelle Version des Scriptes vorhanden sein muss, sondern lediglich auf dem Server die Aufgabe zur gewählten TriggerID geändert werden muss.

    Einmal editiert, zuletzt von misterspeed (21. Oktober 2011 um 21:07)

  • ...
    Die bessere Lösung wäre auf dem Zielsystem einen Serverdienst einzurichten der Kommandos von Clienten annimmt und dann lokal als Admin ode System die Aktion auf dem Server ausführt. So wäre das Passwort nur auf dem Server gespeichert und von Ausserhalb nicht auslesbar.
    ...

    Genau das hatte ich anfangs getan. Ich hatte auf dem Zielsystem einen deaktivierten Task eingerichtet, der eine weitere Batch (die eigentlich relevante, die den Dienst killt) aufruft, mit Adminrechten läuft und die Anmeldedaten dort lokal mit dem Assistenten hinterlegt. Die Batch rief per psexec diesen Task auf und alles war erledigt. Das Ganze funktionierte einwandfrei, bis man meinte, der direkte Weg zur Batch auf dem Zielsystem wäre die bessere Lösung, um auf dem Zielsystem nicht noch eine weitere potentielle Fehlerquelle einzubauen. Nun musste ich alles wieder ummodeln und die Anmeldedaten waren plötzlich relevant. Als ich diese Forderung umgesetzt hatte kam plötzlich die Notwendigkeit ins Spiel, alle offenen Bezüge zur DB zu killen, die als Überreste des nicht mehr reagierenden SQl-Dienstes über waren. Da die openfiles.exe aber nicht besonders gut filtern kann, musste ich per se alle Handles trennen, somit auch das von psexec und der Rückgabewert war somit 1. Ohne den Taskplaner kann ich diese Option aber nicht umsetzen, denn nachdem der Task erfolgreich aufgerufen wird, gibt dieser den Wert 0 zurück und die AutoIt-Anwendung eine Erfolgsmeldung aus. Die Batch auf dem Zielsystem arbeitet inzwischen alle Befehle ab.
    So kanns laufen, wenn Anforderungen in jedem Dialog geändert werden.

    MfG ibicis