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.
There are more than one ways:
- Via icACLs and Notepad
- Via Windows PowerShell
- Via XCopy
- 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.
|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:
- Open Command Prompt with administrative privileges.
- Navigate to a rather temporary folder in which you have write permission.
- Run the following command:
icACLs "C:\Program Files" /save Perms.txt
- Open Perms.txt in Notepad
- Change the first line from “Program Files” to “Programs”. Be careful not to make any other changes.
- Save the file and exit.
- 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.
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.
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”.
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.
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.
|/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.|
Posted on 13 March 2014, in Windows Administration and tagged .NET Framework, ACE, ACL, administrative privileges, DACL, Get-Acl, icacls, IL, Notepad, NTFS, permission, Powershell, Program Files, robocopy, SACL, Set-Acl, TrustedInstaller, Windows PowerShell, xcopy. Bookmark the permalink. 4 Comments.