Bonjour, et bonne année!

Un petit coup de mou sur le blog, mais rien d'inquiétant, juste que ces derniers temps ont été plutôt calmes en terme de création de scripts et que je n'ai pas vraiment eu à faire quoi que ce soit qui mérite de faire un article.

Mais c'est du passé, car j'ai ENFIN (merci les joies de l'auto-projet) quelque chose à mettre pour nourrir cet espace, et je dois avouer en être plutôt fier de ce morceau de code car il m'aura offert quelques beaux petits casse-tête pour faire fonctionner le tout.

Aujourd'hui, je vais vous présenter un script qui vous permettra de :

  1. Détecter les modifications faites sur les GPO
  2. Créer un versionning des dites-GPO afin de pouvoir restaurer en cas de problème
  3. Automatiser un export des paramétrages de GPO format HTML pour une lecture facile

Alors, la première question que je mettrai à cet article est :

POURQUOI?

La raison est simple. Chez mon client, nous sommes plusieurs personnes à nous occuper de l'informatique et nous avons donc bien souvent à effectuer telle ou telle opération sur les politiques de groupe, mais nous n'avons pas forcément l'information de ce qui a été changé. Cela peut poser des problèmes, puisqu'une personne peut écraser ou mettre en place des paramètres qui vont à l'encontre du fonctionnement d'une modification effectuée par un collègue, voir même causer des dysfonctionnements imprévus.

Il nous fallait donc un moyen de savoir et de suivre les changements effectués.

COMMENT?

L'idée initiale m'est venue en voyant les différents mails que nous recevions de notre wiki interne. A chaque modification sur une information, nous recevons un mail avec le changement surligné en vert et l'ancienne valeur barrée en rouge.

wiki

Ayant des GPO de plus en plus tentaculaires et complexes au fur et à mesure du temps, il m’apparaissait évident qu'avoir un suivi identique à celui du Wiki serait une bonne chose, car nous aurions visibilité sur ce qui existe, ce qui est modifié et ce qui est supprimé.

L'outil de base pour gérer les GPO me semblait tout trouvé (et les gens qui suivent un peu le blog ne seront pas étonnés) : Powershell ; mais l'outil pour faire le surlignage des modifications fut bien plus compliqué à trouver que prévu.

J'avais déjà en tête l'idée générale de fonctionnement du script :

  • Sauvegarder les GPOs pour extraire leur date de modification
  • Vérifier que leur date de modification était plus récente que leur dernière sauvegarde
  • Trouver les nouvelles GPOs et les GPOs supprimées
  • Comparer les deux fichiers pour ressortir les lignes non similaires ainsi qu'un contexte pour comprendre la différence (numéro de la ligne + X lignes avant et après)
  • Génerer un fichier récapitulatif des différences
  • Supprimer les backups sans différences
  • Envoyer un mail avec toutes les infos
  • ???
  • Profit

Le vrai point problématique était : Comment comparer les deux fichiers ?

Les mettre à plat et comparer chaque ligne aurait posé un problème, puisque les fichiers de GPO sont comme des fichiers xml et l'activation d'une valeur créera un nouveau bloc de balises qui ne sera pas dans le fichier précédent, et considérera donc tout le restant du fichier comme "différent". Comparer une valeur et la rechercher n'est pas possible non plus, puisque dans l'exemple de recherche d'une valeur "Disabled", il peut très bien y avoir 30 endroits avec cette même valeur.

Il me fallait donc passer par un outil tiers, car je ne tenais pas plus que ça à réinventer la roue.

Après avoir testé les outils intégrés dans Windows de comparaison de fichier (fc.exe), et constatant sa magnifique incapacité à fournir des références de lignes correctes à partir du moment où il y'a des lignes vides (et je peux vous assurer que j'ai cru pendant des heures que le problème venait de mon code, imaginez la frustration à comprendre que je n'étais en rien responsable!), je me suis orienté vers des outils disponibles sur le net.

Et l'ami Google m'aura orienté vers une DLL faite par Google, nommée DiffMatchPatch. Enfin... vers un fichier .cs (C#) à retransformer en .dll.

Et cette DLL fait exactement (ou presque) ce que je veux. Elle prend un fichier de référence, prend un fichier de comparaison, analyse le tout et recrache un fichier de différences. Parfait!

Et me voici donc, armé de mon fidèle ISE et de DiffMatchPatch.dll, prêt à analyser tout ce qui passe et à en découdre!

Et le résultat final ressemble à ça pour la partie "information":

diff1

diff2

Et il ressemble à ça pour la partie "sauvegarde" :

diff3

diff4

Le script a besoin pour fonctionner de :

  • Powershell V4 (il "doit" fonctionner sur la V3 mais je n'ai pas testé)
  • La DLL DiffMatchPatch
  • Le module ActiveDirectory pour Powershell
  • Avoir le répertoire $workspace crée au préalable
  • Une tâche planifiée pour exécuter tous les X heures / jours le script
  • Configurer les variables de début de script et le chemin vers la DLL DiffMatchPatch

Voici le fonctionnement complet :

  1. Ajout des différents modules / DLL (avec arrêt en cas d'erreur)
  2. Déplacement dans le workspace
  3. Renommage des dernières GPO analysées (les dernières en date se terminent par _new.xml)
  4. Vérification des GPO crées / supprimées
  5. Génération des fichiers HTML des GPO
  6. Génération des fichiers XML des GPO
  7. Sauvegarde des GPO non sauvegardées auparavant (car nouvelles)
  8. Lecture des fichiers XML récents et comparaison avec leur ancienne version
  9. Analyse des différences
  10. Génération d'un fichier de différence
  11. Backup de la nouvelle version de chaque GPO

On est partis pour présenter le code, attention c'est un poil plus long que d'habitude! Enjoy! :)

Vous pouvez télécharger le script sur mon espace git personnel.

###############################################
#region VARIABLES
#Emplacement où seront sauvegardés les fichiers
$workspace = "\\serveur\GPO_check"
#nom du fichier HTML qui sera envoyé par mail
$htmlfilename = "results.html"
#informations du serveur de messagerie et d'envoi de mail
$mailserver = "serveurmail.societe.fr"
$usessl = $false
$smtpport = 25
$from = "moi@societe.fr"
$to = "toi@societe.fr"
#Si besoin est : credentials utilisés pour la sauvegarde des fichiers HTML issus des GPO. N'oubliez pas de les sécuriser en mettant le tout dans un 
#fichier haché
$username = "user"
$password = "password"
#emplacement de sauvegarde des fichiers HTML
$backuplocation = "\\serveur\GPOS_HTML\"
#Encodage du texte. UTF8 est toujours un bon choix. Ou presque.
$encoding = "UTF8"
#Nom de fichier de réference pour les anciennes GPO. Inutile de le changer.
$gpolistfilename = "oldgpo.clixml"
#nombre de lignes récupérées avant et après chaque modification trouvée dans les GPO
$maxgathering = 5 

#endregion 

try
{
 #Ajout de la DLL diffmatchpatch qui comparera les fichiers XML des gpo
    Add-type -path '\\serveur\chemin\vers\DiffMatchPatch.dll' -ErrorAction Stop 

}
catch
{
    throw "Impossible d'ajouter la DLL diffmatchpatch"
    exit 10
}

#On récupère toutes les GPO. Si ça ne fonctionne pas, on bloque le script. (module manquant?)
try
{
    $gpos = get-gpo -All -ErrorAction Stop
}
catch
{
    throw "Impossible de récuperer les GPOS. Module AD manquant?!"
    exit 1
}

Set-Variable DebugPreference -Value continue
try
{
    Write-Debug "Déplacement du répertoire vers $workspace"
    Set-Location $workspace -ErrorAction Stop
}
catch
{
    Write-Output "Une erreur s'est produite lors de l'accès à $workspace. $($Error[0].exception.message)"
    Start-Sleep -Seconds 5
    exit 3
}

$date = get-date -Format "yyyyMMddHHmmss"
$errors = New-Object System.Collections.ArrayList
$infos = New-Object System.Collections.ArrayList

#Cette fonction est utilisée pour parser et mettre en forme les différences de l'outil fc.exe
function Highlight-Differences {
    param ($originalfile,$differences)

    Begin
    {
        $highlightarray = New-Object System.Collections.ArrayList
        try
        {
            Write-Debug "Récupération du contenu du fichier original"
            $old = Get-Content $originalfile -ErrorAction Stop
            Write-Debug "Récupération du contenu du fichier de différences"
            $new = Get-Content $differences -ErrorAction Stop
        }
        catch
        {
            Write-Debug "Erreur de lecture du fichier, fin du script"
            throw("Erreur lors de la lecture du fichier source")
            exit
        }

    }
    Process {
    # Creation d'un objet diffmatchpatch via la dll (générée depuis le fichier .cs)
    $diff = new-object DiffMatchPatch.diff_match_patch

    #création de l'objet de différences 
    $differences = $diff.diff_main($old,$new,$true)
    #nettoyage sémantique pour lecture plus aisée
    $diff.diff_cleanupSemantic($differences)
    #Création du fichier HTML qui sera parsé ensuite
    $textdiffs = $diff.diff_prettyHtml($differences).replace("> <",">`n<").split("`n")

    #parsing de l'ensemble du fichier et récupération des lignes comportant un élément ajouté par diff_match_patch
    $indexarray = New-Object System.Collections.ArrayList
    $temparray = New-Object System.Collections.ArrayList
    $gatheringtrigger = $false

    #décompte du numéro de ligne
 $index = 0 
    $textdiffs | % {
        if ($_ -like "*<del style=*" -or $_ -like "*<ins style=*" -or $_ -like "*</del>*" -or $_ -like "*</ins>*")
        {
            if ($index -notin $indexarray)
            {
                if (($index - $maxgathering) -lt 0)
                {
                    $start = 0
                }
                else
                {
                    $start = $index - $maxgathering
                }
                $end = $index + 1
                $count = 0
                do
                {
                   $count++
                   $end++
                   if ($textdiffs[$end] -like "*<del style=*" -or $textdiffs[$end] -like "*<ins style=*" -or $textdiffs[$end] -like "*</del>*" -or $textdiffs[$end] -like "*</ins>*")
                   {
                         $count = 0
                   }
                }
                until ($count -gt $maxgathering -or $end -eq $textdiffs.Length)
                for($start=$start;$start -le $end;$start++)
                {
                    $null = $indexarray.Add($start)
                    $null = $temparray.Add("$($start+$maxgathering) : $($textdiffs[$start])<br>")
                }
                $null = $temparray.Add("******************************************************<br>")
            }
        }
        $index++

    }

    return $temparray

    }

}

#On récupère tous les fichiers de GPO marqués _new.xml (faits lors de la dernière exécution du script) pour les renommer en date du jour
foreach ($item in (Get-ChildItem $workspace -Filter "*_new.xml"))
{
    try
    {
        Write-Debug "Renommage du fichier de $($item.name) vers $($item.name.replace("_new.xml","_$date.xml"))"
        Move-Item $item.Name ($item.Name.Replace("_new.xml","_$date.xml")) -ErrorAction Stop -Force
    }
    catch [System.Management.Automation.ItemNotFoundException]
    {
        $errors.Add([pscustomobject]@{
            "Fichier" = $item.Name
            "Type" = [System.Management.Automation.ItemNotFoundException].name
            "Action" = "Déplacement"
            "Erreur" = "Impossible de le renommer en date du jour, $($Error[0].exception.message)"
        })
    }
    catch
    {
            $errors.Add([pscustomobject]@{
                "Fichier" = $item.Name
                "Type" = [System.Management.Automation.ItemNotFoundException].name
                "Action" = "Déplacement"
                "Erreur" = "Impossible de le renommer en date du jour, $($Error[0].exception.message)"
        })
    }
}

$sendmail = $false
$checkoldgpos = $true
try
{
    Write-Debug "Import du fichier CLIXML de la liste des noms de gpo"
    $oldgpolist = Import-Clixml $gpolistfilename -ErrorAction Stop
}
catch
{
    $checkoldgpos = $false
}

if ($checkoldgpos -eq $true)
{
    #On vérifie les gpo crées ou disparues
    $gpochangelist = Compare-Object -ReferenceObject $oldgpolist.displayname -DifferenceObject $gpos.displayname
    foreach ($entry in $gpochangelist)
    {
        Write-Debug "Recherche de création ou suppression de $($entry.inputobject)"
        if ($entry.sideindicator -eq "=>")
        {
            Write-Debug "GPO $($entry.inputobject) crée"
            $infos.Add([pscustomobject]@{
                "GPO" = $entry.inputobject
                "Information" = "La GPO a été créée"
            }) | Out-Null
        }
        else
        {
            Write-Debug "GPO $($entry.inputobject) supprimée"
            $infos.Add([pscustomobject]@{
                "GPO" = $entry.inputobject
                "Information" = "La GPO a été supprimée"
            }) | Out-Null
        }
    }
}
Write-Debug "Export de la liste des GPO"
$gpos | Export-Clixml $gpolistfilename
Write-Debug "Filtrage de la liste des GPO qui ne se terminent pas par _new.xml et suppression de la date en fin de nom de fichier"
$gpolist = (Get-ChildItem -Filter "*.xml"  | Where-Object {$_.name -notlike  "*_new.xml"}).Name -Replace("_\d{$($date.Length)}.xml$","") | Sort-Object -Unique

foreach ($gpo in $gpos)
{
    Write-Debug "Création d'un rapport HTML pour $($gpo.displayname)"
    $gpo.GenerateReportToFile([Microsoft.GroupPolicy.ReportType]::Html, $(Join-Path $workspace "$($gpo.DisplayName).html"))
    if ($gpo.DisplayName+"_new.xml" -notin $errors.fichier)
    {
        try
        {
            Write-Debug "Création d'un rapport XML pour $($gpo.displayname) nommé $($gpo.displayname)_new.xml"
            $gpo.GenerateReportToFile([Microsoft.GroupPolicy.ReportType]::Xml, $(Join-Path $workspace "$($gpo.DisplayName)_new.xml"))

        }
        catch
        {
            Write-Debug "Erreur lors de l'export de la GPO"
            $errors.Add([pscustomobject]@{
                "Fichier" = $gpo.displayName
                "Type" = $Error[0].CategoryInfo.Reason
                "Action" = "Export de la GPO"
                "Erreur" = "Une erreur s'est produite lors de l'export de la GPO. $($error[0].Exception.Message)"
        })
        }
    }
    else
    {
        Write-Debug "Le déplacement du fichier source $($gpo.displayname) est en erreur. Pas d'export fait"
        $errors.Add([pscustomobject]@{
            "Fichier" = $gpo.displayName
            "Type" = "Manuel"
            "Action" = "Export de la GPO"
            "Erreur" = "Un déplacement du fichier source est en erreur. Cette GPO ne sera pas exportée pour préserver l'historique."
        })
    }
    #On vérifie si le répertoire de backup existe ou non
    if (!(Test-Path $(Join-Path $workspace $gpo.DisplayName)))
    {
        Try
        {
            New-Item -ItemType Directory -Name $gpo.DisplayName -ErrorAction Stop -Verbose -Force
            Backup-GPO -Guid $gpo.id -Path $(Join-Path $workspace $gpo.DisplayName) -Comment "Backup du $date" -ErrorAction Stop -Verbose
        }
        catch
        {
           $errors.Add([PSCUSTOMOBJECT]@{
                "Fichier" = $gpo.DisplayName
                "Type" = $Error[0].CategoryInfo.Reason
                "Action" = "Création de backup"
                "Erreur" = "Une erreur s'est produite lors de la création du répertoire de backup ou du backup pour la GPO. $($Error[0].Exception.Message)"
           })
        }
    }

}
#Une feuille CSS qui sera intégrée au fichier HTML afin de pouvoir avoir un affichage un peu plus sympa
$css = @"
<style media="screen" type="text/css">
table {
 width: 100%;
 border: 2px solid;
 border-collapse: collapse;

}
th, td, tr {

 border: 1px solid;
}

th {
    color: black;
    text-align: center;
 vertical-align: middle;
 height: 50px;
 font-size: 30px;
 background-color: lightblue;
}

td[div=gpo]{
 font-size: 18px;
 vertical-align: top;
 text-align: center;
 text-transform: uppercase;
 font-weight: bold;
}
td[div=time]{
 vertical-align: top;
 text-align: center;
}
p {
    font-family: verdana;
    font-size: 20px;
}

div {
 font-family: Arial;
}
div.delete {
 background-color: lightcoral;
 color: darkred;
 text-decoration:line-through;
 display: block;
 font-weight: bold;
 font-family: verdana;
}
div.create{
 background-color: lightgreen;
 color: darkgreen;
 font-style: italic;
 font-family: verdana;
}
div.warning{
    background-color: yellow;
    font-weight: bold;
    font-size: 150%;
}

</style>
"@
try
{
    $htmlfile = new-object System.Collections.Generic.List[string]
}
catch
{
    try
    {
        $htmlfile = [System.Collections.Generic.List[string]]::new()
    }
    catch
    {
        exit 50
    }
}
$htmlfile.Add("<html>")
$htmlfile.Add("<head>")
$htmlfile.Add('<meta charset="utf-8" />')
$htmlfile.Add($css)

$htmlfile.Add("</head>")
$htmlfile.Add("<body>")
$htmlfile.Add("<table>")
$htmlfile.Add("<tr>")
$htmlfile.Add("<th>GPO</th>")
$htmlfile.Add("<th>Date de modification</th>")
$htmlfile.Add("<th>Différences</th>")
$htmlfile.Add("</tr>")
Write-Debug "Parcours des nouveaux fichiers extraits de GPOS"
foreach ($newitem in (Get-ChildItem $workspace -Filter "*_new.xml"))
{
    $isnewgpo = $false
    try
    {
        Write-Debug "Récupération de $($newitem.name.replace(`"_new.xml`","_$date.xml`"))"
        $olditem = Get-Item $newitem.name.replace("_new.xml","_$date.xml") -ErrorAction Stop
    }
    catch
    {
        Write-Debug "Pas de fichier en date du jour. Recherche d'un plus ancien"
        $foundfiles = Get-ChildItem | Where-Object {$_.name -match "^$($newitem.Name.replace("_new.xml","_\d{$($date.length)}.xml$"))"}
        #if ((get-childitem $newitem.Name.Replace("_new.xml","_*.xml") -Exclude $newitem.Name).count -ne 0)
        if ($foundfiles.count -ne 0)
        {
            try
            {
                Write-Debug "Récupération du fichier le plus récent qui n'est pas $($newitem.name)"
                $lastknownitem = (get-childitem -Exclude $newitem.Name -ErrorAction Stop | Where-object {$_.name -match "^$($newitem.Name.replace("_new.xml","_\d{$($date.length)}.xml$"))"})  | Sort-Object -Property name -Descending | Select-Object -First 1
                Write-Debug "Fichier trouvé : $($lastknownitem.name)"
                $olditem = $lastknownitem
            }
            catch
            {
                Write-Debug "Aucun fichier plus récent. La GPO est nouvelle."
                $isnewgpo = $true
            }

            if ($isnewgpo -eq $true -or $olditem -eq $null)
            {
                $errors.Add([pscustomobject]@{
                    "Fichier" = $olditem.Name
                    "Type" = $Error[0].CategoryInfo.Reason
                    "Action" = "Récupération de l'ancien fichier $($newitem.name.replace("_new.xml","_$date.xml"))"
                    "Erreur" = "La récupération de l'ancien fichier n'a pas pu être effectuée. $($Error[0].Exception.Message). La gpo est nouvelle"
                })
                $isnewgpo = $true
            }
        } 
        else
        {
            Write-Debug "Aucun fichier plus ancien trouvé."
            $isnewgpo = $true
        }
    }

     #récupération des fichiers
     Write-Debug "Lecture du contenu de $($newitem.name) pour création d'un objet XML"
     [xml]$xmlnew = Get-Content $newitem
     if ($isnewgpo -eq $true)
     {
        Write-Debug "La gpo $($newitem.name) est nouvelle, on passe ce fichier"
        $errors.Add([pscustomobject]@{
            "Fichier" = $newitem.Name
            "Type" = "Nouvelle GPO"
            "Action" = "La GPO $($newitem.name.replace("_new.xml","_$date.xml")) a été créée en date du $($xmlnew.GPO.CreatedTime)"
            "Erreur" = "GPO Non traitée car nouvelle. $($Error[0].Exception.Message)."
        })
        continue
     }
     Write-Debug "Lecture du contenu de $($olditem.name) pour création d'un object XML de comparaison"
     [xml]$xmlold = Get-Content $olditem

    if ($xmlold.GPO.ModifiedTime -ne $xmlnew.GPO.ModifiedTime)
    {
        Write-Debug "Les fichiers comportent des dates de modifications différentes."
        $sendmail = $true
        Write-Host -ForegroundColor Green "Modifications détectées entre $($newitem.name) et $($olditem.name)!"
        $htmlfile.Add("<tr>")
        $htmlfile.Add("<td div='gpo'>$($xmlold.GPO.Name)</td>")
        $htmlfile.Add("<td div='time'>$($xmlold.GPO.ModifiedTime)</td>")
        Write-Debug "Selection de la GPO pour sauvegarde"
        $thisgpo = $gpos | Where-Object {$_.DisplayName -eq $xmlnew.GPO.Name}        
        try
        {
            Backup-GPO -Guid $thisgpo.id -Path $(Join-Path $workspace $thisgpo.DisplayName) -Comment "Backup du $date" -ErrorAction Stop
        }
        catch
        {
            $errors.Add([pscustomobject]@{
            "Fichier" = $thisgpo.DisplayName
            "Type" = "BackupGPO"
            "Action" = "La GPO $($thisgpo.DisplayName) n'a pas pu être sauvegardée"
            "Erreur" = "GPO Non sauvegardée. $($Error[0].Exception.Message)."
            })

        }
        #$enc sera utilisé pour lire et convertir le fichier xml
        $enc = [System.Text.Encoding]::$encoding
        $xmlold.InnerXml.replace("><",">`n<")| Out-File $(join-path $workspace "__xmlold.xml") -Encoding $encoding -Force
        $xmlnew.InnerXml.replace("><",">`n<")| Out-File $(join-path $workspace "__xmlnew.xml") -Encoding $encoding -Force
        Write-Debug "Analyse des fichiers XML et comparaison via l'outil diff_match_patch"
        $differences = Highlight-Differences -originalfile (Get-Item .\__xmlold.xml) -differences (Get-Item .\__xmlnew.xml)
        if ($differences)
        {
            $htmlfile.Add("<td>")
            foreach ($difference in $differences)
            {
                $htmlfile.add("$($difference.replace('<span>','<div>').replace('</span>','</div>'))")
            }
        }
        else
        {
            #Encore valide?
            Write-Debug "une erreur s'est produite lors de la comparaison des fichiers."
            $htmlfile.Add("<td>")
            $htmlfile.Add("ERREUR LORS DE LA COMPARAISON DES FICHIERS")
        }
        $htmlfile.Add("</td>")

        $htmlfile.Add("</tr>")
    }
    else
    {
        #Supprimer le fichier XML fraichement crée, inutile car aucune modification par rapport à l'ancien
        Remove-Item $newitem -Verbose -Force
    }
}

$htmlfile.Add("</table>")

$htmlfile.Add("<br>")
$htmlfile.Add("<br>")
$htmlfile.Add("<br>")

if ($infos.Count -gt 0)
{
    $sendmail = $true
    $htmlfile.Add("<table>")
    $htmlfile.Add("<tr>")
    $htmlfile.Add("<th>GPO</th>")
    $htmlfile.Add("<th>Action</th>")
    $htmlfile.Add("</tr>")
    foreach ($entry in $infos)
    {
        $htmlfile.Add("<tr>")
        $htmlfile.Add("<td>$($entry.gpo)</td>")

        if ($entry.Information -eq "La GPO a été créée")
        {
        $htmlfile.Add("<td div='create'>Creation d'une GPO</td>")
        }
        else
        {
            $htmlfile.Add("<td div='delete'>Suppression d'une GPO</td>")
        }
        $htmlfile.Add("</tr>")
    }

}
$htmlfile.Add("</table>")
$htmlfile.Add("</body>")
$htmlfile.Add("</html>")
Write-Debug "Export du fichier HTML $(Join-Path $workspace "$htmlfilename")"
$htmlfile | Out-File $(Join-Path $workspace "$htmlfilename")

$htmlcontent = ""
foreach ($ligne in $htmlfile) { $htmlcontent += $ligne}

$accesserror = $false
if ($sendmail)
{
    Send-MailMessage -From "$from" -To $to -Subject "Modifications sur GPO" -Body $htmlcontent -BodyAsHtml -Attachments  $(Join-Path $workspace "$htmlfilename") -SmtpServer "$mailserver" -Port $smtpport -UseSsl:$usessl -Encoding $encoding
}
$creds = new-object System.Management.Automation.PSCredential -ArgumentList "$username",$("$password" | ConvertTo-SecureString -AsPlainText -Force)
try
{
    $drive = New-PSDrive -PSProvider FileSystem -Name "strategies"  -Root "$backuplocation"  -Credential $creds -ErrorAction Stop
}
catch
{
    $accesserror = $true
    Write-Host -ForegroundColor Red "Impossible de se connecter au lecteur réseau. $($error[0].exception.message)"
}
if (!$accesserror)
{
    foreach ($file in (Get-ChildItem $workspace "*.html" |Where-Object {$_.name -ne "$htmlfilename"}))
    {
        try
        {
            Move-Item $file "strategies:\" -Force -ErrorAction Stop -Verbose
            #Remove-Item $file -Force -ErrorAction Stop -Verbose
        }
        catch
        {
            Write-Host "Erreur sur $($file.name) : $($error[0].exception.Message)"
        }
    }
}
remove-psdrive -Name "strategies" -PSProvider FileSystem

Ajouter un commentaire

Article précédent Article suivant