Active-Directory
將主文件夾的權限移動到新的 Active Directory
我需要將 100 多個使用者的主文件夾從一個 AD 移動到另一個。每個使用者的 samAccountName 在兩個 AD 中都相同,但 ObjectGUID 不同,因為使用者是使用 CSV 文件而不是信任導出和導入的。
複製不是真正的問題——我相信我有一條可以工作的 robocopy 線,但我更擔心在移動後設置文件夾的權限。我想遍歷每個主文件夾並將所有權和完全控制權分配給 samAccountName 與文件夾名稱匹配的使用者。
但是,我對 Powershell Get-ACL 和 Set-ACL 命令並不完全滿意。如果我理解正確,我需要先將 ACL 從文件夾中抓取到變數中,然後操作變數的權限,然後使用 Set-ACL 應用正確的權限。
我設想的方式:
- 從文件夾獲取 ACL 到 $UserACL
- 獲取使用者文件夾的名稱
- 看看我是否可以將文件夾名稱與 samAccountName 匹配
- 如果是這樣,將使用者權限添加到 $UserACL
- 通過在使用者文件夾上執行 Set-ACL 來設置文件夾的權限
- 如果不匹配,請設置權限,以便只有管理員可以訪問該文件夾(有許多不能刪除的非活動帳戶)
虛擬碼:
$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 }