Active-Directory

將主文件夾的權限移動到新的 Active Directory

  • December 9, 2020

我需要將 100 多個使用者的主文件夾從一個 AD 移動到另一個。每個使用者的 samAccountName 在兩個 AD 中都相同,但 ObjectGUID 不同,因為使用者是使用 CSV 文件而不是信任導出和導入的。

複製不是真正的問題——我相信我有一條可以工作的 robocopy 線,但我更擔心在移動後設置文件夾的權限。我想遍歷每個主文件夾並將所有權和完全控制權分配給 samAccountName 與文件夾名稱匹配的使用者。

但是,我對 Powershell Get-ACL 和 Set-ACL 命令並不完全滿意。如果我理解正確,我需要先將 ACL 從文件夾中抓取到變數中,然後操作變數的權限,然後使用 Set-ACL 應用正確的權限。

我設想的方式:

  1. 從文件夾獲取 ACL 到 $UserACL
  2. 獲取使用者文件夾的名稱
  3. 看看我是否可以將文件夾名稱與 samAccountName 匹配
  4. 如果是這樣,將使用者權限添加到 $UserACL
  5. 通過在使用者文件夾上執行 Set-ACL 來設置文件夾的權限
  6. 如果不匹配,請設置權限,以便只有管理員可以訪問該文件夾(有許多不能刪除的非活動帳戶)

虛擬碼:

$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
   }
 }
}

這只是設置權限而不是所有權,所以我不確定這是否可以立即使用 powershell。還是我需要查看 cacls 和 takeown?

我在這裡找到了一個對我有用的解決方案:HALP!我繼承了重定向文件夾/主目錄的權限噩夢

我完成的腳本看起來大多是這樣的:

#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
}

引用自:https://serverfault.com/questions/1043598