Restore NTFS Security Permissions by Using PowerShell

Restore NTFS Security Permissions by Using PowerShell

  • Comments 9
  • Likes

Summary: Superhero BATCHman restores NTFS security permissions using Windows PowerShell.

 

Microsoft Scripting Guy Ed Wilson here. Well, it is time once again for BATCHman. This time, it is Episode 12. Take it away, Sean.

When the digital crash
In a blink and a splash
A gleam in the night
To make all wrongs right
Our heroes fly out
And there is no doubt
That evil will fall true
At the sight of the blue

The one and only .NET duo—BATCHman and Cmdlet.

 

It’s a nice morning. BATCHman is playing with a new test module he has been encoding to stop criminals directly with Windows PowerShell. “BATCHpause” is what he is going to call it (patent pending patent pending). Cmdlet has just walked in from his early morning session of watching Electric Company reruns when off in the corner a large blue phone begins flashing.

“It’s the BATCHphone!” BATCHman leaps through the air pommelling poor Cmdlet in the process just to answer it.

Cmdlets staggers to his feet. “Mmmmmphphh…you know…*ugh*…there was an extension right beside you? *urrgghhh*”

“Wouldn’t have been as dramatic!” BATCHman responded as he picked up the phone. “Hello, BATCHman here!”

“BATCHman! I need your help now.” It was the principal at Redmond High School “Nobody can access their home drives! Little Johnny was trying to “help” the school administrator and somehow locked us out of our personal drives! Help us BATCHman!”

BATCHman knew only ONE thing could stop a problem like this, and only one duo. Quickly tossing Cmdlet an ice pack and a box of aspirin, he began to announce, “Cmdlet to the…”

Cmdlet staggered to his feet, ice pack in hand. “Yes, to the WinMobile. I know, I know”

“Actually, my good chum, I was going to use the new vehicle, the BATCHmobile. It’s powered by WP7 with Mango! The WinMobile needed an update.”

“Cooool!” burst out Cmdlet, forgetting his concussion. Leaping into the air, he landed on the new BATCHmobile, doing a triple flip as he landed.

“New Gorilla Glass,” muttered BATCHman. “Very smooth,” as they fired off into the city.

Moments later they arrive upon a scene that was absolute chaos.

“I can’t access my homework!”

“My locker combination is locked away from me!”

“I can’t see who I was supposed to have on detention!”

The entire high school had been turned into a zoo! (Or more of a zoo than usual anyway.)

The principal, disheveled and worn, is marching down the hall with scraggly-haired youth wearing a combination lock about his neck, and held by the collar, presenting him to the BATCHman.

“THIS! THIS caused all of the trouble! Little Johnny Loc…”

“Stand back, puny creature!” it barked out “I am the Locksmith, the newest member of the V.I.T. program. The world will bow before me! Buah ha ha ha haaaa!”

BATCHman scratched his head. “V.I.T.?”

“’Villains In Training!” announced The Locksmith. “Of course, I’m the first, but there will be more!” and he waved his “Official VIT” card written in crayon, feigning his invisible and useless villainy powers to the world.

Cmdlet shook his head. “A waste of good crayon, if you ask me.”

Undeterred BATCHman pressed on. “So no access to home folders? Please. Lock our little friend here into detention for the moment while we examine the issue.”

Accessing a server with the home folder structure, our hero checked the folders but found he could access them. “Hmmmm,” a puzzled look crossed over his face. He ran the following command on a user’s folder the check the NTFS rights.

$SecurityRights=GET-ACL E:\Home\Student542

Cmdlet looked over “Whatcha’ doin’?

BATCHman nearly forgot his experience in Windows PowerShell was a little more advanced. “I am using Get-ACL on a folder to see what the NTFS rights are. I suspect our little fiend has removed the access to the individual users.”

Scratching his eyeball, the sidekick wondered. “How did you guess that so easily?”

“Well,” the Tilley-hatted one continued, “usually if the user cannot access the files but the administrator can, it’s a rights problem. We can verify this by running Get-Member against the $SecurityRights object we just created to see the available methods.”

Image of available methods

“I see near the very top that there is a property called Access, so if I type this, I can see the various groups able to access this object.”

$SecurityRights.Access

Practicing origami on his arms, Cmdlet stretched and then blurted out. “Hang on one sec. How did you know to use that and without browsing, how did you come to that conclusion?”

“In answer to your first question, I could say I used msdn.com and pulled up details on SYSTEM.SECURITY.ACCESSCONTROL, but the honest answer is I just plugged in values in the BATCHcave to learn what they might contain.”

Reasonable, thought Cmdlet. You can use research but sometimes just “playing about” produces the answer. “And the second?”

“There’s a note here on the desk: ‘I can browse these folders as administrator. !?#$?!%%$ Why isn’t anything working? ARGGGGHHH!!! $$#@@@?’”

“And they bothered to write the asterisk and punctuation marks?”

“Meh,” shrugged BATCHman. “So if you see the list presented on this folder under the HOME$ share called STUDENT542, you’ll see it is in fact missing access for the student.”

$SecurityRights.Access

“Now what I need to see is the normal permissions assigned when a home folder is created on this system, to see what’s missing exactly on a normal home drive for NTFS permissions.”

BATCHman created a temporary student in Active Directory with an appropriate 752-character long password. He then applied the settings for a home folder and noted the differences when running Get-ACL again on the new home folder.

$NewUserSecurity=GET-ACL C:\Home\Student160

$NewUserSecurity.Access

“Aha! As I suspected, we merely need to add the rights that a UserID would normally have on its own home drive. Now, I just need to find a script to do this.” BATCHman quickly queries the TechNet Script Center.

Cmdlet paused “You don’t know everything? But you’re…you’re BATCHman!” his jaw dropped to the ground like a child being told he couldn’t play Kinect for another three hours.

“True little buddy. I am skilled, but sometimes the ability to say ‘I don’t know’ is an even greater power. In these cases, I do know how to leverage many online resources for Wndows PowerShell such as the Hey, Scripting Guy! Blog, online MSDN articles, and community support.”

BATCHman searched and found something on the Script Repository.

“Aha! The power of online resources!” he exclaimed referencing a Windows PowerShell Tip of the Week on the TechNet Script Center.

Reading the instructions, he defined the various variables needed, explaining it all to Cmdlet as he went along.

“So our challenge is we must create a .NET object for access control. It comprises several additional objects. All of them are represented in the view of any of the access lists we just saw. We’ll use one of the access rules that is missing.”

“We start by getting the permissions on the folder in question.”

$Access=GET-ACL E:\Home\Student169

“First, we will specify the type of access for the file or folder.”

$FileSystemRights=[System.Security.AccessControl.FileSystemRights]"FullControl"

“Next, we are setting whether this right is allowed or denied.”

$AccessControlType =[System.Security.AccessControl.AccessControlType]"Allow"

“Next, we’re going to specify whether particular access control will inherit rights and how these rights propagate to child objects in a directory or files.”

$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"None"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"None"

“Finally we need to specify the user or group they will apply to. In our case, this will be a UserID in Active Directory. It will be in the format of “REDMONDHD\UserId.”

$IdentityReference=’REDMONDHS\STUDENT169”

“Sounds like you’ve encountered this once before BATCHman,” Cmdlet noted.

He shrugged. “I goofed one day. Before I was the BATCHman I once worked in a large network. I made a mistake. I learned,” he said grinning sheepishly.

“Next we build the FileSystemAccessRule object.”

$FileSystemAccessRule= = New-Object System.Security.AccessControl.FileSystemAccessRule ($IdentityReference, $FileSystemrRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)

“Then finally we set the new Access rule in place.”

$Access.AddAccessRule($FileSystemAccessRule)

SET-ACL E:\HOME\Student169 $Access

Cmdlet thought. “So it looks like we’ll need to run a second Set-ACL because we have two permissions I see missing. Can I try setting those variables? I think I see the pattern they have to follow.”

Cmdlet looked at the other permission that would have been missing.

$FileSystemRights=[System.Security.AccessControl.FileSystemRights]"268435456"
$AccessControlType =[System.Security.AccessControl.AccessControlType]"Allow"
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"InheritOnly"
$IdentityReference=’REDMONDHS\STUDENT169”

“Dead on the nose, Cmdlet! Now, quick! We have the answer. Because each folder name is the same as a UserID, we can leverage that. We’ll use Get-ChildItem, grab the FolderName, and build the username from that, applying the security as we go along.”

$HomeFolders=GET-CHILDITEM E:\HOME

Foreach ( $Folder in $HomeFolders )
{
$Username=’REDMONDHS\’+$Folder.Name

$Access=GET-ACL $Folder

$FileSystemRights=[System.Security.AccessControl.FileSystemRights]"268435456"
$AccessControlType =[System.Security.AccessControl.AccessControlType]"Allow"
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"InheritOnly"
$IdentityReference=$Username

$FileSystemAccessRule= = New-Object System.Security.AccessControl.FileSystemAccessRule ($IdentityReference, $FileSystemrRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)

$Access.AddAccessRule($FileSystemAccessRule)

SET-ACL $Folder $Access

$FileSystemRights=[System.Security.AccessControl.FileSystemRights]"FullControl"
$AccessControlType =[System.Security.AccessControl.AccessControlType]"Allow"
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"None"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"None"

$FileSystemAccessRule= = New-Object System.Security.AccessControl.FileSystemAccessRule ($IdentityReference, $FileSystemrRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)

$Access.AddAccessRule($FileSystemAccessRule)

SET-ACL $Folder $Access

}

 

They quickly ran the script on the thousands of user folders on the server. Moments later, peace was restored. Flustered and happy, the principal quickly thanked BATCHman and Cmdlet. Too busy with a zoo full of kids, he had to head straight back to work.

Moments later, they were back in the BATCHcave. A long month of crime fighting, BATCHman sat back to relax. Cmdlet was playing on the computer with Windows PowerShell and a new strange toy.

“Hey, little buddy, that looks cool! What are you playing with?”

“A used teleporter I picked up on eBay. It came with a very early alpha version of a Windows PowerShell module. It’s pretty cool and I…”

BATCHman had only just looked over Cmdlet’s shoulder when he burst out “No. You didn’t—wait…”, seeing the one-liner before they vanished into the night.

GET-PERSON –name ‘BATCHman’,’Cmdlet’ | INVOKE-TELEPORT –random

 

BATCHman and Cmdlet have left the building. I want to thank Sean Kearney for writing a tremendous series of fun, entertaining, and educational articles. Tomorrow, I begin a week of random topics that should be quite interesting.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hey BATCHman,

    that's pretty cool!

    We can do everything with Powershell!!

    Even adjust the filesystem rights!!!

    But ... this involves using the appropriate .NET classes and this is a bit tedious :-(

    This time I would prefer the simple cacls.exe or maybe xcacls.exe if available!

    It's "just" commandline stuff but short, quick and reliable.

    The Powershell team should definitely consider reengineering the get-acl command or better

    introduce more effective and straight Cmdlets.

    Klaus

  • @Klaus

    Now of course, knowing the solution, we can build an Advanced Function as well to make this far easier.   As for how this can be improved in Powershell?

    ...Who knows what the future holds in store... :)

    The BATCHman

  • What? Super PosH.  

    Can it really be any better than this?

  • When did powershell tips turn into 99% nonsense with a glimmer of useful content?

    Can we get back on topic? or is this what we've come to?

  • Very good - just a type in all the 3 constructor lines = $FileSystemrRights.

    Pete

  • @jrv There is always room for improvement :)

    @justsayin You did notice our friends "vanished" ?  I suspect normality (or some semblance of it) shall return soon ;)

    @pete Did you mean there was a typo?

    BATCHman

  • @pete Ahhhh! THAT typo! Too many 'r' .  Must have had "Talk like a Pirate Day' on the brain :)

    Rrrrrrrrrrrrrrr

    BATCHman

  • I agree with Just Saying...  please keep on point.

  • Thank you for the valuable post. On the other hand I suppose kindergarten style in documentation is wasting time of readers as well as the author.