Benutzer-Werkzeuge

Webseiten-Werkzeuge


powershell:ad:healthcheck

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
powershell:ad:healthcheck [2019/04/02 10:10] – gelöscht henningpowershell:ad:healthcheck [2024/05/27 08:36] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== ad-healthcheck.ps1 ======
 +Das Skript automatisiert den regelmäßig erforderlichen [[ad:healthcheck|AD-Healthcheck]]
  
 +Am längsten dauert die Abfrage der Eventlogs, wenn diese nicht zu groß werden, beschleunigt sich die Ausführung erheblich.\\
 +
 +Der Replikationstest funktionert nur von einem Rechner mit Windows 8 mit RSAT-Tools(?) Zumindest gibt es diesen Befehl in der Powershell unter Windows 2008R2 nicht ausführen.
 +====== Skript ======
 +====== ad-healthcheck.ps1 ======
 +Das Skript automatisiert den regelmäßig erforderlichen [[ad:healthcheck|AD-Healthcheck]]
 +
 +Am längsten dauert die Abfrage der Eventlogs, wenn diese nicht zu groß werden, beschleunigt sich die Ausführung erheblich.\\
 +
 +Der Replikationstest funktionert nur von einem Rechner mit Windows 8 mit RSAT-Tools(?) Zumindest gibt es diesen Befehl in der Powershell unter Windows 2008R2 nicht ausführen.
 +====== Skript ======
 +<file powershell ad-healthcheck.ps1>
 +<#AD-Healthcheck
 +Autor:   Henning Löser
 +version: 1.0
 +
 +Was macht das Skript?
 +Abfolge der Befehlszeilen für den AD-Healthcheck. 
 +ACHTUNG: Wird das Skript aus der ISE ausgeführt, so kann keine Logdatei erstellt und geöffnet werden!
 +#>
 +$SmtpServer=EIGENER-EMAIL-SERVER
 +$SmtpSender=EIGENE-ABSENDER-EMAIL
 +$SmtpRecipient=EIGENE-EMPFÄNGER-EMAIL
 +$LocalSystem = (Get-WmiObject -Class Win32_ComputerSystem).name
 +$timestamp=(Get-Date -Format yyyMMdd-Hmmss)
 +$LogPath="C:\ProgramData\Skripte\logs\ad-healthcheck"
 +$LogFile="$logpath\$timestamp`.$localsystem`.ad-healtcheck.txt"
 +" "  | Out-File -Encoding utf8 -filepath $logfile -Append
 +$start=Get-Date -Format "dddd, dd.MM.yyy H:mm:ss"
 +"Domaincheck gestartet: "+$start | Out-File -Encoding utf8 -filepath $logfile -Append
 +"---------- "  | Out-File -Encoding utf8 -filepath $logfile -Append
 +" "  | Out-File -Encoding utf8 -filepath $logfile -Append
 +# Skript nur unter einem Domänen-Admin-Account ausführen
 +if (Get-ADGroupMember "Domänen-Admins" | Where-Object {$_.SamAccountName -eq $env:Username })
 +
 +         "Das Skript wird unter dem Account von `""+$env:Username+"`" ausgeführt."  | Out-File -Encoding utf8 -filepath $logfile -Append
 + }
 + else
 + {
 + "Das Skript kann nicht unter dem Account von `""+$env:Username+"`" ausgeführt werden, da es kein Domänen-Admin-Account ist!" | Out-File -Encoding utf8 -filepath $logfile -Append
 + Send-MailMessage -SmtpServer "$SmtpServer" -from "$SmtpSender" -to "$SmtpRecipient" -Subject "AD-Healthcheck vom $start`: Prüfung nicht möglich" -body "Das Skript funktioniert nur unter einem Domänen-Admin-Account. `nDer Benutzer `"$env:Username`" erfüllt diese Bedingung nicht." -Encoding utf8
 +        break #Script wird beendet
 + }
 +
 +
 +#####
 +# Alle aktuellen Domänencontroller finden:
 +##
 +$domain_dcs = Get-ADDomainController -Filter * | Select-Object hostname
 +
 +
 +#####
 +# DCDIAG
 +##
 +
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 1/7: Verzeichnisserverdiagnose `"dcdiag`"" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"----------"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +foreach ($domain_dc in $domain_dcs)
 +    {$check =  invoke-command -computername $domain_dc.hostname {dcdiag | Select-String "nicht bestanden"}
 +    if ($check -eq $null)
 +        {
 +        "TEST BESTANDEN: DC-Diag auf `""+$domain_dc.hostname+"`" hat keine Fehler ausgegeben." | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    Else
 +        {
 +        "FEHLER: DC-Diag auf `""+$domain_dc+"`" hat eine Fehlermeldung verursacht!" | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    " "  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    }
 +
 +#####
 +# REPLIKATION
 +##
 +
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 2/7: Replikation prüfen `"repadmin /replsum`"" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"---------- " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +
 +$check=$false
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +$replicats = Get-ADReplicationPartnerMetadata -Target * -Partition * | Select-Object server,partner,partition,lastreplicationattempt,lastreplicationsuccess,lastreplicationresult
 +$check=$false
 +$compare=(get-date).AddMinutes(-90)
 +foreach ($replicat in $replicats)
 +    {
 +    if (($replicat.lastreplicationresult -notlike 0) -or ($replicat.lastreplicationsuccess -lt $compare))
 +        {
 +        "FEHLER: Server:"+$replicat.server+", Partition: "+$replicat.partition+", zuletzt erfogreich: "+$replicat.lastreplicationsuccess+", letztes Ergebnis: "+$replicat.lastreplicationresult  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +    }
 +
 +if ($check -eq $false)
 +    {
 +    "TEST BESTANDEN: Bei der Replikation wurden keine Fehler oder Verzögerungen festgestellt." | Out-File -Encoding utf8 -filepath $logfile -Append
 +    }
 +
 +
 +#####
 +# BETRIEBSMASTER
 +##
 +    
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 3/7: Betriebsmaster-Rollen prüfen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"---------- " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Alle Rollen sollen auf dem `"DC-ESSEN-01`" liegen!" | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +#Get-ADDomainController -Filter *| %{$_.Name + ": " + $_.OperationMasterRoles}  | Out-File -Encoding utf8 -filepath $logfile -Append
 +foreach ($domain_dc in $domain_dcs)
 +    {
 +    $check=Get-ADDomainController $domain_dc.hostname | Select-Object OperationMasterRoles
 +    if ($domain_dc.hostname -like "DC-ESSEN-01.secunet.de")
 +        {
 +        if ($check.OperationMasterRoles.Count -like "5")
 +            {
 +            "TEST BESTANDEN: `""+$domain_dc.hostname+"`" hat "+$check.OperationMasterRoles.Count+" Rollen zugewisen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        Else
 +            {
 +            "FEHLER: `""+$domain_dc.hostname+"`" hat "+$check.OperationMasterRoles.Count+" Rollen zugewisen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        }
 +    Else
 +        {
 +        if ($check.OperationMasterRoles.Count -like "0")
 +            {
 +            "TEST BESTANDEN: `""+$domain_dc.hostname+"`" hat "+$check.OperationMasterRoles.Count+" Rollen zugewisen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        Else
 +            {
 +            "FEHLER: `""+$domain_dc.hostname+"`" hat "+$check.OperationMasterRoles.Count+" Rollen zugewisen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        }
 +    } 
 +
 +
 +#####
 +# ZEITEINSTELLUNGEN
 +##
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 4/7:Prüfen der lokalen Zeiteinstellungen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"---------- " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +
 +
 +foreach ($domain_dc in $domain_dcs)
 +    {
 +    "Zeiteinstellungen auf: "+$domain_dc.hostname  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    $check = invoke-command -computername $domain_dc.hostname {get-itemproperty "HKLM:\SYSTEM\CurrentControlSet\services\W32Time\Parameters"}
 +    "System: "+$domain_dc.hostname+" - Time-Typ: "+$check.Type+" - NTP-Server: "+$check.NtpServer  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    if ($domain_dc.hostname -like "DC-ESSEN-01.secunet.de")
 +        {
 +        if (($check.type -like "NTP") -and ($check.NtpServer -like "pool.ntp.org"))
 +            {
 +            "TEST BESTANDEN: Zeiteinstellungen korrekt" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        Else
 +            {
 +            "FEHLER: Zeiteinstellungen nicht korrekt" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        }
 +    Else
 +        {
 +        If ($check.type -like "NT5DS")
 +            {
 +            "TEST BESTANDEN: Zeiteinstellungen korrekt" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }
 +        Else
 +            {
 +            "FEHLER: Zeiteinstellungen nicht korrekt" | Out-File -Encoding utf8 -filepath $logfile -Append
 +            }    
 +        }
 +    " " | Out-File -Encoding utf8 -filepath $logfile -Append
 +    }
 +
 +#####
 +# Speicherplatz
 +##
 +
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 5/7: Freien Speicherplatz auf Laufwerk C prüfen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"----------" | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +foreach ($domain_dc in $domain_dcs)
 +    {
 +    "Laufwerk `"C:\`" auf: "+$domain_dc.hostname  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    $check=invoke-command -computername $domain_dc.hostname {get-wmiobject win32_volume -Filter 'drivetype = 3' | Where-Object name -eq "C:\"}
 +    $size=($check.FreeSpace)/1000000000
 +    If ($check.FreeSpace -gt 5000000000)
 +        {
 +        "TEST BESTANDEN: Ausreichend freier Speicher auf Partition `""+$check.name+"`" verfügbar,"+[System.Math]::Round($size, 0)+"GB" | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    Else
 +        {
 +        "FEHLER: Der Verfügbare Speicher auf Partition `""+$check.name+"`" hat den Grenzwert von 5GB unterschritten. Aktuell sind nur noch "+[System.Math]::Round($size, 0)+"GB verfügbar." | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    " " | Out-File -Encoding utf8 -filepath $logfile -Append
 +    }
 +
 +
 +#####
 +# Eventlogs
 +##
 +
 +
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 6/7: Eventlogs prüfen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"----------" | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Es wird lediglich die Zahl aller Meldungen ausgegeben, sowie die Zahl der Fehler pro Log." | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Sollten Fehler angezeigt werden, diese bitte prüfen, ggf. beheben und danach das entsprechende Log speichern und löschen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"!Leere Eventlogs können nicht durchsucht werden, wordurch es zu Fehlermeldungen bei der Skriptausführung kommt!" | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +$check=$false
 +foreach ($domain_dc in $domain_dcs)
 +    {
 +    " " | Out-File -Encoding utf8 -filepath $logfile -Append
 +    "---Eventlogs auf: "+$domain_dc.hostname  | Out-File -Encoding utf8 -filepath $logfile -Append
 +
 +#    $Protokoll="Active Directory Web Services"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Active Directory Web Services"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Active Directory Web Services" | where-object entrytype -match error}).count
 +    "Protokoll: `"Active Directory Web Services`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"Active Directory Web Services`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +
 +#    $Protokoll="Application"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Application"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Application" | where-object entrytype -match error}).count
 +    "Protokoll: `"Application`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"Application`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +
 +#    $Protokoll="DFS Replication"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "DFS Replication"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "DFS Replication" | where-object entrytype -match error}).count
 +    "Protokoll: `"DFS Replication`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"DFS Replication`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +
 +#    $Protokoll="Directory Service"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Directory Service"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Directory Service" | where-object entrytype -match error}).count
 +    "Protokoll: `"Directory Service`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"Directory Service`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +
 +#    $Protokoll="DNS Server"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "DNS Server"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "DNS Server" | where-object entrytype -match error}).count
 +    "Protokoll: `"DNS Server`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"Active Directory Web Services`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +<#
 +#    $Protokoll="Security"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Security"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Security" | where-object entrytype -match error}).count
 +    "Protokoll: `"Security`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER! Das Protokoll `"DNS Server`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +#>
 +
 +#    $Protokoll="System"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "System"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "System" | where-object entrytype -match error}).count
 +    "Protokoll: `"System`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"System`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +
 +#    $Protokoll="Windows PowerShell"
 +    $Count = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Windows PowerShell"}).count
 +    $ErrorCount = (invoke-command -computername $domain_dc.hostname {Get-EventLog "Windows PowerShell" | where-object entrytype -match error}).count
 +    "Protokoll: `"Windows PowerShell`" - Meldungen insgesamt: "+$count+", davon Fehler: "+$ErrorCount | Out-File -Encoding utf8 -filepath $logfile -Append
 +    If ($ErrorCount -notlike "0")
 +        {
 +        "FEHLER: Das Protokoll `"Windows PowerShell`" auf `""+$domain_dc.hostname+"`" muss manuell geprüft werden!"  | Out-File -Encoding utf8 -filepath $logfile -Append
 +        $check=$true
 +        }
 +    }
 +if ($check -eq $false)
 +    {
 +    " "  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    "TEST BESTADNEN: Es wurden keine Fehler gefunden."  | Out-File -Encoding utf8 -filepath $logfile -Append
 +    }
 +
 +#####
 +# Global Catalog
 +##
 +
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Schritt 7/7: Prüfen, ob jeder DC die Rolle des Globalen Katalogs zugewiesen hat:" | Out-File -Encoding utf8 -filepath $logfile -Append
 +"---------- " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +foreach ($domain_dc in $domain_dcs)
 +    {
 +    $check=Get-ADDomainController dc-essen-01 | select-object name,isglobalcatalog
 +    if ($check.isglobalcatalog -eq $true)
 +        {
 +        "TEST BESTANDEN: `""+$domain_dc.hostname+"`" hat die Rolle `"GC`" zugewiesen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    Else
 +        {
 +        "FEHLER: `""+$domain_dc.hostname+"`" hat die Rolle `"GC`" nicht zugewiesen" | Out-File -Encoding utf8 -filepath $logfile -Append
 +        }
 +    }
 +
 +$stop=Get-Date -Format "dddd, dd.MM.yyy H:mm:ss"
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +" " | Out-File -Encoding utf8 -filepath $logfile -Append
 +"Domaincheck beendet um: "+$stop | Out-File -Encoding utf8 -filepath $logfile -Append
 +#Stop-Transcript
 +
 +#####
 +# Ergebnisse per Mail versenden
 +##
 +Send-MailMessage -SmtpServer "$SmtpServer" -from "$SmtpSender" -to "$SmtpRecipient" -Subject "AD-Healthcheck vom $start`: Prüfung durchgeführt" -body "Im Anhang befindet sich eine bereinigte Auswertung.`nBei Hinweisen auf Fehler ist eine weitere Analyse auf den betroffenen Systemen erforderlich.`n`nDie Eventlogs sollten regelmäßig geprüft und danach gesichert und gelöscht werden." -Attachments "$logfile" -Encoding utf8
 +</file>
powershell/ad/healthcheck.1554192627.txt.gz · Zuletzt geändert: 2024/05/27 08:34 (Externe Bearbeitung)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki