Hey, Scripting Guy! Can I Remove Specific Folder Access Rights on a Per-User Basis?

Hey, Scripting Guy! Can I Remove Specific Folder Access Rights on a Per-User Basis?

  • Comments 2
  • Likes
Share this post:

Hey, Scripting Guy! QuestionHey, Scripting Guy! There is this guy at work…well, actually he used to be at work and that is the problem. He left the company. The way security has been implemented at our company, I have to check specific folders, and if a user has been granted explicit access rights to the folders, the entry needs to be removed. I know I could do this manually, but there are several folders and I would rather not waste the time doing this task if it could be scripted. Do you have a script that will do this for me?

-- SC

Hey, Scripting Guy! Answer Hello SC,

Microsoft Scripting Guy Ed Wilson here. It has seemed like fall weather here in Charlotte, North Carolina, in the United States this week. Gentle breezes have been nudging leaves from reluctant trees in my front yard, and the sky has been a dark blue dotted with white fluffy clouds. This is the first time in more than five years that I have been home to enjoy this time of the year. I am sifting through the e-mail that has been sent to scripter@microsoft.com, sipping on a cup of Earl Grey tea, and munching on a hunk of artisan cheese while listening to Vanessa-Mae on my Zune.  Needless to say, I am in one of the best moods I have been in a very long time. The reason that this is significant is because most of the time when I am confronted with a security type of question I say use either Subinacl or use Icacls. Because I am in a good mood, I am susceptible to suggestion. The script I came up with is similar to the script I wrote on Tuesday.

The complete RemoveUserSecurityFromFolder.ps1 script is seen here.

RemoveUserSecurityFromFolder.ps1

$user = 'nwtraders\bob'
$folders = "c:\fso","c:\fso1", "c:\fso2"
$acls = Get-Acl -path $folders
$outputObject = @()

Foreach($acl in $acls)
{
 $folder = (convert-path $acl.pspath)
 Write-Progress -act "Getting Security" -status "checking $folder" -percent ($i/ $folders.count*100)
 
  Foreach($access in $acl.access)
  {
    Foreach($value in $access.identityReference.Value)
     {
       if ($value -eq $user)
          {
           $acl.RemoveAccessRule($access) | Out-Null
          }
     } #end foreach value
  } # end foreach access
 Set-Acl -path $folder -aclObject $acl
$i++
} #end Foreach acl

The first thing that must be done in the RemoveUserSecurityFromFolder.ps1 script is to create a variable to hold the user name and the folders to be searched. The user name is expressed in the form of DomainName\UserName. Each folder path is a string that includes the full path to the folder. Multiple folders can be supplied as long as they are separated by commas. This is seen here:

$user = 'nwtraders\bob'

$folders = "c:\fso","c:\fso1", "c:\fso2"

As seen in the following image, the user nwtraders\bob has been granted specific rights to the C:\fso2 folder. He has also been granted specific rights to other folders. The RemoveUserSecurityFromFolder.ps1 script will be used to remove his access to the folders specified in the $folders array.

Image of specific user granted specific rights

After you have the user name and the folders to be searched, you use the Get-Acl Windows PowerShell cmdlet to return a collection of System.Security.AccessControl.DirectorySecurity objects. The DirectorySecurity objects are stored in the $acls variable. This is shown here:

$acls = Get-Acl -path $folders

Because you need to inspect individual access control entries, you will need to use the Foreach statement to walk through the collection of DirectorySecurity objects that are stored in the $acls variable. Each DirectorySecurity object will be stored in the $acl variable as you iterate through the collection. The Foreach statement is seen here:

Foreach($acl in $acls)

{

The path to the current folder is retrieved from the pspath property of the System.Security.AccessControl.DirectorySecurity .NET Framework class. The folder path is used in the status of the Write-Progress cmdlet, which displays a progress bar that informs the user of the status of removing the user from the folders. For more information about the use of Convert-Path or the Write-Progress cmdlet, see Tuesday’s Hey, Scripting Guy! post. The code is shown here:

$folder = (convert-path $acl.pspath)

 Write-Progress -act "Getting Security" -status "checking $folder" -percent ($i/ $folders.count*100)

It is time to walk through the individual access control entries. Because the user name that has been granted rights to a folder is stored in the value of the identityReference property of the System.Security.Principal.NTAccount .NET Framework class, it is necessary to somehow gain access to the NTAccount class.  To do this, each of the System.Security.AccessControl.FileSystemAccessRule .NET Framework classes that are returned by querying the access property of the DirectorySecurity object are queried. The Foreach statement is used to walk through the collection of FileSystemAccessRules as seen here:

  Foreach($access in $acl.access)

  {

After a specific FileSystemAccessRule has been obtained and stored in the $access variable, the NTAccount class is obtained by referencing the identityReference property.  The value contained in value property is stored in the $value variable as seen here:

    Foreach($value in $access.identityReference.Value)

     {

       if ($value -eq $user)

If the user matches the value of the identityReference property, the FileSystemAccessRule is removed from the System.Security.AccessControl.DirectorySecurity object. The information that is returned from the RemoveAccessRule method call is piped to the Out-Null cmdlet. This is shown here:

          {

           $acl.RemoveAccessRule($access) | Out-Null

          }

     } #end foreach value

  } # end foreach access

It is time to commit the changes to the DirectorySecurity object. If you do not use the Set-Acl cmdlet to write the changes to the DirectorySecurity object, the script will appear to work properly, but the user will not be removed from access to the folders. To commit the changes, you specify the folder and the aclObject. For this script, the path to the folder is contained in the $folder variable and the aclObject is the DirectorySecurity object that is stored in the $acl variable. This line of code is seen here:

 Set-Acl -path $folder -aclObject $acl

$i++

} #end Foreach acl

After the RemoveUserSecurityFromFolder.ps1 script has run, a quick inspection of the C:\fso2 folder reveals that nwtraders\bob has been removed. This is seen here:

Image of specific use removed from specific folder

 

Well, SC, that is all there is to removing a user’s access rights to a folder. I am glad you asked the question because the process was not nearly as difficult as I had believed. This brings us to the end of our Security Week posts. Join us tomorrow as we dig into the virtual mail bag for questions that do not need quite as long of an answer. That is right: Tomorrow is Quick-Hits Friday!

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, keep on scripting.

Ed Wilson and Craig Liebendorfer, Scripting Guys

fazpeux4s3 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • What if you wanted to remove all security?

  • Great post.. Great explanition!!