Powershell/Private/Permissions/Set-RegPermission.ps1
function Set-RegPermission { param ( [Parameter(Mandatory)] [string]$SourceSID, [Parameter(Mandatory)] [string]$TargetSID, [Parameter(Mandatory)] [string]$FilePath ) # Create SecurityIdentifier objects $SourceSIDObj = New-Object System.Security.Principal.SecurityIdentifier($SourceSID) $TargetSIDObj = New-Object System.Security.Principal.SecurityIdentifier($TargetSID) # Get NTAccount names for logging and ACLs $SourceAccount = $SourceSIDObj.Translate([System.Security.Principal.NTAccount]).Value $TargetAccount = $TargetSIDObj.Translate([System.Security.Principal.NTAccount]).Value # Add the targetAccount to the ACL if it doesn't already exist $acl = Get-Acl -Path $FilePath $targetMember = $acl.Access | Where-Object { $_.IdentityReference -eq $TargetAccount } if (-not $targetMember) { $newRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $TargetAccount, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow" ) $acl.AddAccessRule($newRule) Set-Acl -Path $FilePath -AclObject $acl } # Get all files and folders recursively, including hidden/system $items = Get-ChildItem -Path $FilePath -Recurse -Force -ErrorAction SilentlyContinue foreach ($item in $items) { try { $acl = Get-Acl -Path $item.FullName if ($null -eq $acl) { continue } $aclChanged = $false # Change owner if SourceSID is current owner if (($acl.Owner -ne $TargetAccount) -and ($acl.Owner -eq $SourceAccount)) { $acl.SetOwner($TargetSIDObj) $aclChanged = $true } # Copy SourceSID permissions to TargetSID foreach ($access in $acl.Access) { if ($access.IdentityReference -eq $SourceAccount) { $perm = $access.FileSystemRights $inheritance = $access.InheritanceFlags $propagation = $access.PropagationFlags $type = $access.AccessControlType $newRule = New-Object System.Security.AccessControl.FileSystemAccessRule( $TargetAccount, $perm, $inheritance, $propagation, $type ) $acl.AddAccessRule($newRule) $aclChanged = $true } } if ($aclChanged) { Set-Acl -Path $item.FullName -AclObject $acl } } catch { if ($_.Exception.Message -notmatch "because it is null") { Write-ToLog "Failed to update $($item.FullName): $($_.Exception.Message)" } } } } |