From 97ba946da09ae2af5a03e12b3b96a37dd0caabb2 Mon Sep 17 00:00:00 2001 From: Nicolas Lang Date: Sun, 17 Dec 2023 19:29:57 +0100 Subject: [PATCH] =?UTF-8?q?Cr=C3=A9ation=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Domino/domino_group_acl.ps1 | 278 ++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 Domino/domino_group_acl.ps1 diff --git a/Domino/domino_group_acl.ps1 b/Domino/domino_group_acl.ps1 new file mode 100644 index 0000000..c42a540 --- /dev/null +++ b/Domino/domino_group_acl.ps1 @@ -0,0 +1,278 @@ +#Script créé par Nicolas Lang - Sous licence CC-BY-SA +#https://nicolaslang.fr + +if ([System.IntPtr]::Size -ne 4) +{ + Write-Error "Ce script doit être lancé depuis un Powershell 32 bits (disponible dans %windir%\syswow64\WindowsPowershell)" + Exit 3 +} + +function Clean-Filename ($Filename=$(throw "Can't be empty")) +{ + $invalidcharsforpath = [System.IO.Path]::GetInvalidFileNameChars() + foreach ($char in $invalidcharsforpath) + { + $Filename = $Filename.replace("$char","") + return $Filename + } +} + +$aclarray = New-Object System.Collections.ArrayList +$errorarray = New-Object System.Collections.ArrayList + +#Le mot de passe à utiliser par l'identité proposée par Notes lorsque vous le lancez. Vous ne pouvez pas changer d'identité depuis ce script +$passwordforactualaccount = "PASSW0RD" +#Creating the Lotus object +$lotus = New-Object -ComObject Lotus.Notessession +try +{ + #Ouverture de Notes avec l'identité par défaut et le mot de passe fourni + $lotus.Initialize("$passwordforactualaccount") +} +catch +{ + Write-Output "Impossible d'ouvrir Notes, mot de passe incorrect?." + exit 2 +} +Write-Output "Logged as $($lotus.usernamelist.canonical)" + +<# +Ce script enregistrera les données sur le Bureau. Vous pouvez changer la valeur pour un chemin régulier ou utiliser une valeur de cette list : +Desktop +Programs +MyDocuments +Personal +(et bien d'autres...) +#> + +$exportfolder = [Environment]::GetFolderPath("Desktop") +Set-Location $exportfolder + +#Vous pouvez ajouter autant d'objets que vous le désirez dans la section $databasepath. Respectez juste la syntaxe et tout sera ok : +#"server" : Le chemin vers le serveur Domino. Exemple : "\\DOMINO01" +#"datapath" : Le chemin amenant versle repertoire des données de Domino, là ou sont stockés les fichiers NSF. Si vous utilisez un partage caché, ajoutez un ` avant le $. Cela échappera le caractère. Exemple : "d`$\domino\data\" +#"splitpart" : Utilisé pour séparaer le repertoire racine du restant. Il s'agit souvent de "data", et cette section est utilisée pour Lotus, permettant à l'object COM de trouver la base dans son arborescence. +# NE TERMINEZ PAS PAR Un \ . Si vous spécifiez une valeur avec un \ dedans, remplacez le par un double backslash \\. +#"lotusdomainname" : Le nom que la methode getdatabase() va utiliser pour selectionner le serveur. + + + +$databasepath = @( + +[PSOBJECT]@{ +"server"="\\DOMINO01" +"datapath"="c`$\lotus\domino\data\" +"splitpart"="data" +"lotusdomainname"="domino01/Company France" +} + +[PSOBJECT]@{ +"server"="\\DOMINO03" +"datapath"="d`$\lotus\domino\data\" +"splitpart"="data" +"lotusdomainname"="domino02/Company UK" +} + +) + + + +$resultsarray = @() + +#<# + + +$id =0 + +$databasepath | foreach { + #Pour chaque valeur dans databasepath, je joins "server" et "datapah' pour créer un chemin UNC pour l'analyse avec Robocopy + $analysed = Join-Path $_.server $_.datapath + #Le nom du fichier de log. $ID est incrementé, permettant de reconnaitre chaque entrée dans la variable $databasepath + $logname = "robocopylog_$id.log" + #Ajout de l'ID correspondante à l'entrée actuelle dans $databasepath + $_ | Add-Member -MemberType NoteProperty -Name "logid" -Value $id + $id++ + $logname = Clean-Filename -Filename $logname + + try + { + New-Item -ItemType file -Name "$logname" -Force -ErrorAction Stop + } + catch + { + Write-Host "Impossible de créer le fichier de log : $logname" + continue + } + + #Lancement d'un nouveau processus Robocopy, qui scannera les dossiers à la recherche de nos précieux fichiers NSF, et enregistrant tout dans le fichier de log précedemment crée + $results = Start-process "robocopy" -argumentlist "$analysed NULL *.nsf /NDL /NS /L /S /XJ /TS /NJS /NJH /UNILOG:$logname" -PassThru -Wait -WindowStyle Hidden + #Les codes de sortie de Robocopy sont ok si en dessous de 7. Au dessus, une erreur s'est produite + if ($results.ExitCode -gt 7) + { + Write-Warning "Erreur avec robocopy!" + Exit 5 + } +} + +#> +#On récupère les fichiers de log robocopy +$loglist = Get-item "robocopylog_*.log" + + +foreach ($log in $loglist) +{ + #On se lance à la recherche du bon serveur et on collecte les valeurs demandées + $thisserver = $null + foreach ($server in $databasepath) + { + if ($log.name -eq "robocopylog_$($server.logid).log") + { + $thisserver = $server + break + } + } + if ($thisserver -eq $null) + { + Write-host "Impossible de trouver le serveur qui a créé $($log.name)" + continue + } + else + { + #On récupère le contenu de chaque fichier... + Get-Content $log | % { + #Une petite regex pour retrouver le nom + if ($_.trim() -match "(?[\\].*$)") + { + #Et on retrouve le chemin du fichier NSF sous un format que l'objet Lotus pourra comprendre + $object = $null + $cutindex = $Matches.file.IndexOf("$($thisserver.splitpart)\") + $length = $Matches.file.Length + try + { + $object = [PSOBJECT]@{ + "server" = $thisserver.lotusdomainname + "nsffile" = $Matches.file.Substring($cutindex,$length-$cutindex) + } + } + catch + { + Write-Warning "Erreur lors de l'obtention des infos de $($matches.file)" + } + $resultsarray += $object + } + } + } +} + + +#Maintenant que nous avons la liste des fichiers NSF, leur chemin, et le serveur domino qui est rattaché, nous pouvons collecter nos ACLs +$progress = 0 +foreach ($entry in $resultsarray) +{ + + Write-Progress -Activity "Analyse des ACL" -Status $entry.nsffile -PercentComplete $($progress/$($resultsarray.count)*100) + $progress++ + $index = 1 + $aclobjectlist = @() + + #Vidage de $db à chaque passage, pour pouvoir vérifier si la propriété .ISOpen est $false (DB manquante) ou si $db n'existe pas (problem avec le chemin) + $db = $null + + #Connexion à la DB + $db = $lotus.GetDatabase($entry.server,$entry.nsffile) + + #On verifie que l'ouverture se fait correctement + if ($db.IsOpen -eq $false -or $db -eq $null) + { + $message = $null + switch ($db.isopen) + { + $null {$message = $($error[0].Exception.Message)} + $false {$message = "Pas de base de données $($entry.nsffile) sur $($entry.server)"} + + } + + $errorarray.Add([PSCUSTOMOBJECT]@{ + "Fichier" = $entry.nsffile -as [String] + "Serveur" = $entry.server -as [String] + "Erreur" = $message + }) + Write-Host "Impossible d'ouvrir $($entry.nsffile) sur $($entry.server)" + continue + } + #On obtient la première ACL + $acl = $db.ACL.GetFirstEntry() + #On boucle tant qu'on trouve une autre ACL + while ($acl -ne $null) + { + #On récupère si ca n'est pas un serveur et si c'est un groupe ou une personne + if ($acl.IsServer -ne $true -and ($acl.isGroup -eq $true -or $acl.isperson -eq $true)) + { + #Je vérifie seulement les propriétés de création et suppression de documents. D'autres droits existent, que vous pouvez ajouter à la suite en utilisant la même syntaxe. + $aclinfo = [PSCUSTOMOBJECT]@{ + "Name" = $acl.Name + "CanCreateDocuments" = $acl.CanCreateDocuments + "CanDeleteDocuments" = $acl.CanDeleteDocuments + } + #Ajout de l'objet à la liste d'ACL + $aclobjectlist += [pscustomobject]@{"Nom" =$acl.name;"Droits"=$aclinfo} + + $index++ + } + #On obtient la prochaine ACL ... et ainsi de suite + $acl = $db.ACL.GetNextEntry($acl) + } + #Lorsque nous avons fini avec les ACL sur cette DB, on ajoute les résultats au tableau récaputilatif + $aclarray.Add([PSCUSTOMOBJECT]@{ + "Serveur" = $entry.server -as [String] + "Fichier" = $entry.nsffile -as [String] + "ACL" = $aclobjectlist | Sort-Object -Property "Nom"}) | Out-Null +#Et on passe à la suivante +} + +#On compte le maximum d'ACLs trouvées sur un DB. Cette valeur maximum sera utilisée pour ajouter des membres aux autres objets, d'avoir le même nombre partout afin d'avoir un fichier CSV à la fin. +$max = 0 +$aclarray | % { + $count = $_.acl.count + if ($count -gt $max) + { + $max = $count + } +} + +#Nouvel objet qui conservera toutes les données après formatage +$exportableaclarray = New-Object System.Collections.ArrayList + +#On parcourt les résultats +foreach ($entry in $aclarray) +{ + #On crée une nouvelle ligne qui démarrera avec le nom du serveur, puis le nom de la base NSF + $object = [PSCUSTOMOBJECT]@{ + "Serveur" = $entry.serveur + "Fichier" = $entry.Fichier + } + + $index=1 + #On ajoute des colonnes. D'abord le nom, puis les droits de création, ensuite de suppression pour chaque ACL trouvée + foreach ($acl in $entry.acl) + { + $object | Add-Member -Name "Membre_$index" -MemberType NoteProperty -Value $acl.Nom + $object | Add-Member -Name "Droits_Creation_membre_$index" -MemberType NoteProperty -Value $acl.Droits.CanCreateDocuments + $object | Add-Member -Name "Droits_Suppression_membre_$index" -MemberType NoteProperty -Value $acl.Droits.CanDeleteDocuments + $index++ + } + #Et on remplit le reste avec des valeurs vides jusqu'a ce que nous ayons le même nombre de colonnes que le fichier NSF avec le plus grand nombre d'ACL + for ($i = $index;$i -le $max;$i++) + { + $object | Add-Member -Name "Membre_$i" -MemberType NoteProperty -Value $null + $object | Add-Member -Name "Droits_Creation_membre_$i" -MemberType NoteProperty -Value $null + $object | Add-Member -Name "Droits_Suppression_membre_$i" -MemberType NoteProperty -Value $null + } + $exportableaclarray.Add($object) | Out-Null + +} + +#Puis nous exportons les résultats +$exportableaclarray | Export-Csv "$exportfolder\liste_acl_Notes.csv" -NoTypeInformation -Delimiter ";" -Encoding UTF8 +#Et enfin les erreurs rencontrées +$errorarray | Export-Csv "$exportfolder\erreuracl.csv" -NoTypeInformation -Delimiter ";" -Encoding UTF8 \ No newline at end of file