vendredi 14 septembre 2018

Powershell : liste des utilisateurs de tous les partages SMB d'un serveur

J'ai réalisé un script permettant de générer une liste d'utilisateurs des partages SMB d'un serveur, ce qui peut être pratique à des fins d'audit ou si l'on souhaite simplement contacter les utilisateurs d'un serveur de fichiers pour une maintenance par exemple.

Il existe bien l'instruction Get-SmbShare mais elle n'est disponible qu'à partir de 2012 R2 ! Afin de permettre une compatibilité avec les OS 2008 (qui seront par ailleurs bientôt plus maintenus 😱), j'ai utilisé la classe WMI Win32_share.

Le script fonctionne en plusieurs phases : tout d'abord, il liste les partages existants (tels qu'on peut les voir dans la console de Computer Management), puis liste leurs ACL et récupère les membres des groupes AD éventuellement positionnés pour n'obtenir au final que des identifiants utilisateur. Naturellement, il est nécessaire de lancer le script avec des droits d'administration sur la machine afin d'être sûr de pouvoir lire toutes les ACL et d'avoir les modules AD pour Powershell ; sans quoi il vous faudra vous résoudre à utiliser un Invoke-Command qui a de grandes chances d'être bloqué par le pare-feu.

function parse{
param($objectName)
$doneparsing = $false
    for($i=0; $doneparsing -eq $false; $i++){
        if ($i+1 -gt $parsedArray.Count) { Write-Host "Added user $objectName." ; $parsedArray.Add($objectName) > $null; $doneparsing = $true }
        if ($parsedArray[$i] -eq $objectName){ $doneparsing = $true }
    }
}

Write-Host "Share user ACL listing script"
Write-Host "============================="
Write-Host "This script will retrieve all the SMB shares and their ACLs with a 'MYDOMAIN' domain object filter to a file located in the temp folder."
$parsedArray = New-Object System.Collections.ArrayList
$sharelist = Get-WmiObject -Class Win32_Share
foreach($share in $shareList){
    if ($share.Path -ne ""){
        $aclList = (Get-Acl $share.Path).Access | Where-Object {$_.IdentityReference.ToString().Contains('MYDOMAIN') }
        foreach ($acl in $aclList){
            $objectName = $acl.IdentityReference.Value
            $canoName = $objectName.ToString().SubString(9,$objectName.Length-9)
            $objectType = Get-ADObject -Filter {CN -eq $canoName}
            if ($objectType.ObjectClass -eq "user"){ parse($objectName) }
            if ($objectType.ObjectClass -eq "group") {
                    Write-Host "Processing group $canoName..."
                    $PplInGrp = Get-ADGroupMember $canoName
                    foreach($ppl in $PplInGrp){ parse($ppl.SamAccountName) }
            }
        }
    }
}
cd $env:temp
foreach ($line in $parsedArray){
    Add-Content share-acl.txt $line }
Write-host "Done processing."

Le script renvoie alors un fichier texte avec une liste de comptes utilisateurs. Une version commentée du script est disponible en téléchargement. 💾

Aucun commentaire:

Enregistrer un commentaire