;-- TIME_STAMP   2018-03-13 15:07:03   v 0.1

#RequireAdmin

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#Region ;************ Includes ************
#include-once
#include <File.au3>
;~ #include <Array.au3>
;~ #include <AutoItConstants.au3>
;~ #include <MsgBoxConstants.au3>
#EndRegion ;************ Includes ************

; WMI-Dienst gestartet?
; abfragen  : sc.exe \\ComputerName query winmgmt
; starten   : sc.exe \\ComputerName start winmgmt

; Windows Firewall WMI eingehend
; abfragen: psexec \\ComputerName netsh advfirewall firewall show rule name="Windows-Verwaltungsinstrumentation (WMI eingehend)"
; erlauben: psexec \\ComputerName netsh advfirewall firewall set rule group="Windows-Verwaltungsinstrumentation (WMI)" new enable=yes

; ESET Security musste ich temporär auf "Interaktiv" umstellen, um die neuen Firewall-Regeln ohne einen Neustart zu übernehmen.

Global $g_sLogFile = @ScriptDir & "\CheckBootUp.txt"

If Not IsAdmin() Then Exit MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL, $MB_TOPMOST), @ScriptName, "Das Skript muss mit Adminrechten gestartet werden!")

; Globales Hotkey zum Beenden des Scripts: "ESC-Taste"
If Not HotKeySet("{ESC}", _Exit) Then Exit MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL, $MB_TOPMOST), @ScriptName, "Globales HotKey 'ESC' konnte nicht gesetzt werden!")

_CheckBootUp()

Func _CheckBootUp()
	Local $hFile, $sComputerName, $sUserName, $sPassword, $aRechner = FileReadToArray(@ScriptDir & "\RechnerListe.txt")
	If Not UBound($aRechner) Then Exit MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL, $MB_TOPMOST), @ScriptName, "RechnerListe.txt nicht gefunden oder leer!")

	$hFile = FileOpen($g_sLogFile, BitOR($FO_ANSI, $FO_APPEND)) ; ANSI reicht völlig aus, wenn keine Sonderzeichen enthalten sind.

	For $i = 0 To UBound($aRechner) - 1 Step 1
		Ping($aRechner[$i], 300)
		If @error Then
			; ____________________StringFormat('11111 : 22222 : 33333 : 44', 1111111111111, 22, 33, 444444444)
			_FileWriteLog($hFile, StringFormat('%-26s : %-26s : %-26s : %s', $aRechner[$i], '', '', 'offline'))
		Else
			$sUserName = _GetUserName($aRechner[$i])
			$sComputerName = $aRechner[$i]
			$sPassword = '' ; Evtl. nächste Woche kann ich dir zeigen, wie man die Passwörter verschlüsselt speichern kann... doch jetzt habe ich keine Zeit dafür. ;-)

			; ____________________StringFormat('11111 : 22222 : 33333 : 44', 1111111111111, 22222222222, 333333333333333333333333333333333333333333333333333, 444444444444444444444444444444)
			_FileWriteLog($hFile, StringFormat('%-26s : %-26s : %-26s : %s', $sComputerName, $sUserName, _GetRegData($sComputerName, $sUserName, $sPassword), _GetLastBootUp($sComputerName)))
		EndIf
	Next

	FileClose($hFile)

	MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL, $MB_TOPMOST), @ScriptName, "Fertig")
EndFunc   ;==>_CheckBootUp

Func _GetLastBootUp($sComputer = '.') ; "." steht für lokalen Rechner
	Local $oWMIService = ObjGet("winmgmts:\\" & $sComputer & "\root\cimv2")
	If Not IsObj($oWMIService) Then Return ''
	Local $oColOperatingSystems = $oWMIService.ExecQuery("Select LastBootUpTime from Win32_OperatingSystem")
	Local $sBootup
	For $oOS In $oColOperatingSystems
		$sBootup = $oOS.LastBootUpTime ; --> 20180210112637.125599+060
	Next
	Return $sBootup = '' ? 'WMI-Dienst nicht gestartet oder keine Regeln für Windows Firewall WMI eingehend definiert!' : StringRegExpReplace($sBootup, '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).+', '\1-\2-\3 \4:\5:\6')
EndFunc   ;==>_GetLastBootUp

Func _GetUserName($strClient = @ComputerName, $strDomain = '')
	Local $objWMIService, $objItem, $colItems, $strUser, $Result
	$objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strClient)
	If Not IsObj($objWMIService) Then Return ''

	$colItems = $objWMIService.InstancesOf("Win32_Process")
	If IsObj($colItems) Then
		For $objItem In $colItems
			If ($objItem.Caption = "explorer.exe") Then
				$Result = $objItem.GetOwner($strUser, $strDomain)
				If (Not @error) And ($Result = 0) Then Return $strUser
			EndIf
		Next
	EndIf
EndFunc   ;==>_GetUserName

; Download psexec: https://technet.microsoft.com/de-de/sysinternals/bb897553.aspx
Func _GetRegData($sComputerName, $sUserName, $sPasswort = '', $bActivateAutoStart = True)
	Local $sUserID32, $sUserID64, $iPID, $sOutput, $iError

	$sPasswort = '' ? _GetPassword($sComputerName, $sUserName) : $sPasswort

	; Wenn wir diesen Schlüssel nicht lesen können, dann wurde die RemoteRegistry auf diesem Computer noch nicht gestartet!!!
	If Not RegRead('\\' & $sComputerName & "\HKCR\.txt", "") Then
		; Wird der Dienst ausgeführt?
		$iPID = Run(StringFormat('psexec \\\%s -u %s -p %s -h sc.exe query RemoteRegistry', $sComputerName, $sUserName, $sPasswort), '', @SW_HIDE, $STDOUT_CHILD)
		If Not $iPID Then Return SetError($iError, 0, 'query RemoteRegistry Error = 1')
		ProcessWaitClose($iPID)
		$sOutput = StdoutRead($iPID)
		If Not StringInStr($sOutput, 'RUNNING') Then
			; Nein, der Dienst wird momentan nicht ausgeführt... dann bitte jetzt starten!
			$iError = RunWait(StringFormat('psexec \\\%s -u %s -p %s -h sc.exe start RemoteRegistry', $sComputerName, $sUserName, $sPasswort))
			If $iError Then
				ConsoleWrite('sc.exe start RemoteRegistry - Dienst auf '&$sComputerName& ' konnte nicht gestartet werden! Error = ' & $iError & @CRLF)
				Return SetError($iError, 0, 'sc.exe start RemoteRegistry Error = ' & $iError & '!')
			EndIf
		EndIf

		; Soll der Dienst auf diesem Computer ($sComputerName) automatisch beim Systemstart gestartet werden?
		If $bActivateAutoStart Then
			; Wird der Dienst bereits automatisch beim Systemstart gestartet?
			$iPID = Run(StringFormat('psexec \\\%s -u %s -p %s -h sc.exe qc RemoteRegistry', $sComputerName, $sUserName, $sPasswort), '', @SW_HIDE, $STDOUT_CHILD)
			If Not $iPID Then Return SetError($iError, 0, 'sc.exe qc RemoteRegistry Error = 1')
			ProcessWaitClose($iPID)
			$sOutput = StdoutRead($iPID)
			If Not StringInStr($sOutput, 'AUTO_START') Then
				; Nein, der Dienst wird nicht automatisch beim Systemstart gestartet... dann Starttype auf Auto setzen!
				$iError = RunWait(StringFormat('psexec \\\%s -u %s -p %s -h sc.exe config RemoteRegistry start= auto', $sComputerName, $sUserName, $sPasswort)) ; Leerzeichen nach "start= " ist wichtig!!!
				If $iError Then
					ConsoleWrite('sc.exe config RemoteRegistry start= auto - Autostart konnte nicht aktiviert werden! Error = ' & $iError & @CRLF)
					Return SetError($iError, 0, 'sc.exe config RemoteRegistry start= auto Error = ' & $iError & '!')
				EndIf
			EndIf
		EndIf
	EndIf

	; 32-Bit-Software?
	$sUserID32 = RegRead("\\" & $sComputerName & "\HKCU\SOFTWARE\pSAG\proalpha-client-production\5.1\proALPHA Session", "UserID")
	; 64-Bit-Software?
	$sUserID64 = RegRead("\\" & $sComputerName & "\HKCU64\SOFTWARE\pSAG\proalpha-client-production\5.1\proALPHA Session", "UserID")
	Switch True
		Case $sUserID32 <> ''
			MsgBox(64, @ScriptName, '\HKCU\ ist der richtige Schlüssel!!!')
			Return $sUserID32
		Case $sUserID64 <> ''
			MsgBox(64, @ScriptName, '\HKCU64\ ist der richtige Schlüssel!!!')
			Return $sUserID64
		Case Else
			MsgBox(64, @ScriptName, 'pSAG ist nicht auf "' & $sComputerName & '" installiert!!!')
			Return SetError(1, 0, 'pSAG ist nicht auf "' & $sComputerName & '" installiert!!!')
	EndSwitch
EndFunc   ;==>_GetRegData

Func _GetPassword($sComputerName, $sUserName)
	Return InputBox(@ScriptName, StringFormat('ComputerName: %s\r\rUserName: %s\r\r\rPasswort eingeben: ', $sComputerName, $sUserName), '*')
EndFunc

Func _Exit()
	Exit
EndFunc   ;==>_Exit
