SCRIPT POWERSHELL RAPPORT GPO
Dans le cadre de la refonte et de l’audite des GPO chez un client, j’ai créé un script PowerShell dans le but de faire une remonter avec rapport html sur toutes les GPO’s du domaine puis envoie de celui-ci dans le corps du mail.
Voici les caractéristiques du script :
- Un script qui fait apparaitre toutes les GPO’s du domaine avec leur liaisons sur les Site, Domain et Ou
- Les GPO’s modifier de moins de 7 jours doivent apparaitre en rouge
- Rapport GPO sous forme de tableau et envoyer par mail
- Copie du rapport GPO dans un répertoire du serveur (suppression automatique des rapports de plus de 30 jours
Tout d’abord il mettre un titre au script, il faut savoir que dans un script PowerShell tout ligne commençant par # veut dire que c’est un commentaire, PowerShell n’exécute pas ce qui suit mais cela est intéressant du point de vue afficher un commentaire
#/////////////////////////////////////////////////////////////////////////////
#//
#// Titre: GPO-Report.ps1
#// Auteur: OUASTI Khatir
#// Version: 1.0
#//
#/////////////////////////////////////////////////////////////////////////////
L’importation des modules suivant est important car il permet d’exécuter le script sans blocage (niveau droit d’exécuter le script) Et surtout charge les modules active directory et grouppolicy qui vont permettent l’exécution des commandes liés à l’AD ou au GPO
############import des modules AD et grouppolicy##########
Set-ExecutionPolicy -ExecutionPolicy Bypass
Import-Module activedirectory
Import-Module grouppolicy
Ci-dessous La construction du tableau HTML a été choisi du fait quel permet d’être intégré au corps du mail à savoir que certaines dates apparaissent en rouge c’est la solution la mieux adapter. (L’autre solution corps du mail avec fichier texte pas de couleur pas adapté).
#######construction du style et du tableau html##############
$style = @'
<style>
H3 {text-align: center;background-color: lightgreen;}
BODY{background-color:lightblue;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:thistle}
TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black}
</style>
'@
###les variables dates ci-dessous sont associés au nom du rapport #####
$datereport = (get-date).AddDays(0).ToString("dd-MM-yyyy")
$thedate = (get-date).AddDays(0).ToString('dd/MM/yyyy HH:mm:ss')
$resultdate = (get-date).AddDays(-7)
La commande ci-dessous permet d’afficher toutes les GPO du domaine, sort-Object permet de classer la colonne modification par ordre de date la plus récente, select-Object affiche les colonnes que l’on a choisi.
####Extraction de l'information concernant toutes les GPO’s #####
$GPO = Get-GPO -all | Sort-Object -descending modificationtime | Select-Object displayname, id, owner, creationtime ,modificationtime
La commande ci-dessous permet d’afficher les noms des SITES, DOMAINES ou Unités Organisationnelles auxquelles sont liées des GPO’s, il est clair que pour faire apparaitre les liaisons des GPO’s celle-ci n’est pas contenu dans la commande GET-GPO, il fallut extraire l’information à partir de la commande GET-GPOREPORT.
##########Extraction de l'information en fonction du nom de la GPO lié à une ou plusieurs OU######################
$GPOReport = Get-GPOReport -all -ReportType xml | % {
([Xml]$_).gpo | select name,@{n="SOMName";e={$_.LinksTo | % {$_.SOMName}}},@{n="SOMPath";e={$_.LinksTo | %{$_.SOMPath}}}}
Les variables $body nous permet la construction des colonnes du tableau HTML et aussi des titres du rapport.
#############construction des colonnes du tableau html#############
$Body = "<h3>Rapport GPO journalier: $thedate</h3><br><table><tr><th>DISPLAYNAME</th><th>ID</th><th>OWNER</th><th>CREATIONTIME</th><th>MODIFICATIONTIME</th><th>LINK-OU-SITE-DOMAIN</th></tr>"
La construction de la boucle va permettre d’aller chercher chaque valeur date de la colonne modificationtime si la GPO a été modifié il y’a moins de 7 jours la date apparaitra en fond rouge sur écriture blanc.
###########construction de la boucle pour l'application de la couleur rouge pour la colonne modificationtime#######
Foreach($GPOALLDOMAIN in $GPO) {
$displayname = $GPOALLDOMAIN.displayname
$ID = $GPOALLDOMAIN.id
$owner = $GPOALLDOMAIN.owner
$creationtime = $GPOALLDOMAIN.creationtime
$modificationtime = $GPOALLDOMAIN.modificationtime
$Body += "<tr><td>$displayname</td><td>$ID</td><td>$owner</td><td>$creationtime</td>"
######Application changement de couleur Rouge sur chaque cellule de la colonne modificationtime si une valeur date est supérieure à $resultdate################
If ($GPOALLDOMAIN.modificationtime -gt $resultdate) {
$Body += "<td bgcolor=`"`#FF0000`"><font color=`"`#FFFFFF`">$modificationtime</font></td>"
La partie du script ci-dessous permet de joindre au tableau HTML, les valeurs obtenu par les commandes GET-GPOReport et GET-GPO.
##Application d'aucune changement sur la colonne modificationtime #####
} else {
$Body += "<td>$modificationtime</td>"
}
$Result = $GPOReport | Where-Object {$_.name -eq $displayname}
$ResultString = $Result.SOMPath -join ";"
#######comparaison entre le nom de la gpo de la commande get-gpo et get-GPOreport et ajoute le résultat $resultstring à la colonne "link" ##########
if ($ResultString -eq "") {$Body += "<td align=center bgcolor=`"`#CCFF00`">NO-LINK</td>"}
$Body += "<td>$ResultString</td>"
$Body += "</tr>"
}
#############fin de la boucle du tableau html################
$Body += "</table>"
##############Conversion du tableau en html###################
ConvertTo-HTML -head $style -body $Body | set-content "D:\Scripts\GPO-RAPPORT\LOGS\ReportGPO-$datereport.htm"
Bien évidemment, il faut penser à effectuer un nettoyage automatique des rapports qui ont plus d’un mois.
##########suppressions des fichiers de plus de 30 jours #############
dir \\serveur1\d$\Scripts\GPO-RAPPORT\LOGS -recurse | where { ((get-date)-$_.lastwritetime).days -gt 30 } | Remove-Item –Force
L’envoie du rapport dans le corps du message, je l’ai effectué en version 1.0 pour plus de clarté.
###########information d'identification pour l'envoie du message et Rapport HTML intégrer au corps du message adapter pour PowerShell v1.0########
$fromaddress = "email de l'expéditeur"
$toaddress = "email du 1er destinataire"
$bccaddress = "email du 2 eme destinataire"
$CCaddress = "email du 3 eme destinataire"
$Subject = "Envoie Rapport GPO journalier (Copie dans \\serveur1\Scripts\GPO-RAPPORT\LOGS)"
$body = get-content "D:\Scripts\GPO-RAPPORT\LOGS\ReportGPO-$datereport.htm"
#$Attachment = "D:\Scripts\GPO-RAPPORT\test.txt" (non utilisé pour mon script mais pourrais servir pour joindre un fichier au mail)
$smtpserver = "smtp.domaine.com"
##########information d'authentification pour l'envoie du message##########################
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.CC.Add($CCaddress)
$message.Bcc.Add($bccaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
# création du nouvel objet Net.Mail.Attachment($attachment) permettant #d'attacher le fichier en question.
#$attach = new-object Net.Mail.Attachment($attachment)
#$message.Attachments.Add($attach)
$message.body = $body
$CredUser = "user1"
$CredPassword = "Password"
$smtp = new-object Net.Mail.SmtpClient($smtpserver, 25)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential($CredUser, $CredPassword);
$smtp.Send($message)
#######################################################
SCRIPT COMPLET
#/////////////////////////////////////////////////////////////////////////////
#//
#// Titre: GPO-Report.ps1
#// Auteur: OUASTI Khatir
#// Version: 1.0
#//
#/////////////////////////////////////////////////////////////////////////////
#####import des modules AD et grouppolicy########################
Set-ExecutionPolicy -ExecutionPolicy Bypass
Import-Module activedirectory
Import-Module grouppolicy
###############construction du style et du tableau html##############
$style = @'
<style>
H3 {text-align: center;background-color: lightgreen;}
BODY{background-color:lightblue;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:thistle}
TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black}
</style>
'@
$datereport = (get-date).AddDays(0).ToString("dd-MM-yyyy")
$thedate = (get-date).AddDays(0).ToString('dd/MM/yyyy HH:mm:ss')
$resultdate = (get-date).AddDays(-7)
###Extraction de l'information concernant tout les GPO du domaine ####
$GPO = Get-GPO -all | Sort-Object -descending modificationtime | Select-Object displayname, id, owner, creationtime ,modificationtime
###Extraction de l'information en fonction du nom de la GPO lié à une ou plusieurs OU #####################
$GPOReport = Get-GPOReport -all -ReportType xml | % {
([xml]$_).gpo | select name,@{n="SOMName";e={$_.LinksTo | % {$_.SOMName}}},@{n="SOMPath";e={$_.LinksTo | %{$_.SOMPath}}}}
#######construction du style et du tableau html################
$Body = "<h3>Rapport GPO journalier: $thedate</h3><br><table><tr><th>DISPLAYNAME</th><th>ID</th><th>OWNER</th><th>CREATIONTIME</th><th>MODIFICATIONTIME</th><th>LINK-OU-SITE-DOMAIN</th></tr>"
########construction de la boucle pour l'application de la couleur rouge pour la colonne modificationtime##############################
Foreach($GPOALLDOMAIN in $GPO) {
$displayname = $GPOALLDOMAIN.displayname
$ID = $GPOALLDOMAIN.id
$owner = $GPOALLDOMAIN.owner
$creationtime = $GPOALLDOMAIN.creationtime
$modificationtime = $GPOALLDOMAIN.modificationtime
$Body += "<tr><td>$displayname</td><td>$ID</td><td>$owner</td><td>$creationtime</td>"
##########Application changement de couleur Rouge sur chaque cellule de la colonne modificationtime si une valeur date est supérieure à $resultdate################
if ($GPOALLDOMAIN.modificationtime -gt $resultdate) {
$Body += "<td bgcolor=`"`#FF0000`"><font color=`"`#FFFFFF`">$modificationtime</font></td>"
##########Application d'aucune changement sur la colonne modificationtime #########################################
}else {
$Body += "<td>$modificationtime</td>"
}
$Result = $GPOReport | Where-Object {$_.name -eq $displayname}
$ResultString = $Result.SOMPath -join ";"
##########comparaison entre le nom de la gpo de la commande get-gpo et get-GPOreport et ajoute le résultat $resultstring à la colonne "link" ################
if ($ResultString -eq "") {$Body += "<td align=center bgcolor=`"`#CCFF00`">NO-LINK</td>"}
$Body += "<td>$ResultString</td>"
$Body += "</tr>"
}
########fin de la boucle du tableau html##################
$Body += "</table>"
#########Conversion du tableau en html#####################
ConvertTo-HTML -head $style -body $Body | set-content "D:\Scripts\GPO-RAPPORT\LOGS\ReportGPO-$datereport.htm"
##########suppressions des fichiers de plus de 30 jours #############
dir \\serveur1\d$\Scripts\GPO-RAPPORT\LOGS -recurse | where { ((get-date)-$_.lastwritetime).days -gt 30 } | Remove-Item -Force
###########information d'identification pour l'envoie du message et Rapport HTML intégrer au corps des messages adapter pour powershell v1.0########
$fromaddress = "email de l'expéditeur"
$toaddress = "email du 1er destinataire"
$bccaddress = "email du 2 eme destinataire"
$CCaddress = "email du 3 eme destinataire"
$Subject = "Envoie Rapport GPO journalier (Copie dans \\serveur1\Scripts\GPO-RAPPORT\LOGS)"
$body = get-content "D:\Scripts\GPO-RAPPORT\LOGS\ReportGPO-$datereport.htm"
#$Attachment = "D:\Scripts\GPO-RAPPORT\test.txt" (non utilisé pour mon script mais pourrais servir pour joindre un fichier au mail)
$smtpserver = "smtp.domaine.com"
##information d'authentification pour l'envoie du message########
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.CC.Add($CCaddress)
$message.Bcc.Add($bccaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
# création du nouvel objet Net.Mail.Attachment($attachment) permettant d'attacher le fichier en question.
#$attach = new-object Net.Mail.Attachment($attachment)
#$message.Attachments.Add($attach)
$message.body = $body
$CredUser = "user1"
$CredPassword = "Password"
$smtp = new-object Net.Mail.SmtpClient($smtpserver, 25)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential($CredUser, $CredPassword);
$smtp.Send($message)
#################################################################################