STEALTHCHIP.DE
:: I WANT TO DECRYPT.


Nikon-Blogger-Linkring :: powered by KLUGERD
TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste
Blogverzeichnis Bloggerei.de - Fotoblogs




2024-07-26
SAAD - Ein Hoch auf die Systemadministratoren!


Letzten Freitag hat sich ein IT-Sicherheitsunternehmen (Crowdstrike Holdings, Inc. ) nicht gerade mit Ruhm bekleckert. Das Ergebnis: zahlreiche Systemadministratoren mussten viele Überstunden leisten und das Wochenende war für viele Menschen außerhalb der IT-Branche ruiniert.

Dank der Disziplin und Expertise weltweit beschäftigter Systemadministratoren konnten die meisten Systeme schlussendlich wieder in Betrieb genommen werden. Auch wenn mein Arbeitgeber nicht direkt betroffen war und mein Team sich folglich stressfrei ins Wochenende verabschiedete, möchte ich pünktlich zum System Administrator Appreciation Day allen interessierten Informatikern mit diesem Beitrag meine Wertschätzung ausdrücken und einige praktische Lösungsschablonen aus meiner beruflichen Praxis vorstellen.

Lösungsschablonen:
Entscheidungsfindung für Dateidownload über ein Datumsvergleich
Microsoft Exchange 2016: Berichtserstellung über Verteilergruppenbesitzer
PHP: LDAP-Authentifizierung

Entscheidungsfindung für Dateidownload über ein Datumsvergleich

In der beruflichen Praxis eines Systemadministrators kommt es häufig vor, dass bestimmte Dateien nur dann heruntergeladen oder aktualisiert werden müssen, wenn sie neuer sind als die bereits vorhandenen. Eine einfache, aber effektive Methode zur Entscheidungsfindung für Dateidownloads basiert auf einem Datumsvergleich.

Hinzu kommt, dass der vom Betriebssystem aufgedrückte Zeitstempel nach dem Download mit dem Zeitstempel der Downloadquelle synchronisiert werden muss, um einen effizienten Datumsvergleich (ab dem zweiten Durchlauf) durchzuführen.

Ausschlaggebend für den Download ist der Zeitstempel - beispielsweise: 2024-07-26 13:45.

Hier ist ein praktisches Beispiel, wie dies mit einem PowerShell-Skript umgesetzt werden kann:

<#
RSA-Update-Downloader Ver. 0.2
(C) Alexander H. / STEALTHCHIP.DE
#>

Start-Transcript -Path "C:\Skripte\RSAUPDATE\RSAKEYDATE-Transcript.log"
$url = "https://trustcenter-data.itsg.de/dale/gesamt-rsa4096.key"
$verzeichnis = "C:\Skripte\RSAUPDATE\RSAFILE"
$logdateipfad = "C:\Skripte\RSAUPDATE\RSAKEYDATE.log"

$dateipfad = Join-Path $verzeichnis (Split-Path $url -Leaf)
if (Test-Path $dateipfad) {
    $lastModifiedRemote = (Invoke-WebRequest -Uri $url -Method Head -UseBasicParsing).Headers["Last-Modified"]
    $lastModifiedRemoteDateTime = [DateTime]::ParseExact($lastModifiedRemote, "ddd, dd MMM yyyy HH:mm:ss 'GMT'", [System.Globalization.CultureInfo]::InvariantCulture)
    $creationTimeLocal = (Get-Item $dateipfad).CreationTime

    if ($creationTimeLocal -lt $lastModifiedRemoteDateTime) {
        Invoke-WebRequest -Uri $url -OutFile $dateipfad
        (Get-Item $dateipfad).CreationTime = $lastModifiedRemoteDateTime
        $logText = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | Datei heruntergeladen und Erstelldatum aktualisiert."
        Add-Content -Path $logdateipfad -Value $logText
    } else {
        $logText = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | Die Datei ist bereits vorhanden und aktuell."
        Add-Content -Path $logdateipfad -Value $logText
    }
} else {
    Invoke-WebRequest -Uri $url -OutFile $dateipfad
    $lastModified = (Invoke-WebRequest -Uri $url -Method Head -UseBasicParsing).Headers["Last-Modified"]
    $lastModifiedDateTime = [DateTime]::ParseExact($lastModified, "ddd, dd MMM yyyy HH:mm:ss 'GMT'", [System.Globalization.CultureInfo]::InvariantCulture)
    (Get-Item $dateipfad).CreationTime = $lastModifiedDateTime
    $logText = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | Datei heruntergeladen und Erstelldatum aktualisiert."
    Add-Content -Path $logdateipfad -Value $logText
}
Stop-Transcript
					
Der unter $verzeichnis angegebene Ordner muss vor Skriptausführung erstellt werden.

Ein häufiger Fehler beim Kontrollieren ist; visuell abweichende, aber korrekte Zeitstempel aufgrund von unterschiedlichen Zeitzonen falsch zu interpretieren (zum Beispiel 2024-07-26 13:45 > 2024-07-26 11:45).

Visuell abweichender aber korrekter Zeitstempel (2024-07-26 13:45 > 2024-07-26 11:45) - Zeitzone...

Update 2024-09-10:

Microsoft Exchange 2016: Berichtserstellung über Verteilergruppenbesitzer

Benutzer, Gruppen, Postfächer und andere Exchange-bezogene Einstellungen werden über das EAC (Exchange Admin Center) verwaltet. Die webbasierte Verwaltungsoberfläche für Exchange Server bietet jedoch nicht immer die gewünschten Lösungen - insbesondere wenn es um die Exportmöglichkeit aller Verteilergruppen mit ihren Besitzern geht. Hier bietet die Exchange Management Shell eine leistungsstarke Alternative.

Im integrierten Reportdialog stehen die Verteilerbesitzer nicht zur Auswahl.

Mit einem PowerShell-Skript lassen sich detaillierte Berichte über die Besitzer von Verteilergruppen erstellen. Im Folgenden wird gezeigt, wie dies umgesetzt werden kann:


<#
Exchange-Verwaltungsgruppen-Reportgenerator Ver. 0.1
(C) Alexander H. / STEALTHCHIP.DE
#>

# Ermitteln des Skriptverzeichnisses
$scriptPath = $PSScriptRoot
$exportPath = Join-Path -Path $scriptPath -ChildPath "DistributionGroups.csv"
$logPath = Join-Path -Path $scriptPath -ChildPath "DistributionGroups.log"

# Logdatei erstellen oder überschreiben
Out-File -FilePath $logPath -Encoding UTF8

# Alle Verteilergruppen und dynamischen Verteilergruppen abrufen
$distributionGroups = Get-DistributionGroup -ResultSize Unlimited
$dynamicDistributionGroups = Get-DynamicDistributionGroup -ResultSize Unlimited

# Beide Gruppenarten in einer Sammlung zusammenführen
$allGroups = $distributionGroups + $dynamicDistributionGroups

# Ein Array initialisieren, um die Gruppeninformationen zu speichern
$result = @()

# Über jede Gruppe iterieren, um die erforderlichen Informationen zu sammeln
foreach ($group in $allGroups) {
    $owners = $group.ManagedBy
    $ownerEmails = @()
    
    foreach ($owner in $owners) {
        # Versuchen, die E-Mail-Adresse des Besitzers abzurufen
        $ownerEmail = (Get-Recipient $owner -ErrorAction SilentlyContinue).PrimarySmtpAddress
        if ($ownerEmail) {
            $ownerEmails += $ownerEmail
        } else {
            # Protokollieren des Fehlers in die Logdatei
            $logMessage = "Der Besitzer $owner konnte nicht abgerufen werden. Zugewiesene Gruppe: $($group.DisplayName)"
            $logMessage | Out-File -FilePath $logPath -Append -Encoding UTF8
        }
    }
    
    $groupType = if ($group.RecipientTypeDetails -eq "DynamicDistributionGroup") { "Dynamische Verteilergruppe" } else { "Verteilergruppe" }
    
    $result += [PSCustomObject]@{
        DisplayName = $group.DisplayName
        EmailAddress = $group.PrimarySmtpAddress
        GroupType = $groupType
        Owners = $ownerEmails -join "; "
    }
}

# Die Ergebnisse in eine CSV-Datei exportieren
$result | Export-Csv -Path $exportPath -NoTypeInformation -Encoding UTF8

Write-Host "Export abgeschlossen. Die CSV-Datei befindet sich unter $exportPath"
Write-Host "Fehlerhafte Besitzer wurden in der Logdatei protokolliert: $logPath"
					
Update 2024-09-13:

PHP: LDAP-Authentifizierung

In vielen Unternehmensnetzwerken ist LDAP (Lightweight Directory Access Protocol) ein
essenzieller Bestandteil zur Verwaltung und Authentifizierung von Benutzern.

Eine LDAP-Authentifizierung kann auch in einer PHP-Anwendung implementiert werden:

<!DOCTYPE html>
<html>
<head>
    <title>LDAP-Anmeldungstemplate Ver. 0.1</title>
    <!--(C) Alexander H. / STEALTHCHIP.DE-->
    <meta charset="UTF-8">
    <style>
        body, html {
            margin: 0;
            padding: 0;
            height: 100%;
            overflow: hidden;
        }
        .login-container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        .login-form {
            display: flex;
            flex-direction: column;
            width: 300px;
        }
        .login-form label {
            text-align: left;
            margin-bottom: 5px;
        }
        .login-form input[type="text"], .login-form input[type="password"], .login-form input[type="submit"] {
            width: 100%;
            margin-bottom: 10px;
            padding: 8px;
            box-sizing: border-box;
        }
    </style>
    <script>
        function logToConsole(message) {
            console.log(message);
        }
    </script>
</head>
<body>
    <div class="login-container">
        <form class="login-form" method="POST" action="">
            <label for="username">Benutzername:</label>
            <input type="text" id="username" name="username">
            
            <label for="password">Passwort:</label>
            <input type="password" id="password" name="password">
            
            <input type="submit" value="Anmelden">
        </form>
    </div>

    <?php
    function log_message($message) {
        echo "<script>logToConsole('$message');</script>";
    }

    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $username = isset($_POST['username']) ? $_POST['username'] : '';
        $password = isset($_POST['password']) ? $_POST['password'] : '';
        
        if (empty($username) || empty($password)) {
            log_message('Benutzername und Passwort dürfen nicht leer sein.');
        } else {
            $server = '';
            $domain = '@';
            $port = 389;

            $ldap_connection = ldap_connect($server, $port);

            if (!$ldap_connection) {
                log_message('Verbindung zum LDAP-Server fehlgeschlagen.');
                exit;
            }

            ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3);
            ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0);

            $ldap_bind = @ldap_bind($ldap_connection, $username . $domain, $password);

            if (!$ldap_bind) {
                log_message('Anmeldung am LDAP-Server fehlgeschlagen.');
            } else {
                log_message('Anmeldung erfolgreich!');
            }

            ldap_close($ldap_connection);
        }
    }
    ?>
</body>
</html>
Diese LDAP-Authentifizierungslogik kann als grundlegende Vorlage für eigene Webdienste
verwendet werden. Für eine erfolgreiche Authentifizierung sind jedoch noch der Server
und die Domäne in den dafür vorgesehenen Variablen anzugeben.

Fehler- und Erfolgsmeldungen werden in der Debugkonsole des Browsers ausgegeben.

Ähnliche Artikel:


2024-01-16 - ...lesen.

2024-01-03 - ...lesen.

2023-03-25 - ...lesen.