#Script créé par Nicolas Lang - Sous licence CC-BY-SA #https://nicolaslang.fr $ErrorActionPreference = "Stop" #Faites correspondre $path avec la même valeur que dans le script d'interface utilisateur $path = "\\nas\ScriptPS\Workspaces\TemporaryUserToGroup" $filelist = Get-ChildItem $path #Les fichiers XML sont générés avec un identifiant numérique. La regex va filtrer selon ce critère $totreat = $filelist | Where-Object {$_.Name -match "^\p{Nd}.+.xml$"} #Les fichiers à moitié traités commencent par un A puis un identifiant numérique. La encore, la regex va filtrer. $resultarrayimports = $filelist | Where-Object {$_.Name -match "^A\p{Nd}.+.xml$"} $resultarray = New-Object System.Collections.ArrayList $global:headers = $null function Update-File { param($from = $null,$until = $null) $result = $null if ($from -ne $null) { $result = $resultarray.IndexOf($from) if ($result -eq -1) { "$(get-date -format yyyyMMdd_HHmmss) : Update from FROM - $($line.$($global:headers[1])) / $($line.$($global:headers[2])) => $($Error[0].Exception.Message)" >> "$path\warning.txt" throw("No result for FROM in the result array") } else { $resultarray[$result].$($global:headers[2]+"_checked") = "X" } } elseif ($until -ne $null) { $result = $resultarray.IndexOf($until) if ($result -eq -1) { "$(get-date -format yyyyMMdd_HHmmss) : Update from UNTIL - $($line.$($global:headers[1])) / $($line.$($global:headers[2])) => $($Error[0].Exception.Message)" >> "$path\warning.txt" throw("No result for UNTIL in the result array") } else { $resultarray[$result].$($global:headers[3]+"_checked") = "X" } } else { "$(get-date -format yyyyMMdd_HHmmss) : A Null value came to the function => $($Error[0].Exception.Message)" >> "$path\warning.txt" throw("Null Value from function") } } #Récupération des fichiers et ajout des colonnes de check date foreach ($file in $totreat) { try { $array = Import-Clixml $file.FullName } catch { "$(get-date -format yyyyMMdd_HHmmss) : $($file.FullName) => $($Error[0].Exception.Message)" >> "$path\error.txt" throw("Error while importing") } $global:headers = $array[0].psobject.Properties.name $array | Add-Member -MemberType NoteProperty -Name $($global:headers[2]+"_checked") -Value $null $array | Add-Member -MemberType NoteProperty -Name $($global:headers[3]+"_checked") -Value $null $array | Add-Member -MemberType NoteProperty -Name "Original_file" -Value $file.Name foreach ($entry in $array) { $resultarray.Add($entry) | Out-Null } } #Récupère les headers si aucun fichier créé depuis la GUI n'existe. if ($global:headers -eq $null) { #Tente depuis des fichiers déja importés try { $array = Import-Clixml ($filelist | Where-Object {$_.Name -like "IMPORTED_*"} | Select-Object -First 1).fullname $Global:headers = $array[0].psobject.Properties.name } catch { #Si rien, tente depuis un fichier Axxxxx.xml issu d'un $resultarray précedent try { $array = Import-Clixml $($resultarrayimports | Select-Object -First 1).FullName $global:headers = $array[0].psobject.Properties.name } catch { "$(get-date -format yyyyMMdd_HHmmss) : No file to import" >> "$path\warning.txt" throw("Nothing to import!") } } } #Rajoute chaque enregistrement déja exporté auparavant if ($resultarrayimports -ne $null) { $import = Import-Clixml $resultarrayimports.FullName foreach ($result in $import) { $resultarray.Add($result) } foreach ($result in $resultarrayimports) { Move-Item $result.FullName (join-path $path $("IMPORTED_"+ $($result.Name))) } } #Renomme chaque fichier totreat, considéré comme intégré, pour ne plus être pris en compte au prochain passage du script foreach ($file in $totreat) { $newname = "IMPORTED_" + $file.Name try { Move-Item $file.FullName (Join-Path $path $newname) -Force } catch { "$(get-date -format yyyyMMdd_HHmmss) : $($file.FullName) / $newname => $($Error[0].Exception.Message)" >> "$path\error.txt" throw("Error while moving item") } } #Checke de chaque entrée dans resultarray $date = get-date foreach ($line in $resultarray) { $line if ((Get-Date $($line.$($global:headers[2]))).date -le $date.Date -and $line.$($global:headers[2]+"_checked") -eq $null) { try { Add-ADGroupMember $line.$($global:headers[1]) $line.$($global:headers[0]) Write-output "Adding $($line.$($global:headers[0])) to $($line.$($global:headers[1])) / $($line.$($global:headers[2])) to $($line.$($global:headers[3]))" } catch [Microsoft.ActiveDirectory.Management.ADException] { "$(get-date -format yyyyMMdd_HHmmss) : $($line.$($global:headers[1])) / $($line.$($global:headers[0])) => $($Error[0].Exception.Message)" >> "$path\warning.txt" } catch { "$(get-date -format yyyyMMdd_HHmmss) : $($line.$($global:headers[1])) / $($line.$($global:headers[0])) => $($Error[0].Exception.Message)" >> "$path\error.txt" throw("Erreur!") } Update-File -from $line } if ((Get-Date $($line.$($global:headers[3]))).date -lt $date.Date -and $line.$($global:headers[3]+"_checked") -eq $null) { try { Write-output "Removing $($line.$($global:headers[0])) from $($line.$($global:headers[1])) / $($line.$($global:headers[2])) to $($line.$($global:headers[3]))" Remove-ADGroupMember $line.$($global:headers[1]) $line.$($global:headers[0]) -Confirm:$false } catch [Microsoft.ActiveDirectory.Management.ADException] { "Account not member of the group " "$(get-date -format yyyyMMdd_HHmmss) : $($line.$($global:headers[1])) / $($line.$($global:headers[0])) => $($Error[0].Exception.Message)" >> "$path\warning.txt" } catch { "$(get-date -format yyyyMMdd_HHmmss) : $($line.$($global:headers[1])) / $($line.$($global:headers[0])) => $($Error[0].Exception.Message)" >> "$path\error.txt" throw("Erreur!") } Update-File -until $line } } #Clean des entrées $indexarray = @() $index = 0 foreach ($line in $resultarray) { if ($line.$($global:headers[2]+"_checked") -eq "X" -and $line.$($global:headers[3]+"_checked") -eq "X") { $indexarray += $index } $index++ } $indexarray = $indexarray | Sort-Object -Descending foreach ($entry in $indexarray) { $resultarray.RemoveAt($entry) } $rafile = "A"+(Get-Date).Ticks+".xml" if ($resultarray.Count -gt 0) { $resultarray | Export-Clixml (Join-Path $path $rafile) }