We are in a colocated RackSpace facility in San Antonio, with an active directory named "SAT".

We are being moved to their Dallas/Ft. Worth facility, with an active directory named "DFW".

These machines are running Windows 2008 Server (some 32-bit, some 64-bit).

The machines have been cloned to the new facility using DoubleTake software, and are generally working fine. Upon moving the machines over, however, we have been forced to start logging in with new user accounts established in the DFW Active Directory.

I spent a long time getting our original servers working, in terms of file permissions across the servers, and am hoping someone can share some programmatic way, either with an existing piece of software, or even some custom .NET code, that we can "translate" all of these permissions.

For example, I'd like some way to specify the drives to update, the "BEFORE" username, e.g. SAT\User, and the "AFTER" username, e.g. "DFW\User", and let er rip... Any ideas?


I highly recommend the free open source tool, SetACL.


I'm going to assume that SAT and DFW do not have any kind of trust, and SAT\USER1 probably has a vastly different SID than DFW\USER1. Permissions in NTFS are all stored by SID, not username. This can complicate things.

Learn the backup and restore commands first, and backup the permissions on all your servers to a safe place. You may need to come up with your own solution where you backup the existing permissions to an SDDL file, search and replace the domain names or SIDs, and then restore that in the new domain.

  • 1
    +1 - I'd be all over using SetACL for this, too. – Evan Anderson Jul 6 '11 at 5:00
  • Although I marked @mrdenny's response as the answer since it was the solution for us, I marked your answer up as well because it was very helpful for other situations! – Mason G. Zhwiti Jul 15 '11 at 18:41

As the domains are trusted, make Rackspace use the AD migration tool to migrate the accounts to the new DFW domain. This way all the SIDs will remain the same and the new accounts will simply have the correct permissions.

  • Thanks for your help on this. I chose this as the answer because in our case, this is going to work. However, the other answer from @Jed is also very helpful in situations where yours will not work. – Mason G. Zhwiti Jul 15 '11 at 18:40

Using the feedback from @Jed and @mrdenny, I thought I would answer my own question with the exact procedure I used to solve the issue.

As it turns out, RackSpace is unable to migrate the accounts over with the same SIDs, because that would require doing a "cut-over" where our old systems would no longer be usable. We need both environments to be online at the same time, for testing during our migration.

So I moved on to the SetACL.exe idea and that worked. Here is exactly what I did.

  1. Downloaded SetACL.exe from http://helgeklein.com/download/
  2. Ran this command to backup all of our existing ACL information on the server for the C: drive:

    SetACL.exe -on C:\ -ot file -actn list -lst "f:sddl;w:d,s,o,g" -rec cont -bckp "c:\acl-backup.txt"

  3. Obtained the BEFORE and AFTER SIDs for all of our users and groups between the old and new active directory domains.

  4. Wrote a perl script to find/replace these SIDs in the acl-backup.txt file. A little tricky since Unicode 16 read/write support is a little wonky in the Windows version of Perl. The script I used was basically this:

    use charnames qw( :full );
    # e.g. take acl-backup.txt and rename to acl-backup.replaced.txt
    my $newfilename = $ARGV[0];
    $newfilename =~ s/(\..{3,4})$/.replaced$1/;
    if ($ARGV[0] eq $newfilename)
            # Sanity Check
        die "Could not continue: new file would overwrite old file ($newfilename)\n";
    open my $input_fh, '<:raw:perlio:encoding(UTF-16):crlf', $ARGV[0];
        or die "Could not open $ARGV[0] for reading: $!";
    open my $output_fh, '>:raw:perlio:encoding(UTF-16LE):crlf', $newfilename
        or die "Could not open $newfilename for writing: $!";
    print $output_fh "\N{BYTE ORDER MARK}";
    while (my $line = <$input_fh>)
        # you'll need a line like this for each SID you're replacing
        $line =~ s/S-1-5-21-1844237615-861567501-XXXXXXXXX-XXXX/S-1-5-21-1644697732-2861104425-YYYYYYYYY-YYYYY/g;
        chomp $line;
        print $output_fh "$line\n";
    close $output_fh;
    close $input_fh;
  5. Ran the setacl.exe restore command on the newly generated file (be careful, as if you have made a mistake in your new replaced.txt file, you could bork your ACLs completely... although theoretically you should have a pristine backup you can restore from Step 2):

    setacl -on c:\ -ot file -actn restore -bckp acl-backup.replaced.txt

The only issue I encountered is I would occassionally get errors like this:

ERROR: Writing SD to <\\?\c:\inetpub\custerr> failed with: The parameter is incorrect.

Not sure why, but in my case I was able to remove those lines from the replaced.txt file (as well as the ones above it that had already been completed by setacl.exe), and move on. Then go back later and manually check the permissions on those areas that failed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.