Windows permissions, as we all know, usually follow the rules of inheritance. Correctly configured, inheritance greatly simplifies the manual effort of permissioning a large file structure. With
Yet while inheritance is a great time-saver when configured correctly, it quickly becomes a nightmare when it isn't. That's the problem I discovered upon returning from vacation one fateful Monday morning.
Someone from our help desk had received a work order to change a permission in my folder structure's topmost level. Ignoring for the moment whether that permission change was truly necessary, in completing the request the unfortunate sap accidentally checked the box marked "Replace all child object permissions with inheritable permissions from this object." So as he clicked the Apply button, my exquisitely-designed permissions structure -- the one that protected multiple teams from each other, regular employees from executive-level correspondence, and exceptionally-sensitive project data from on-site contractors -- went away.
Everyone could now see everything.
It's a rookie mistake, but one with painful consequences. While I was gone, the rookie mistake-maker attempted to fix the problem by hurriedly (and incorrectly) resetting permissions directly throughout the folder structure. People lost access to their data. Other people found access to data they should never see. Catastrophe ensued.
Documentation saves the day
Fortunately, all wasn't necessarily lost. Unbeknownst to the rest of the IT team, I kept a personal document of the folder tree's complex structure in a separate Word document. Inside that document were the keys to fixing the problem and restoring order (and thus, regulatory compliance) back to this half-terabyte sized structure of Office documents.
But the even-more painful process, as I soon discovered, involved somehow transferring my Word document's configuration into actual permissions on the file server.
I'm sure you know this pain as well; it's the pain in the wrist you get from right-clicking folders, clicking multiple times through Windows GUI-based permissions configuration screens, and ultimately waiting as they apply. Let's face it: Microsoft's GUI-based tool works for this task, but they don't exactly work well.
It was not very far into my story's resolution that I experienced one of our industry's classic "there's got to be a better way" realizations. I found that better way with a little tool that's installed to every modern version of Microsoft Windows: Icacls.exe.
Using Icacls.exe, I was able to get around the limitations of the Windows GUI tools. From the command line, I could easily script together a fix for permissions and let it run on its own, without painfully clicking through every folder in the GUI.
I found that using Icacls, I was able to create a self-documenting system that tackles permissions through an auditable and automated fashion. You can create such a solution today with a simple batch file and a Windows scheduled task, and you'll be happy to know I'll be sharing that solution in my next article. But first, it's important to understand the basics of the Icacls syntax and how it works
Icacls syntax: The primer
To understand the Icacls syntax, you must first understand why Windows files and folders are permissioned the way they are. The structure is exceedingly complicated, but you really only need to learn a small portion of it to accomplish the vast majority of your daily permissioning tasks. I'll show you that small portion here.
Let's start with the easy stuff. In a folder structure, you already know that the primary three permissions you usually set are Read, Modify and Full Control. Other options are available, but these usually involve edge cases that you won't set very often. So for the purpose of simplicity, this example will focus only on these three permissions.
At first it appears relatively simple to set permissions on a file or folder using Icacls syntax. You need the location of that file or folder, the permission you want to set, and the user or group you want to set it to. Thus, you might think that if you wanted to grant the eloise user full control over the C:\Private folder, you would use:
icacls C:\Private /grant eloise:F
Seems easy, but there are a few oddball behaviors with this apparently simple syntax. First, all by itself the /grant switch adds the eloise user to the access control list (ACL) instead of replacing the ACL with eloise. If you want to replace the ACL granting only the eloise user permission, you need to add ":r" to /grant, like this:
icacls C:\Private /grant:r eloise:F
Here's where things get complicated. If you're playing along at home -- which you should be -- you may have tried this and noticed that the permissions on your C:\Private folder aren't what you thought they'd be. First of all, you'll see the eloise user in the list of group or user names. But instead of seeing any of the basic permissions (such as Full Control, in this case), you instead see a checkbox next to Special Permissions.
Huh? I thought we were granting eloise full control over this folder? Well, we are. But, this "full control" isn't the same as what the GUI considers to be the real full control.
What's missing is inheritance, and fully understanding this part of the conversation requires a bit more background. First, recognize that every element on a Windows disk is considered by Icacls to be either an object or a container. Files are objects, folders are containers, but files are never containers.
You also need to know that inheritance for containers is a component of the "basic permissions" that we think of as Modify or Full Control. You can't get the nice checkbox next to Modify in the GUI unless you also set that folder's inheritance. Anything else (such as "no inheritance") is considered a special permission.
Now back to the example. The Windows GUI doesn't consider a folder permission to be the "real" or "basic" full control unless it is full control plus inheritance on both objects and containers. That syntax looks like this:
icacls C:\Private /grant:r eloise:(OI)(CI)F
In the example above, (OI) stands for object inherit. Setting (OI) means that objects such as files that are inside this folder will inherit its permissions. As for (CI), that stands for container inherit. Setting (CI) will make folders inside this folder inherit its permission. This syntax fully sets what the Windows GUI considers to be the "basic permission" of full control.
Try it now. You'll see that the checkboxes you want are set in the GUI.
Icacls: The next step
With the syntax above, you now can directly set any basic permission -- R for Read, M for Modify, F for Full Control -- on a folder anywhere on your file server.
That's great, but how do you tackle the situation if you don't want inheritance? For example, maybe you have a top-level folder C:\Public that should be open to everyone. Every person in your company should have Modify access to this folder. But beneath this folder is a subfolder C:\Public\Private that only eloise should have access to. What do you do now?
One solution involves breaking inheritance.
Getting a bit more specific, you now want to grant Modify access to the Domain Users group on C:\Public. You want only eloise to have access to C:\Public\Private. Let's break this process down into its disparate steps, as we look at another important Icacls switch called /inheritance.
In order to grant the Domain Users group the modify permission on C:\Public, use the following syntax:
icacls C:\Public\ /grant:r "Domain Users":(OI)(CI)M
This is no different than what we did in the previous section. Still, while running this command solves the first problem, it creates a second one at the same time. The Domain Users group now has access to C:\Public, but it also has access to C:\Public\Private. That's because (OI)(CI) has enabled inheritance on all objects and containers below C:\Public. You need to break that inheritance, which you can do with /inheritance:r at the level of C:\Public\Private.
The /inheritance:r switch instructs Icacls to break the inheritance from the folder above. The ":r" in /inheritance:r at the same time removes any permissions the folder was getting from above. Essentially, with /inheritance:r, what you get is a completely empty ACL.
This is exceptionally powerful, but with an exceptionally important caveat: do not use this syntax:
icacls C:\Public\Private /inheritance:r
Using it would indeed break the C:\Public\Private folder's inheritance from C:\Public, but you would end up with a folder that didn't have any permissions at all. That's bad. A better solution is to break inheritance and, in the same command, reset the permissions to what you want. Use this syntax instead:
icacls C:\Public\Private /inheritance:r /grant:r eloise:(OI)(CI)M
Running this command accomplishes three things, all within the same command. First, it breaks the inheritance on C:\Public\Private from the folder above. Then, it clears the ACL completely. Finally, it adds eloise with the modify permission to the empty ACL.
As you can see, this command is powerful. With it and the other command we looked at in the section above, you'll be able to perform the vast majority of permissioning activities commonly done on your file servers. Icacls has a ridiculously large number of other switches that it can use, and you can discover what they are by entering Icacls by itself at the command line.
At this point, you now have nearly everything you need to create an auditable and automated permissions management solution with Icacls. All that's left is actually turning these individual commands into a full solution, which is the topic for my next article. Stay tuned.
ABOUT THE AUTHOR
Greg Shields, Microsoft MVP, is a partner at Concentrated Technology. Get more of Greg's Jack-of-all-Trades tips and tricks at www.ConcentratedTech.com.
This was first published in July 2010