Rapport Quotidien des modifications Active Directory.
By: Date: 16 février 2021 Categories: BrickABrack #PowerShell,Scripting pour les fainéants Étiquettes :

Le but :

Avoir un jolie rapport le matin, qui récapitule l’ensemble des modifications faites sur l’Active Directory. Bien évidement, cela ne remplacera pas une solution type : Netwrix ou autres mais ça a le mérite de fonctionner
Exemple (bon ok, tout est flouté mais c’est normal) :

Les prérequis :

  1. Activer la fonction d’audit avancée via GPO sur les contrôleurs de domaine.
    Voici la configuration de ma GPO appliquée sur les contrôleurs de domaine.

// Prévoyez du stockage supplémentaire si vous êtes déjà limite car la GPO ci dessus augmente la taille alloué aux journaux d’audit » //

Le script :

Le principe du script :

Le script est divisé en 7 fonctions chacune indépendante de l’autre (vous pouvez donc en désactiver une sans que le rapport soit impacté.
Chaque fonction écrit dans un fichier HTML
Les 6 premières fonctions sont :

  • Rapport sur le changement de groupe. Ajout ou suppression d’appartenance à un groupe. Avec en bonus, un avertissement si le groupe en question est « Admins du Domaine »
  • Rapport sur le changement de statuts d’un objet : désactivation
  • Rapport sur le changement de statuts d’un objet : activation (la réactivation et la création d’un objet est pris en compte)
  • Rapport sur la suppression d’un objet (User / Computer / DNS etc)
  • Rapport sur le blocage d’un compte AD (exemple : verrouillage d’un compte suite à plusieurs mot de passe)
  • Rapport sur la modification d’une GPO. Indique quelle GPO a été modifié et par qui mais impossible de savoir quoi (pour le moment)

Le tout dans un rapport avec des entêtes et des couleurs, exemple :

DateDomaineUtilisateurActionCiblePar qui
19/01/2021 15:40:37MONDOMAINBIANCHIFait maintenant parti du groupe :GROUPE_CIBLEMONDOMAIN\un_admin

La dernière fonction consiste à envoyer le rapport (le fichier HTML) par Email.

Comment ça fonctionne ?

Le script va s’exécuter le matin (via une tache planifiée par exemple) et va lire le journal des évènements Windows (Security) à J-1 (donc la veille) afin de chercher des ID d’Event en fonction du besoin.

Ensuite, à chaque « match » d’ID, le script va lire les propriétés de l’event afin de récolter les informations nécessaire, mettre en forme, et le stocker dans une variable ($obj) pour ensuite y intégrer dans un tableau ($Table)

Chaque fonctions procèdent de la sorte.

Les variables des 6 fonctions à modifier :

Comme expliqué plus haut, chaque fonction est indépendante. Il y a donc les mêmes variables à chaque fonction.
les variables à modifier sont :

  • $starttime = (get-date).adddays(-1) : Si vous souhaitez un rapport sur 2 ou 3 jours précédents, changez le -1 en -2 ou -3 etc
  • $file = « C:\administration\AD_reports\rapport.html » : C’est l’emplacement du fichier HTML.

NB : Si vous souhaitez généraliser les variables vous pouvez mettre un :
$Global:$starttime = (get-date).adddays(-1)
$Global:$file = « C:\administration\AD_reports\rapport.html »
au début du script et supprimer les mêmes variables présentes dans les fonction afin de faire les modifications une fois sur l’ensemble des fonctions.

Les variables de la dernière fonction (Mail) à modifier :

Les variables à modifier sont :

  • $file = « C:\administration\AD_reports\rapport.html »-> Emplacement du fichier HTML généré par les fonctions
  • $smtpServer = « smtp@serveur.com » -> Le serveur SMTP
  • $MailFrom = « dc@email.com » -> Expéditeur
  • $mailto = « email@email.com », « email2@email.com » -> destinataires

Le script :

function change_groupe {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=4728;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{
           
            $SID   = $Event.Properties[1].Value
            $UserName = $(Get-ADUser -Identity $SID).SamAccountName
            $groupecible = $Event.Properties[2].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $Domain     = $Event.Properties[3].Value
            $who = $Event.Properties[6].Value
            $DomainWho = $Event.Properties[7].Value

            $obj = new-object psobject -Property @{
            Date = $Time
            Utilisateur = $UserName 
            Domaine = $Domain 
            Action = "Fait maintenant parti du groupe : "
            Cible = $groupecible
            "Par qui" = $DomainWho+ "\" + $who
            }
            if ($groupecible -eq "Admins du domaine")
            {
            Write-Host $obj -ForegroundColor Red
            $Table += $obj
            }
            else
            {
            $Table += $obj
            }
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>

<h1>Rapport des modifications de groupe:</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date -Descending | ConvertTo-Html -Head $Header -Property Date,Domaine,Utilisateur,Action,Cible,"Par qui" | foreach {
    $PSItem -replace "<td>Admins du domaine</td>", "<td style='background-color:#FF8080'>Admins du domaine</td>"
}| Add-Content -Path $file

}

function change_status_disable {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=4725;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{
           
            $Objet = $Event.Properties[0].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $Domain     = $Event.Properties[1].Value
            $DomainWho = $Event.Properties[5].Value
            $who = $Event.Properties[4].Value


            $obj = new-object psobject -Property @{
            Date = $Time
            Objet = $Objet 
            Domaine = $Domain 
            Action = "a été désactivé par :"
            "Par qui" = $DomainWho+ "\" + $who
            }
            $Table += $obj
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>
<h1>Comptes désactivés :</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #E73F1C;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date -Descending | ConvertTo-Html -Property Date,Domaine,Objet,Action,"Par qui" -Head $Header | Add-Content -Path $file

}

function change_status_enabled {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=4722;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{
            $UserName = $Event.Properties[0].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $Domain     = $Event.Properties[1].Value
            $DomainWho = $Event.Properties[5].Value
            $who = $Event.Properties[4].Value


            $obj = new-object psobject -Property @{
            Date = $Time
            Utilisateur = $UserName 
            Domaine = $Domain 
            Action = "a été activé par :"
            "Par qui" = $DomainWho+ "\" + $who
            }
            $Table += $obj
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>
<h1>Comptes activés / re-activés :</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #9AEE11;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date -Descending | ConvertTo-Html -Property Date,Domaine,Utilisateur,Action,"Par qui" -Head $Header | Add-Content -Path $file

}

function change_supress {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=5141;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{
           
            $UserName = $Event.Properties[3].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $DomainWho     = $Event.Properties[4].Value
            $TypeObjet = $Event.Properties[10].Value
            $Objet = $Event.Properties[8].Value
            $who = $UserName


            $obj = new-object psobject -Property @{
            Date = $Time
            Action = "Supprimé :"
            Type = $TypeObjet
            Objet = $Objet
            Domaine = $Domain 
            "Par qui" = $DomainWho+ "\" + $who
            }
            $Table += $obj
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>
<h1>Objets Supprimés :</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #E4EE11;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date -Descending | ConvertTo-Html -Property Date,Action,Type,Objet,"Par qui" -Head $Header | Add-Content -Path $file

}

function change_status_locked {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=4740;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{
           
            
            $UserName = $Event.Properties[0].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $DomainWho     = $Event.Properties[5].Value 
            $Objet = $Event.Properties[1].Value
            $who = $UserName


            $obj = new-object psobject -Property @{
            Date = $Time
            Action = "Verrouillé"
            Domaine = $Domain 
            Compte = $UserName
            Workstation = $DomainWho+ "\" + $Objet
            Cause = "5 Mauvais mot de passe"
            }
            If ((Get-ADUser -Identity $UserName -Properties *).badPwdCount -eq 5) {
            $Table += $obj
            }
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>
<h1>Objets Verrouillés :</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #E4EE11;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date -Descending | ConvertTo-Html -Property Date,Action,Domain,Compte,Workstation,Cause -Head $Header | Add-Content -Path $file
}

function change_GPO {
$starttime = (get-date).adddays(-1)
$Events = Get-WinEvent -FilterHashTable @{Logname='Security';ID=5136;starttime=$starttime}
$file = "C:\administration\AD_reports\rapport.html"
[Array]$Table = $null

foreach($Event in $Events)
{  
            $UserName = $Event.Properties[3].Value
            $Time       = ($Event.TimeCreated).ToString($G)
            $DomainWho     = $Event.Properties[4].Value
            $TypeObject = $Event.Properties[10].Value
            $AttributeLDAPDisplayName = $Event.Properties[11].Value

            If ($TypeObject -eq "groupPolicyContainer" -and $AttributeLDAPDisplayName -eq "versionNumber") {
            $ObjetDN = $Event.Properties[8].Value
            $ObjetGUID = $ObjetDN -replace"(CN={)(.*?)},.*",'$2'
            $GPO = (Get-GPO -Guid $ObjetGUID -ErrorAction SilentlyContinue).DisplayName 

            $obj = new-object psobject -Property @{
            Date = $Time
            Action = "Modification"
            GPO = $GPO
            Qui = $DomainWho+ "\" + $UserName
            }
            }
            $Table += $obj
            {
            write-host "NA"
            }
            
}

$html_start = @"
<!DOCTYPE html>
<html>
<body>
<h1>GPO Modifiées : :</h1>
"@

Add-Content -Path $file -Value $html_start

$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #E4EE11;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@

$Table | sort Date,GPO -Unique -Descending | ConvertTo-Html -Property Date,Action,GPO,Qui -Head $Header | Add-Content -Path $file
}

function mail {
$file = "C:\administration\AD_reports\rapport.html"
#Envoi par Email
$smtpServer = "serveur SMTP" 
$MailFrom = "email expéditeur" 
$mailto = "email destinataire", "email destinataire" 
$msg = new-object Net.Mail.MailMessage  
$smtp = new-object Net.Mail.SmtpClient($smtpServer)  
$msg.From = $MailFrom 
$msg.IsBodyHTML = $true 
$msg.To.Add($Mailto)  
$msg.Subject = "Rapport des Modifications Active Directory"
$MailTextT =  Get-Content -Path $file
$msg.Body = $MailTextT 
$smtp.Send($msg) 
Remove-Item -Path $file
}

change_groupe
change_status_disable
change_status_enabled
change_supress
change_status_locked
change_GPO
mail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *