WMI - Dienst beenden/neu starten über remote

  • Hallo zusammen,

    ich möchte einen Dienst am Server von einem Client aus neu starten.
    Der Server dient als Domaincontroller.

    Als Basis hab ich das Skript von UEZ genommen: [ gelöst ] Dienste starten und beenden
    Das funtkioniert aber nur lokal.
    Der Anmeldungsteil (Domain, User, Passwort) fehlt aber doch komplette oder?
    Kann mir jemand sagen wie man ungefähr vorzugehen hat?

    Gruß & danke

    Nuts

    Einmal editiert, zuletzt von nuts (12. Oktober 2012 um 14:27)

  • ich mache das immer so:

    RunWait(@ComSpec & " /C" & 'sc \\' & $sHostname & ' stop gewünschterDienstname', @TempDir, @SW_HIDE)

    und

    RunWait(@ComSpec & " /C" & 'sc \\' & $sHostname & ' start gewünschterDienstname', @TempDir, @SW_HIDE)

    Adminrechte vorausgesetzt.

  • Probiere es mal damit:

    Spoiler anzeigen
    [autoit]


    ;Coded by UEZ 2009
    #AutoIt3Wrapper_Change2CUI=y
    #AutoIt3Wrapper_UseUpx=n

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

    $oMyError = ObjEvent("AutoIt.Error", "oMyError") ; Install a custom error handler

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

    Global $ip = "localhost"
    If $CmdLine[0] > 0 Then $ip = $CmdLine[1]

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

    $stop_srv = "RemoteRegistry"

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

    If Stop_Service($ip, $stop_srv) Then
    MsgBox(0, "Stop Service", "Service " & $stop_srv & " stopped properly on " & $ip)
    Else
    MsgBox(16, "Error", "Error")
    EndIf

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

    Func Stop_Service($srv, $service, $sUsr = "", $sPass = "")
    Local $colItems, $colItem, $ping, $objWMILocator, $objWMIService
    $ping = Ping($srv)
    If $ping Then
    $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    If @error Then Return SetError(3, 0, 0)
    $objWMIService = $objWMILocator.ConnectServer($srv, "\root\cimv2", $sUsr, $sPass, "", "", 128)
    If @error Then Return SetError(4, 0, 0)
    $colItems = $objWMIService.ExecQuery("Select * From Win32_Service Where Name='" & $service & "'")
    If IsObj($colItems) Then
    For $objItem In $colItems
    $objItem.StopService()
    Next
    Return 1
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndIf
    Return SetError(2, 0, 0)
    EndFunc

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

    Func oMyError()
    Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !" & @CRLF & @CRLF & _
    "err.description is: " & @TAB & $oMyError.Description & @CRLF & _
    "err.windescription:" & @TAB & $oMyError.WinDescription & @CRLF & _
    "err.number is: " & @TAB & Hex($oMyError.Number, 8) & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oMyError.LastDllError & @CRLF & _
    "err.scriptline is: " & @TAB & $oMyError.Scriptline & @CRLF & _
    "err.source is: " & @TAB & $oMyError.Source & @CRLF & _
    "err.helpfile is: " & @TAB & $oMyError.Helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oMyError.HelpContext _
    )
    EndFunc

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hm da gibt es doch noch ein Problem.

    Die zweite Variante von UEZ funktioniert vom Client, aber nicht vom Server selbst.
    Kann das sein?
    Fehlermeldung:

  • "Zugriff verweigert" -> checke mal die Berechtigungen auf dem Server bzw. ob dein Acoount auf dem Server Zugriff auf den Client hat. Funktioniert DNS?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hm das war etwas schlecht ausgedrückt.

    Das Skript funktioniert (User und Pass ist vom Administrator des Servers) vom Client per remote, aber nicht auf dem Server vom Server aus.

    Hintergrund ist folgender: Ich muss den DNS-Server Dienst von Zeit zu Zeit neu starten.
    Ich hab jeden Tag am Server (win2008 server) um 23:50 Uhr eine Aufgabe erstellt und möchte die Möglichkeit haben auch vom Client den Dienst auf dem Server neu zu starten.
    Nun funktionierts vom Client, aber die tägliche Aufgabe wird mir mit oben genanntem Fehler abgebrochen.
    Verwende dein Skript mit unwesentlichen Änderungen.

    DNS funktioniert. User und Pass ist korrekt (sonst würde es vom Client ja auch nicht funktionieren).

    Einmal editiert, zuletzt von nuts (16. Oktober 2012 um 11:21)

  • Die Fehlermeldung ist aber eindeutig!

    Zitat


    2012-10-15 23:50:18 : We intercepted a COM Error !

    err.description is: Zugriff verweigert
    err.windescription: Zugriff verweigert

    err.number is: 80020009

    Du musst einmal den Task Scheduler mit einem Account ausführen (i.d.R. ein Service Account) und das Skript muss nach dem Start durch den Task Scheduler die Verbindung zu WMI über das Login, was du mitgibst, erstellen.
    Laut der Fehlermeldung machst du irgendwas falsch!

    Ich denken, dass du die Login Anmeldeinformation in deinem Skript fest eingebunden hast oder?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich denke du hast recht.
    Nachdem ich mal direkt die IP (vorher den Namen des Server) verwende habe kommt folgende Fehlermeldung:

    Werde nur nicht richtig schlau daraus.
    Auf dem Server läuft win2008 server und der Server ist auch der domain controller.
    Was für "Benutzeranmeldeinformationen" werden denn gefordert? :(
    Die Benutzerverwaltung in win2008 server ist leider ziemlich umfangreich und kompliziert.

    Hier noch das Skript:

    Spoiler anzeigen
    [autoit]


    #include <File.au3>
    #include <Misc.au3>

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

    ;Coded by UEZ 2009
    #AutoIt3Wrapper_Change2CUI=y
    #AutoIt3Wrapper_UseUpx=n

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

    $oMyError = ObjEvent("AutoIt.Error", "oMyError")

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

    Global $title="dienstreset"
    Global $log =@ScriptDir & "\" &$title&".log"
    Global $ini=@ScriptDir & "\" &$title&".ini"

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

    _Singleton($title)

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

    if not FileExists($ini) then
    _FileWriteLog($log, "ini nicht gefunden", 1)
    Iniwrite($ini, "Settings", "server", "192.168.111.12")
    Iniwrite($ini, "Settings", "dienst", "DNS-Server")
    endif

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

    Global $ip =Iniread($ini, "Settings", "server", "192.168.111.12")
    Global $dienst=Iniread($ini, "Settings", "dienst", "DNS-Server") ;"DNS-Client"

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

    Global $user="Administrator"
    Global $pass="****"

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

    Global $silent=true

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

    _FileWriteLog($log,"Startup ---- server="& $ip &"----dienst="&$dienst&"----", 1)

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

    If $cmdline[0] > 0 Then
    _FileWriteLog($log, "dienst= " & $dienst, 1)
    if $cmdline[1] <> "msgbox" then
    $dienst = $cmdline[1]
    If StringLeft($dienst, 1) == "-" Then $dienst = StringReplace($dienst, "-", "")
    else
    $silent=False
    endif
    EndIf

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

    If Stop_Service($ip, $dienst, $user, $pass) Then
    if not $silent then MsgBox(0, "Stop Service", "Service " & $dienst & " stopped properly on " & $ip)
    _FileWriteLog($log, "Stop Service: Service " & $dienst & " stopped properly on " & $ip,1)
    Else
    if not $silent then MsgBox(16, "Error", "Stop Service fehlgeschlagen")
    _FileWriteLog($log, "Stop Service - Error", 1)
    EndIf

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

    Sleep(5000)

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

    if Start_Service($ip, $dienst, $user, $pass) then
    if not $silent then MsgBox(0, "Start Service", "Service " & $dienst & " started properly on " & $ip)
    _FileWriteLog($log, "Start Service: Service " & $dienst & " started properly on " & $ip,1)
    Else
    if not $silent then MsgBox(16, "Error", "Start Service fehlgeschlagen")
    _FileWriteLog($log, "Start Service - Error", 1)
    EndIf

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

    _Exit()

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

    Func Stop_Service($srv, $service, $sUsr = "", $sPass = "")
    Local $colItems, $colItem, $ping, $objWMILocator, $objWMIService
    $ping = Ping($srv)
    If $ping Then
    $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    If @error Then Return SetError(3, 0, 0)
    $objWMIService = $objWMILocator.ConnectServer($srv, "\root\cimv2", $sUsr, $sPass, "", "", 128)
    If @error Then Return SetError(4, 0, 0)
    $colItems = $objWMIService.ExecQuery("Select * From Win32_Service Where Name='" & $service & "'")
    If IsObj($colItems) Then
    For $objItem In $colItems
    $objItem.StopService()
    Next
    Return 1
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndIf
    Return SetError(2, 0, 0)
    EndFunc

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

    Func Start_Service($srv, $service, $sUsr = "", $sPass = "")
    Local $colItems, $colItem, $ping, $objWMILocator, $objWMIService
    $ping = Ping($srv)
    If $ping Then
    $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    If @error Then Return SetError(3, 0, 0)
    $objWMIService = $objWMILocator.ConnectServer($srv, "\root\cimv2", $sUsr, $sPass, "", "", 128)
    If @error Then Return SetError(4, 0, 0)
    $colItems = $objWMIService.ExecQuery("Select * From Win32_Service Where Name='" & $service & "'")
    If IsObj($colItems) Then
    For $objItem In $colItems
    $objItem.StartService()
    Next
    Return 1
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndIf
    Return SetError(2, 0, 0)
    EndFunc

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

    Func oMyError()
    local $error
    $error= "We intercepted a COM Error !" & @CRLF & @CRLF & _
    "err.description is: " & @TAB & $oMyError.Description & @CRLF & _
    "err.windescription:" & @TAB & $oMyError.WinDescription & @CRLF & _
    "err.number is: " & @TAB & Hex($oMyError.Number, 8) & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oMyError.LastDllError & @CRLF & _
    "err.scriptline is: " & @TAB & $oMyError.Scriptline & @CRLF & _
    "err.source is: " & @TAB & $oMyError.Source & @CRLF & _
    "err.helpfile is: " & @TAB & $oMyError.Helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oMyError.HelpContext _

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

    _FileWriteLog($log, $error, 1)
    EndFunc

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

    Func _Exit()
    Local $size = FileGetSize($log)
    If $size / 1024 > 500 Then
    Local $aread
    _FileReadToArray($log, $aread)
    If @error Then
    _FileWriteLog($log, ".log konnte nicht automatisch verkleinert werden", 1)
    Else
    FileDelete($log)
    Local $count = 100
    If $aread[0] < $count Then
    $count = $aread[0]
    _FileWriteLog($log, ".log konnte nicht automatisch verkleinert werden", 1)
    EndIf
    _FileWriteFromArray($log, $aread, 1, $count)
    if @error then _FileWriteLog($log, "_FileWriteFromArray error:"& @error, 1)
    EndIf
    EndIf

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

    _FileWriteLog($log,"Exit ------------------------------------", 1)
    exit
    endfunc

    [/autoit]

    Einmal editiert, zuletzt von nuts (17. Oktober 2012 um 21:04)

  • Kommst diese Fehlermeldung, wenn du dein Skript direkt startest oder wenn der Task Scheduler dies tut? Ferner musst du unter Windows 2008 einen RegKey setzen, damit du den Task mit Benutzerinformationen starten kannst.

    Du kannst dich nur mir Domänen Benutzerinformation an einem DC anmelden - lokale Accounts gibt es nicht mehr.

    Ich schmeiße mal meine VM DC an und werde mal dein Problem versuchen nachzustellen.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (17. Oktober 2012 um 17:56)