Quick Snippet to Copy NTFS Permissions Between SMB Shares

The experimental script below will sync permissions of a folder toward another.

WARNING: if sub-folders at the destination does NOT inherit permissions from its root directory parent, then any ACL changes to root or parent directory may render sub-folders ACL to be NULL. NO NOT use this script in production without knowing contexts!

The only good usage of this script is to run it before an initial data sync between 2 SMB servers. Be certain that new destination directories are empty prior to copying ACLs. Once the ACLs of root directories are copied, then data sync could be ran to copy sub-directories and data with explicit ACLs to those items.

$arr=@();
$arr+=[PSCustomObject]@{Clustername='';From='D:\Accounting';To='\\NEWSERVER\Accounting'}
$arr+=[PSCustomObject]@{Clustername='';From='D:\Test';To='\\NEWSERVER\Test'}

$arr=@();
$arr+=[PSCustomObject]@{Clustername='';From='D:\Accounting';To='\\NEWSERVER\Accounting'}
$arr+=[PSCustomObject]@{Clustername='';From='D:\Test';To='\\NEWSERVER\Test'}

foreach ($item in $arr){
    $sourceDirectory=$item.From
    $destinationDirectory=$item.To
    # Noting this command here to remind us that command below doesn't work when an entity in Source ACL is invalid; hence, the long workaround to bypass those errors
    # Get-Acl $sourceDirectory|Set-Acl $destinationDirectory
    $sourceAcl=Get-Acl -path $sourceDirectory
    $destinationAcl=Get-Acl -path $destinationDirectory
    foreach($permission in $sourceAcl.Access){
        $identity=$permission.IdentityReference
        $rights=$permission.FileSystemRights
        $accessType=$permission.AccessControlType
        try{
            $accessRule=New-Object System.Security.AccessControl.FileSystemAccessRule($identity,$rights,$accessType) -ea Ignore
        }catch{
            write-warning $_
        }
        $destinationAcl.AddAccessRule($accessRule)
    }
    # Uncomment this line to run experiment
    # Set-Acl $destinationDirectory $destinationAcl
    write-host "Root directory $sourceDirectory ACL has been set toward $destinationDirectory as:`r`n$($destinationAcl|ft -wrap|out-string)"
}

Leave a Reply

Your email address will not be published. Required fields are marked *