PI Services

Le blog des collaborateurs de PI Services

Powershell: Gestion d’erreur sur une commande NON CMDLETS

 

PERIMETRE: Tâches planifiés qui permette la réplication de fichier d’un serveur vers un autre chez un de nos client.

FONCTIONNEMENT: Les tâches planifiées lancent des scripts PowerShell, la commande utilisé est la commande ROBOCOPY

Dans le cadre de la gestion des erreurs des commandes dites NON CMDLETS qui sont propre à powershell, la gestion des erreurs est différente.

 

SCRIPT D’ORIGNE:

#Listes des serveurs destinations +chemin
$Srvdestination = "\\orches1\tachep"
$srvdest1 = $Srvdestination.split("\")  
$srvdest = $srvdest1[2]

#Fichier Log avec nom du serveur.log
$Filelog = "$srvdest.log"

#repertoire de LOGS pour la derniere ligne du script powershell
$Folderlogs = "\\orches2\TACHEcollection2"

# Rapport Log Robocopy
$LOGS1 = "$Folderlogs"+"\"+"$Filelog"

#Option logs + chemin du rapport log
$LOGS = "/log:"+"$LOGS1"


#Liste de(s) fichier(s) à copier
$File = "*.*"

#Listes du dossier sources Réplication
$SourceFolder = "\\orches2\tachep2"

#Options de la commande robocopy
$optionstrings = "/XX,/E,/Z,/R:1,/W:2,/MT:64,/TEE"
$options = $optionstrings.split(",")

 

#Copie du fichier source vidéo vers le serveur de destination
$Robocopy = Robocopy $sourcefolder $srvdestination $file $options $logs

$LASTEXITCODE

Il faut savoir que dans la variable $Robocopy vous avez l’affichage du Log robocopy + la création du log $logs  grâce à l’option /TEE qui permet 2 sorties

Nous avons le log Robocopy sous cette forme :

-----------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows                             
-------------------------------------------------------------------------------

  Started : dimanche 8 mars 2015 16:40:16
   Source : \\orches2\tachep2\
   Dest : \\orches1\tachep\

    Files : *.*       


  Options : *.* /TEE /S /E /DCOPY:DA /COPY:DAT /Z /XX /MT:64 /R:1 /W:2

------------------------------------------------------------------------------

        New File          246.3 m    \\orches2\tachep2\tache.zip
  ------------------------------------------------------------------------------

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         1                0         0         0         0
   Files :         1         1         0         0         0         0
   Bytes :  246.36 m  246.36 m         0         0         0         0
   Times :   0:00:59   0:00:14                       0:00:00   0:00:14
   Ended : dimanche 8 mars 2015 16:40:45

Nous voyons clairement que le log robocopy affiche le résultat de la copie Ok, mais lorsque la copie est un fichier ou répertoire identique  ou qu’il y’a des options au niveau du robocopy à ajouter ou modifier cela devient compliquer à gérer, de plus si nous voulons afficher une sortie simplifié du style Error ou Success en plus du log robocopy, il faudrait connaitre tout les retours sur ce qui est considérer comme Error ou Success , Sans oublier l’erreur de syntaxe de la commande robocopy qui n'apparait pas.

solution se baser sur  $LASTEXITCODE par contre le code de sortie de 0 à 16 cela ne nous dis pas si c’est une Erreur ou un Succès du déroulement de la copie

Voici le 2ème Script avec la gestion des erreurs qui inclura aussi l’erreur de syntaxe de la commande avec l’utilisation de TRY et CATCH. et le SWITCH pour les sorties $LASTEXITCODE.

2EME SCRIPT (le début et identique):

Pour info: Robocopy $LASTEXITCODE. :

- De 0 à 7 : Succès

- De 8 à 16 : Erreur

#Copie du fichier source vidéo vers le serveur de destination
$RoboSyntaxe = try {

      Robocopy $sourcefolder $srvdestination $file $options $logs | Out-Null

          Switch ($LASTEXITCODE
{   
"16" {$RobocopyJob = "Error Robocopy : Serious error. Robocopy did not copy any files. $srvdestination" }
"15" {$RobocopyJob = "Error Robocopy :OKCOPY + FAIL + MISMATCHES + XTRA. $srvdestination" }
"14" {$RobocopyJob = "Error Robocopy : FAIL + MISMATCHES + XTRA . $srvdestination" }
"13" {$RobocopyJob = "Error Robocopy :OKCOPY + FAIL + MISMATCHES. $srvdestination" }
"12" {$RobocopyJob = "Error Robocopy : FAIL + MISMATCHES. $srvdestination" }
"11" {$RobocopyJob = "Error Robocopy : OKCOPY + FAIL + XTRA. $srvdestination" }
"10" {$RobocopyJob = "Error Robocopy : FAIL + XTRA . $srvdestination" }
"9" {$RobocopyJob = "Error Robocopy : OKCOPY + FAIL. $srvdestination" }
"8" {$RobocopyJob = "Error Robocopy: Some files or directories could not be copied $srvdestination" }
"7" {$RobocopyJob = "Success Robocopy : Files were copied, a file mismatch was present, and additional files were present $srvdestination"}
"6" {$RobocopyJob = "Success Robocopy : Additional files and mismatched files exist, No files were copied $srvdestination" }
"5" {$RobocopyJob = "Success Robocopy : Some files were copied. Some files were mismatched $srvdestination"}
"4" {$RobocopyJob = "Success Robocopy : Some Mismatched files or directories were detected $srvdestination" }
"3" {$RobocopyJob = "Success Robocopy : Some files were copied. Additional files were present $srvdestination" }
"2" {$RobocopyJob = "Success Robocopy : Some Extra files or directories were detected $srvdestination "}
"1" {$RobocopyJob = "Success Robocopy : One or more files were copied successfully $srvdestination"}
"0" {$RobocopyJob = "Success Robocopy : No Change files successfully $srvdestination"}     
}
                           
    }catch{
          "Error : syntaxe command robocopy"
          } 
 

Dans ce script nous avons 2 types de sortie d’erreur :

- La 1ère s’effectue à l’aide du Try et catch, si on enleve le Y de ROBOCOPY on obtient :

image

image

- La 2ème s’effectue à l’aide du switch sur la variable $LASTEXITCODE mais commenter avec le chemin de destination et la variable qui permet d’afficher le résultat est $RobocopyJob :

image

image

Nous pouvons envoyer ses informations dans les journaux d’évènement dans un journal personnaliser APPLIMETIER par exemple plutôt que le log robocopy qui peut être trop long et pas pris en compte.

 

 

 

PowerShell : Création Rapport HTML basé sur 2 colonnes Serveurs et Nom de Ville

 

 

Cadre :

Dans le cadre actuel de l’amélioration des tâches planifiés chez un de nos client.

Périmètre :

Cette tâche devra être capable de tester les chemins de tous les serveurs en France et d'afficher un résultat sous forme de tableau HTML qui affichera uniquement les noms de villes.

Voici le script en tache planifié qui va permettre plus de clarté au niveau des tests des serveurs avec les noms des villes associé

# Date de Début de réplication
$DateStart = (get-date).ToString("dd/MM/yyyy : HH'H'mm")


# Log Robocopy + Loghtml contenant les noms de villes
$Loghtml ="C:\test\test.html"


# Listes des serveurs et de leurs situation géographique en l'occurrence nom de la ville
$LISTSRVCITY = @("SRV01","PARIS"),
("SRV02","LYON"),
("SRV03","MONTPELLIER"),
("SRV03","MARSEILLE"),
("SRV04","BORDEAUX"),
("SRV05","RENNES"),
("SRV06","LILLE"),
("KHOUA-DL-01","CREIL")

# Nombre de colonnes en relation avec la variable $LISTSRVCITY pour la première serveur et nom de villes pour l'autre
$Nbcolonne = "2"

# Tableau remplacant un fichier CSV en avec un bouclage sur la variable $LISTSRVCITY
# En mettant les serveurs dans la colonne LISTSRV et les nom de ville dans $LISTCITY
# c'est la variable $FileLineSRVCITY qui contiendra le tableau en question

$FileLineSRVCITY = @()
$rang = @("LISTSRV","LISTCITY")
Foreach ($LineSRVCITY in $LISTSRVCITY) {
 $MyObject = New-Object -TypeName PSObject
For ($i=0;$i -lt $Nbcolonne; $i++)

  {$MyObject | Add-Member -Type NoteProperty -Name $rang[$i] -Value $LineSRVCITY[$i]
  }
$FileLineSRVCITY += $MyObject
}

## La variable $style permet la construction de la page html avec cadres et couleurs
$style = @'
<style =type="text/css">
H1 {text-align: center;background-color: lightblue;}
H2 {text-align: center;background-color: yellow;}
BODY{background-color:PaleGoldenRod;}
TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH{border-width: 1px;padding: 2px;border-style: solid;text-align: center;border-color: black;background-color:thistle}
TD{border-width: 1px;padding: 0px;border-style: solid;text-align: center;border-color: black"
</style>
'@

 


# La variable $Body permet la construction des titres et cadre supplémentaire dans le corps html

$Body = "<H1>Revue De Presse BI</H1><H2>Début de TEST : $DateStart</H2><br><center><table><tr><th><H3>Revue De Presse BI</H3></th></tr>"

# Il faut une seconde boucle pour insérer chaque ligne du tableau $FileLineSRVCITY avec condition vu ci-dessous

foreach ($LISTglobal in $FileLineSRVCITY) {

#Représente la liste des serveurs
$PATHSRV = $LISTglobal.listsrv

#Représente la liste des villes
$PATHCITY = $LISTglobal.listcity

# Test le chemin complet de tout les serveurs dans notre cas hormis le nom du serveur la fin du chemin \Users\kouasti\Downloads
# est identique pour tous les serveurs

$TESTPATHSRV= Test-Path \\$pathsrv\Users\kouasti\Downloads

# Condition si le chemin existe avec les droits de lecture au minimum alors le Nom de la ville apparait avec le fond de la cellule VERT et texte NOIR
# Sinon le Nom de la ville apparait avec le fond de la cellule ROUGE et texte BLANC

if ($TESTPATHSRV -eq "true")

{
$Body += "<td bgcolor=`"`GREEN`"><font color=`"`FFFFFF`">$PATHCITY</font></td>"
}
else
{
$Body += "<td bgcolor=`"`RED`"><font color=`"`white`">$PATHCITY</font></td>"
}

$Body +=  "</tr>"

}

# Fin de construction du corp html
$Body += "</table>"

# Date de Fin de réplication
$DateEnd = (get-date).ToString("dd/MM/yyyy : HH'H'mm")
$Body += "<H2>Fin de TEST : $DateEnd</H2>"
$Body += "</center>"

# Conversion du tableau complet avec les variables $style et $body en sortir fichier HTML

ConvertTo-HTML -head $style -body $Body | set-content "$Loghtml"

 

Voici le résultat en ouvrant le fichier TEST.HTML:

En Rouge: TEST échoué

En Vert: TEST réussi

image

Powershell / Active directory: Traduire le SID <=>l’utilisateur

 

CADRE:

Cet article vise un public débutant en powershell ne connaissant pas bien l’utilisation des classes objets avec powershell.

INTRODUCTION:

Dans cet article nous allons expliquer comment Traduire le SID lié à un utilisateur active directory ou local ou encore l’inverse.

Il faut savoir que Powershell est fondé sur la programmation objet.

Nous avons besoin d’installer aussi Net Framework 4.5, pour avoir les classes d’objets suivant sous powershell: 

1- System.Security.Principal.SecurityIdentifier (SID)

2- System.Security.Principal.NTAccount (compte NT)

SCRIPT:

Traduire le l’utilisateur en SID:

1-  Création de l’objet de la classe System.Security.Principal.NTAccount qui permet de représenter un utilisateur ou un groupe dans une variable $objUser .

$objUser = New-Object System.Security.Principal.NTAccount("administrator")

2-  Traduction de l’objet de la classe System.Security.Principal.NTAccount qui représente un utilisateur ou un groupe en classe System.Security.Principal.SecurityIdentifier qui représente le SID à savoir que .translate() après le $objUser est la méthode qui permet la traduction mais c’est la classe de l’objet contenue dans () sur lequel s’appuie la traduction (en quoi on veut le traduire) sans cela aucune traduction n’est possible .

$strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])

2-  Traduction de l’objet étant effectué et mise dans une variable $strSID nous avons plus qu’à regarder la valeur de la variable en tapant .value après $strSID

$strSID .Value

affiche: S-1-5-21-29

Traduire le SID en Nom d’utilisateur:

Nous avons vu comment traduire l’utilisateur en SID l’inverse est tout simplement d’inverser les classes d’objets avec les noms des variables correspondant.

$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-32-546")

$objUser = $objSID.Translate([System.Security.Principal.NTAccount])

$objUser.Value

affiche: BUILTIN\Invités

Erreur Scecli 1202

Il faut savoir que l’erreur Scecli 1202 est une erreur qui apparait dans le journal d’évènement au niveau des contrôleurs de domaine, plusieurs KB Microsoft donne des solutions qui ne sont pas compréhensible voir ci-dessous, il faut faire un regroupement d’informations :

# Erreur Scecli 1202: appliquer la KB Microsoft: http://support.microsoft.com/kb/324383/fr ou encore http://support.microsoft.com/kb/2000705

Tout d'abord sous cmd Taper RSOP (cela permet de voir les conflits niveau application des GPO qui apparait au niveau des contrôleur de domaine  PO)

Pour faire simple:
Erreur Scecli 1202 code erreur 0x534 se rapporte soit à un compte ajouter qui n'existe pas ou qui a été supprimer,
soit à une mauvaise traduction des SID en Nom GPO

Ensuite j'ai regardé le fichier c:\windows\security\logs\winlogon.log puis info (Error assigning SeSystemtimePrivilege)


J'ai relevé l'id 6AC1786C-016F-11D2-945F-00C04fB984F9 du fichier winlogon.log

sous powershell :

get-gpo -guid 6AC1786C-016F-11D2-945F-00C04fB984F9 (cela correspond à Default Domain Controllers Policy)

donc une erreur au niveau de la gpo qui s'applique sur les DC (donc configuration des ordinateurs)

puis regarder l'erreur niveau RSOP(lecture seule) computer configuration => windows setting => Local policies =>
user Rights assignment=> Acess this computer from network
puis clique droit =>properties et vu que le compte administrator n'existait pas, je l'ai supprimé sous GPMC

et gpupdate/force sous CMD et RSOP et l'erreur est corrigé.

powershell rapport-gpo

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)

#################################################################################

EXCHANGE 2013 DAG

INSTALLATION DU DAG (DATA AVAIBILITY GROUP)

Tout d’abord il faut connaitre le rôle du DAG, son but est tout simplement la haute disponibilité des BASES MAIL.

petit rappel sur les bases mail, c’est une base de donnée qui contient  les boites aux lettres (BAL) des utilisateurs de messagerie exchange et dont la limite est de 2 TB.

Tout d’abord il faut renommer les bases mail pour plus de clarté prévoir une convention de nommage

1) renommer les bases de données (avec convention de nommage simple)

image

2) création d’un compte ordinateur que l’on désactive et attribue les droits

image

Full control, celui va servir pour le DAG

3) Le serveur File Server Witness (FSW01) joue le rôle de QORUM

Il doit être ajouter au groupe (Exchange Trusted Subsystem ) dans Active Directory puis le groupe Exchange Trusted Subsystem ajouter au groupe local administrator du serveur FSW01.

Le FSW doit être créé car si le cluster passe de serveur impair à pair

On n’aura toujours 1 votant supplémentaire.

Installer la fonctionnalité du serveur de fichier

image

Puis ouvrir niveau pare-feu avancé et paramétrer

image

4) créer un groupe de disponibilité,

Figure 1

image

Figure 2

image

Figure 3 : mettre une ip pour le DAG 192.168.1.10 sur le réseau MAPIDAGNetwork

image

5) parametrer le réseau dedié au DAG01, dans notre cas

Figurer 1

image

Figure 2 : décocher register this connection’s adresses in DNS.

image

Pour regarder les configuration du DAG sur EXCH01 et EXCH02 taper la commande suivante sous Exchange management shell:

image

Voici les résultats :

EXCH01

image

EXCH02

image

6) Par defaut les reseaux mapidagnetwork et ReplicationDAG Network

Se configurer en auto avec la carte reseau en prod et l’autre pour REPLICA avec aucune passerelle activé et décocher registrer this connection in DNS, il fait la différence et les bascule automatiquement.

Pour modifier manuellement les configuration du DAG sur EXCH01 et EXCH02 faire comme ci-dessous.

Figure1 : cocher configurer manuellement les réseaux.

image

Figure 2 : soit désactiver la réplication soit afficher les détail pour modifier la configuration.

image

7) Creation de la copie passive sur les 2 serveurs EXCHANGE :

- Copie des Bases mail De EXCH01 vers EXCH02 et EXCH02 vers EXCH01

image

Figure1 : voir ci-dessous

image

Figure2 : ajouter le serveur EXCH02 puis cliquer ENREGISTRER

image

Taper la commande suivante pour fixer la configuration :

Set-DatabaseAvailabilityGroup DAG01 -ManualDagNetworkConfiguration $false

Tester le réplication avec le commande let : Test-ReplicationHealth

Ou Test-ReplicationHealth | fl

Vérification de la copie de base de données avec PowerShell:

EXCH01

image

EXCH02

image

8) Test de la bascule de la base de données

Vérification de l’utilisateur créé (kouasti) sur quelle base ? :

image

Eteindre le serveur EXCH01 sur lequel la base MBX-DAG01-DB01 est actif

Cela prend quelques secondes.

9) Test de la bascule de la base de données en mode maintenance

Effectuer ses manipulations sur le serveur ou les bases sont actives

MBX-DAG01-DB01

MBX-DAG01-DB02

Aller dans C:\Program Files\Microsoft\Exchange Server\V15\Scripts puis

Taper :

[PS] C:\Program Files\Microsoft\Exchange Server\V15\Scripts>.\StartDagServerMaintenance.ps1 -servername exch02

image

 

RESULTAT

Sur Exch01 faire get-mailboxdatabasecopystatus

image

Sur Exch02 faire get-mailboxdatabasecopystatus

image

POUR REMETTRE EN PLACE il faut stopper la maintenance:

.\StopDagServerMaintenance.ps1 -servername exch02

 

J’espère que le blog vous a éclairé sur la mise en plce sdu DAG exchange 2013