Blog/Domino/domino_group_acl.ps1

278 lines
10 KiB
PowerShell
Raw Permalink Normal View History

2023-12-17 19:29:57 +01:00
#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