Zum Inhalt springen

Windows Start/Beenden netzwerkweit protokollieren

Netzwerkweite, datenbankbasierte Protokollierung von Windows Start/Herunterfahren. Umgesetzt mit Gruppenrichtlinie, Powershell, PHP und MySQL.

Warum?

Windows Start/Laufzeit/Beenden lässt sich auf mehreren Wegen mitverfolgen. Mit dieser Lösung wird clientseitig bei jedem Windows-Start bzw. Beenden ein kleines, per Gruppenrichtlinie definiertes, Powershell-Script gestartet, dass lediglich eine Website mit den entsprechenden Parametern kontaktiert. Die Website beinhaltet ein kleines PHP-Script, dass den Vorgang in eine MySQL-Datenbank speichert und auf Anfrage eine Übersicht ausgibt.

Achtung: Leider konnte ich aus Zeitgründen keine größeren Tests durchführen! Das Powershell-Script funktioniert aber scheinbar nicht auf Windows 7 Systemen! Mit Windows 10 und Windows Server 2012 (R2) konnte ich bislang keine Probleme feststellen!

Webserver

Sofern kein Intranet-Webserver mit PHP und MySQL zur Verfügung steht, bitte herunterladen/installieren (z.B. XAMPP)!

MySQL-Datenbank „startstoplog“ erzeugen

Datenbank „startstoplog“ vorab manuell erzeugen und folgende SQL-Befehle darin ausführen:

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

-- Datenbank: `startstoplog`
-- --------------------------------------------------------

-- Tabellenstruktur für Tabelle `startstoplog`

CREATE TABLE `startstoplog` (
  `id` int(11) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `type` varchar(5) NOT NULL,
  `computer` varchar(50) NOT NULL,
  `ip` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Indizes für die Tabelle `startstoplog`

ALTER TABLE `startstoplog`
  ADD PRIMARY KEY (`id`),
  ADD KEY `computer` (`computer`),
  ADD KEY `timestamp` (`timestamp`);

-- AUTO_INCREMENT für Tabelle `startstoplog`

ALTER TABLE `startstoplog`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;COMMIT;Code-Sprache: JavaScript (javascript)

PHP-Script: startstoplog\index.php

Das folgende PHP-Script sollte im Pfad http://webserver/startstoplog/ als index.php abgelegt werden. Je nach MySQL-Konfiguration müssen evtl. die Zugangsdaten angepasst werden: $mysqli = new mysqli(„mysqlserver„, „benutzername„, „passwort„, „datenbankname„);

<html>
    <head>
        <title>StartStopLog</title>
        <style type="text/css">
        *{font-family:Verdana,Helvetica,Arial;font-size:14px;}
        h1{font-size:21px;}
        a:link, a:hover, a:visited, a:active{color:#000;}
        </style>
    </head>
<body>
    <h1>StartStopLog</h1>    
<?php

$mysqli = new mysqli("localhost", "root", "", "startstoplog");

if(isset($_GET['type'])){

    // LOGGING
    $type = $mysqli->real_escape_string($_GET['type']);
    $ip = $mysqli->real_escape_string($_SERVER['REMOTE_ADDR']);
    $host = $mysqli->real_escape_string(gethostbyaddr($_SERVER['REMOTE_ADDR']));

    if(!$mysqli->query("INSERT INTO `startstoplog` SET `type` = '".$type."', `computer` = '".$host."', `ip` = '".$ip."'")){
        print('Error: '.$mysqli->errno.' - '.$mysqli->error);
    } else {
        print($host.' ('.$ip.') '.$type.' logged');        
    }
        
    
} else {
    
    // VIEWER-Auswahl
    $q = $mysqli->query("SELECT * FROM `startstoplog` GROUP BY `computer` ASC");

    ?><form action="" method="get">
        <select name="computer">
            <option></option>
    <?php
        while($r = $q->fetch_assoc()){
        ?><option <?php $_GET['computer'] == $r['computer'] ? print(' selected') : '' ?>><?php print($r['computer']) ?></option><?php
    }
    ?>
        </select>
        
        <input type="submit" value="anzeigen" />
    </form><?php

    // VIEWER-Ausgabe
    $computer = $mysqli->real_escape_string($_GET['computer']);
    $q = $mysqli->query("SELECT * FROM `startstoplog` WHERE `computer` = '".$computer."' ORDER BY timestamp DESC LIMIT 1000");
    while($r = $q->fetch_assoc()){
        print($r['timestamp'].' - '.$r['type'].'<br>');
    }
}
?>
</body>
</html>Code-Sprache: JavaScript (javascript)

Powershell-Script: startstoplog.ps1

Webserver ändern und vorerst am Desktop abspeichern: Invoke-WebRequest „http://webserver/startstoplog/?type=$type“…

param(
    [string]$type
)
if($type -eq $null){
    echo "ERROR"
} else {
    Invoke-WebRequest "http://webserver/startstoplog/?type=$type" -WebSession $Session -TimeoutSec 5
}Code-Sprache: PHP (php)

Gruppenrichtlinie

Die zuvor erstellte Powershell-Scriptdatei startstoplog.ps1 wird per Gruppenrichtlinie verteilt und ausgeführt. Der Gruppenrichtlinienverwaltungs-Editor ermöglicht Powershell-Script-Ausführung z.B. über Computerkonfiguration → Richtlinien → Windows-Einstellungen → Scripts (Start/Herunterfahren).

In den Eigenschaften von „Starten„, wird „Powershell-Scripts“ wie folgt konfiguriert:

  • startstoplog.ps1 im Speicherort der Gruppenrichtlinie (Schaltfläche „Dateien anzeigen“) ablegen
  • über Schaltfläche „Hinzufügen…“ mit “ – type start“ einbinden:

Vorgang in den Eigenschaften von „Herunterfahren“ wiederholen, aber „- type stop“ verwenden:

Fehlerbehebung

Mögliche Gründe, warum es nicht auf Anhieb funktioniert:

  • Gruppenrichtlinie ist noch nicht auf dem Client angekommen. gpupdate /force am Client kann den Vorgang beschleunigen.
  • Client wird nicht von Gruppenrichtlinie umfasst (z.B. durch Gruppenrichtlinie-Sicherheitsfilter ausgeschlossen).

Um Gruppenrichtlinien oder Powershell-Probleme auszuschließen, kann das PHP-Script natürlich auch manuell aufgerufen werden:

  • „Start“ loggen: http://webserver/startstoplog/?type=start
  • „Beenden“ loggen: http://webserver/startstoplog/?type=stop

Falls die Seiten auch manuell nicht erreichbar sind, liegt es möglicherweise an einer fehlerhaften Firewall-Konfiguration (z.B. Windows Firewall lässt keine Anfragen an den Apache Webserver durch).

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

sechzehn + siebzehn =