Déplacer les autorisations des dossiers de départ vers le nouvel Active Directory

Nov 23 2020

Je dois déplacer les dossiers de départ de plus de 100 utilisateurs d'une annonce à une autre. Le samAccountName de chaque utilisateur est le même dans les deux AD, mais l'ObjectGUID diffère car les utilisateurs ont été exportés et importés avec un fichier CSV plutôt qu'avec une approbation.

La copie n'est pas un vrai problème - je crois que j'ai une ligne de robocopy qui fonctionne, mais je suis plus inquiet de la définition des autorisations sur les dossiers après le déplacement. Je voudrais parcourir chaque dossier personnel et attribuer la propriété et le contrôle total à l'utilisateur dont samAccountName correspond au nom du dossier.

Cependant, je ne suis pas tout à fait à l'aise avec les commandes Powershell Get-ACL et Set-ACL. Si je comprends bien, je dois d'abord saisir l'ACL d'un dossier dans une variable, puis manipuler les autorisations sur la variable, puis appliquer les autorisations appropriées avec Set-ACL.

La façon dont je l'envisage:

  1. Get-ACL d'un dossier vers $ UserACL
  2. Obtenez le nom d'un dossier utilisateur
  3. Voir si je peux faire correspondre un nom de dossier avec un samAccountName
  4. Si tel est le cas, ajoutez les autorisations utilisateur à $ UserACL
  5. Définissez les autorisations sur le dossier en exécutant Set-ACL sur le dossier utilisateur
  6. Si aucune correspondance, définissez les autorisations afin que seuls les administrateurs aient accès au dossier (il existe un certain nombre de comptes inactifs qui ne peuvent pas simplement être supprimés)

Pseudo code:

$baseACL = Get-ACL -Path [ExampleDir] $HomeFolders = Get-ChildItem [RootDir] | Where-Object {$_.PSIsContainer} | Foreach-Object {$_.Name}
$ADUsers=Import-csv 'UserCSV.csv' -Delimiter ';' Foreach ($Folder in $HomeFolders) { ForEach ($User in $ADUsers) { if ($Folder -eq $($User.samAccountName)) {
      # Set properties
      $useridentity = "[AD]\$Folder"
      $admidentity = "BUILTIN\Administrators" $fileSystemRights = "FullControl"
      $type = "Allow" # Create new rule $fileSystemAccessRuleArgumentList = $useridentity, $admidentity, $fileSystemRights, $type
      $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList
      # Apply new rule
      $baseACL.SetAccessRule($fileSystemAccessRule)
      Set-Acl -Path "[Path]\$Folder" -AclObject $baseACL
    }
    Else {
      $admidentity = "BUILTIN\Administrators" $fileSystemRights = "FullControl"
      $type = "Allow" # Create new rule $fileSystemAccessRuleArgumentList = $admidentity, $fileSystemRights, $type $fileSystemAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $fileSystemAccessRuleArgumentList # Apply new rule $baseACL.SetAccessRule($fileSystemAccessRule) Set-Acl -Path "[Path]\$Folder" -AclObject $baseACL
    }
  }
}

Il ne s'agit que de définir les autorisations et non la propriété, donc je ne suis pas sûr que cela soit possible dès le départ avec PowerShell. Ou aurai-je besoin de regarder les cacls et de les prendre?

Réponses

Laage Dec 09 2020 at 17:26

J'ai trouvé une solution qui, avec quelques ajustements, a fonctionné pour moi ici: HALP! J'ai hérité d'un cauchemar d'autorisations pour les dossiers / répertoires de départ redirigés

Mon script fini ressemble principalement à ceci:

#requires -PSEdition Desktop
#requires -version 5.1
#requires -Modules ActiveDirectory
#requires -RunAsAdministrator

[CmdLetBinding()]
Param ()

$AD = [DOMAIN CONTROLLER] $Root = [HOME DIRECTORY]

$Paths = Get-ChildItem $Root -Directory | Select-Object -Property Name,FullName

# Local Admin access rule
$LASID = Get-LocalGroup -Name 'Administrators' | Select-Object -ExpandProperty SID $LAAR = New-Object System.Security.AccessControl.FileSystemAccessRule($LASID, "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow") # Domain Admin access rule $DASID = Get-ADGroup -Server $AD -Filter { Name -eq 'Domain Admins' } | Select-Object -ExpandProperty SID $DAAR = New-Object System.Security.AccessControl.FileSystemAccessRule($DASID, "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow") # System Access rule $SysAR = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")

Try {
  foreach ($Directory in $Paths) {
    $samExists = $(try {Get-ADUser -Server $AD -Identity $($Directory.Name)} catch {$null})
    if ($samExists -ne $null) {
      # For error handling purposes - not all folders will map to a user of the exact same name
      Write-Output "Creating User ACL for $($Directory.FullName) ... "
      
      # Creates a blank ACL object to to add access rules into, also blanks out the ACL for each iteration of the loop
      $ACL = New-Object System.Security.AccessControl.DirectorySecurity # Creating the right type of user object to feed into our ACL and populating it with the user whose folder we're currently on $UserSID = Get-ADUser -Server $AD -Identity $($Directory.Name) | Select-Object -ExpandProperty SID # $objUser = New-Object System.Security.Principal.NTAccount($UserSID) # Access rule for the user whose folder we're dealing with this iteration $UserAR = New-Object System.Security.AccessControl.FileSystemAccessRule($UserSID, "FullControl","ContainerInherit,ObjectInherit", "None", "Allow") # Change the inheritance, propagation settings for the folder we're dealing with $ACL.SetOwner($UserSID) $ACL.SetAccessRuleProtection($true,$false)

      $ACL.SetAccessRule($UserAR)
      $ACL.SetAccessRule($LAAR)
      $ACL.SetAccessRule($DAAR)
      $ACL.SetAccessRule($SysAR)

      # For error handling purposes - not all folders will map to a user of the exact same name
      $ACL | Format-List Set-Acl -Path $Directory.FullName -AclObject $ACL } else { # For error handling purposes - not all folders will map to a user of the exact same name Write-Warning "Creating Admin ACL for $($Directory.FullName) ... " # Creates a blank ACL object to to add access rules into, also blanks out the ACL for each iteration of the loop $ACL = New-Object System.Security.AccessControl.DirectorySecurity

      # Creating the right type of user object to feed into our ACL and populating it with the user whose folder we're currently on
      # $objUser = New-Object System.Security.Principal.NTAccount($DASID)

      # Change the inheritance, propagation settings for the folder we're dealing with
      $ACL.SetOwner($DASID)
      $ACL.SetAccessRuleProtection($true,$false) $ACL.SetAccessRule($LAAR) $ACL.SetAccessRule($DAAR) $ACL.SetAccessRule($SysAR) # For error handling purposes - not all folders will map to a user of the exact same name $ACL | Format-List

      Set-Acl -Path $Directory.FullName -AclObject $ACL
    }
  }
}

Catch {
  Write-Host -BackgroundColor Red "Error: $($_.Exception)"
  Break
}