Copying NTFS permissions between folders

Let’s assume you have created a folder called “Programs” in your D: volume and now you want its NTFS permissions to match that of “C:\Program Files”, thus having the same level of security.

Basic NTFS permission of "Program Files" folder in Windows 7

Basic NTFS permission of “Program Files” folder in Windows 7

There are more than one ways:

  1. Via icACLs and Notepad
  2. Via Windows PowerShell
  3. Via XCopy
  4. Via Robocopy

This article only elaborates on the first two. Since the subject of NTFS security is one that requires intermediate knowledge of Windows, I will skip elementary details such as how to run a certain program with elevated privileges.

Windows terminology

Term Acronym Description
Discretionary access control list DACL The set of permissions on a given file, folder, registry key, network share or any other types of secured object in Windows. In case of files and folders stored on an NTFS disk, DACL is the set of NTFS permissions that says which user accounts or groups have which permissions.
System access control list SACL The set of auditing rules defined on a file, folder or other types of secured objects that support auditing.
Access control list ACL Refers to the whole set of security properties on a secured object (in our case, a file or folder), including the DACL, the SACL, the owner’s name, the integrity level and anything else that I might have missed.
Access control entry ACE Refers to an individual rule in a DACL or SACL.
Integrity level IL Also known as “mandatory label”, it is added in Windows Vista and is part of the DACL. But do not assume that what can copy DACL can also copy IL. Always investigate.
Owner Every secured object can have an owner. The user account defined as the owner of a securable object has complete access to the object regardless of its DACL. However, if Disk Quota feature is enabled, the size of the files on an NTFS volume are deduced from the owner’s quota. Normally, ownership can be taken over by a user who has Take Ownership permission in DACL. Administrators and Backup Operators, by default, can also transfer the ownership to another user account.

icACLs and Notepad

This section shows how you can use icACLs in Windows 7 to transfer DACL and IL. icACLs was first introduced in Windows Server 2003 Service Pack 2, when IL didn’t exist. However, I believe there is a good chance this method works with Windows Vista, Windows 8, Windows 8.1 and all their Windows Server siblings.

Do as follows:

  1. Open Command Prompt with administrative privileges.
  2. Navigate to a rather temporary folder in which you have write permission.
  3. Run the following command:icACLs "C:\Program Files" /save Perms.txt
  4. Open Perms.txt in Notepad
  5. Change the first line from “Program Files” to “Programs”. Be careful not to make any other changes.
  6. Save the file and exit.
  7. Run the following command:icACLs D:\ /restore Perms.txt

You can use /t switch with icACLs to save the permissions for all files and subfolders of the initial folder (in this example “Program Files”). Also please note that Program Files folder, by default, does not have an IL rule. But I am guessing system administrators would like to move permission on other folders as well, some of which may have IL rules.

Windows PowerShell

This section explain how to use PowerShell v4.0 to transfer DACL, SACL and object owner. This works on all versions of Windows that have or can have PowerShell v4.0, but I believe there is a good chance this works on PowerShell v2.0 and later.

PowerShell is readily equipped with Get-Acl and Set-Acl commands, which can be piped as follows:

Get-Acl -Path <Source file or folder> | Set-Acl -Path <Destination file or folder>

It tries to transfer all access control properties from the source file or folder to the destination file or folder. It works perfectly well for most of your ordinary files and folders. However, “Program Files” is another story. The following command:

Get-Acl -Path 'C:\Program Files' | Set-Acl -Path 'D:\Programs'

…when executed without admininstrative privileges in PowerShell v4.0, generates the following error message:

Set-Acl : Attempted to perform an unauthorized operation.
At line:1 char:36
+ Get-Acl -Path 'C:\Program Files' | Set-Acl -Path 'D:\Programs'
+                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (D:\Programs:String) [Set-Acl], UnauthorizedAccessException
    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.SetAclCommand

When executed with admininstrative privileges, it generates the following error message:

Set-Acl : The security identifier is not allowed to be the owner of this object.
At line:1 char:36
+ Get-Acl -Path 'C:\Program Files' | Set-Acl -Path 'D:\Programs'
+                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (D:\Programs:String) [Set-Acl], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.SetAclCommand

This is a natural outcome. Not every user account has the permission to modify every piece of ACL. Standard users have the right to transfer the DACL to a file or folder they own. So, the following code succeeds:

(Get-Item 'C:\Program Files').GetAccessControl("Access") | Set-Acl -Path 'D:\Programs'

Unfortunately, this commands does not seem to transfer the integrity level. In fact, it appears that .NET Framework deliberately avoids altering integrity levels. Native utilities like icalcs can do so, because they have access to Windows API.

Administrators can transfer SACLs, although by default, no such list is defined on “C:\Program Files”. So, this command succeeds when PowerShell is run with administrative privileges:

(Get-Item 'C:\Program Files').GetAccessControl("Audit") | Set-Acl -Path 'D:\Programs'

Administrators can also arbitrarily change ownership (“Owner”) to other users. But Program Files folder is owned by “NT SERVICE\TrustedInstaller” and Set-ACL seems not to be able to transfer it.

But why bother? Windows installs some of its components in “Program Files”; hence it needs free reign in it. This is not the case with a custom folder like “D:\Programs”.

Robocopy

Starting with Windows 2000, RoboCopy became a Windows component as the successor of the venerable XCopy. So, although this article does not cover using Robocopy, I thought a mention of honor is due. According to Microsoft Support article 323275 and Robocopy documentation on TechNet, Robocopy can transfer DACL, SACL and ownership data. The following command transfers DACL only:

Robocopy "C:\Program Files" "D:\Programs" /COPY:S /SECFIX

This method is not tested. So, the risk is entirely yours.

XCopy

I am told that the following command “works” but the term “works” is not defined; i.e. I have no clue as to what part of ACL it transfers:

xcopy "C:\Program Files" "D:\Programs" /T /E /I /H /K /X /Y

This method is not tested. So, the risk is entirely yours. But if you want to know what each switch means, I am reproducing the relevant parts of XCopy help page for your perusal.

Switch Description
/E Copies directories and subdirectories, including empty ones. Same as /S /E. May be used to modify /T.
/H Copies hidden and system files also.
/I If destination does not exist and copying more than one file, assumes that destination must be a directory.
/K Copies attributes. Normal Xcopy will reset read-only attributes.
/T Creates directory structure, but does not copy files. Does not include empty directories or subdirectories. /T /E includes empty directories and subdirectories.
/X Copies file audit settings (implies /O).
/Y Suppresses prompting to confirm you want to overwrite an existing destination file.
/O Copies file ownership and ACL information.
/S Copies directories and subdirectories except empty ones.
Advertisements

Posted on 13 March 2014, in Windows Administration and tagged , , , , , , , , , , , , , , , , , , . Bookmark the permalink. 4 Comments.

  1. Thank you for this. I stumbled upon it when looking to copy Program Files ACL to a new folder. Because I initially only skimmed over it I ran “Get-Acl -Path ‘C:\Program Files’ | Set-Acl -Path ‘D:\Programs'” and it worked for Powershell 5.0 B10586 (Windows 10). It even included the TrustedInstaller as owner.

  2. i was trying it for \\hostname\D$ to \\new-hostname\C$ how it will work between hosts.

    • It does not work. NTFS permissions are not visible over the network. Windows networks have their own permissions called SMB permissions. And they cannot be tweaked over the network as you are doing.

  3. The icacls method worked perfectly for me; thanks!

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: