Author Posts

May 22, 2013 at 1:17 pm

I have a network drive that I am repairing NTFS permissions on due to poor management by my predecessor.
One of the steps is to reset the inheritance for all the subfolders/files of folders listed in a text file. I have this PS2 script:

`
$badFolders = "c:\badfolders.txt"

ForEach($location in (Get-Content $badFolders))
{
get-childitem -r $location | foreach{
     $tempLocation = $_.FullName; 
	 $tempLocation = [Management.Automation.WildcardPattern]::Escape($tempLocation);
	 
     #Get ACL for tempLocation;
     $acl = get-acl $tempLocation;
     
	 # set access rule protection to remove inheritance and do not copy to subfolders
	 $acl.SetAccessRuleProtection($true,$false) 
	 set-acl $tempLocation -aclobject $acl 
	 
	 # set access rule protection to add inheritance
     $acl.SetAccessRuleProtection($false,$false)
	 set-acl $tempLocation -aclobject $acl
	 $templocation
}
}
`

This is working well until it hits a file that has a bracket in the filename (filename[1].doc for example). for each file, the error returned is:

`
At D:\Powershell\FolderPermissions\!3Reset_Inheritance_recurse.ps1:13 char:31
+      $acl.SetAccessRuleProtection < <<< ($true,$false) 
    + CategoryInfo          : InvalidOperation: (SetAccessRuleProtection:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
At D:\Powershell\FolderPermissions\!3Reset_Inheritance_recurse.ps1:14 char:35
+      set-acl $tempLocation -aclobject <<<<  $acl 
    + CategoryInfo          : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclComma 
   nd
`

I found 2 different aritcles other places that are for similar issues, but I cannot get them to apply properly to my script.
http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/e436c4e6-a88d-417d-bdea-94d0a77d94e3/
http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/d1e41504-c306-4109-8d2d-edc5930798d7

What am I missing?

May 23, 2013 at 4:18 am

Is it possible for you to try your script using PowerShell 3.0 instead? IIRC there were a few fixes wrt square brackets in filenames in PowerShell 3.0.

May 23, 2013 at 7:04 am

I ran it under PS 3.0, and I still get the error:

`You cannot call a method on a null-valued expression.
At D:\Powershell\FolderPermissions\!3Reset_Inheritance_recurse.ps1:13 char:3
+      $acl.SetAccessRuleProtection($true,$false)
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull
 
Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
At D:\Powershell\FolderPermissions\!3Reset_Inheritance_recurse.ps1:14 char:36
+      set-acl $tempLocation -aclobject $acl
+                                       ~~~~
    + CategoryInfo          : InvalidData: (:) [Set-Acl], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand`

May 23, 2013 at 8:10 am

Oh, that's helpful. You missed the first line of your first error in the copy/paste in the original post. The first error tells you that $acl is null when you try to invoke a method on it. So, the problem/challenge is in getting Get-Acl to return the Acl for a file with a square bracket in the name. You can do that like this:

'Boo' | Out-File 'C:\File`[1`].txt'
Get-Acl -LiteralPath 'C:\File`[1`].txt'

So the trick you didn't know before is that when you have square brackets in a filename, you need to escape them with a backtick in order for the PowerShell cmdlets to work with them as expected.

May 23, 2013 at 10:11 am

Thanks, Poshoholic!

After I upgraded to PS 3.0, I revisited one of the forums that I had looked at before.
The Set-ACL in PS3 allows the use of the -LiteralPath switch, which you also included in your above example.

In my case, I am not referring to a file with Brackets in the filename explicitly, but instead it is found during a get-childitem search, so I cannot escape them out with a backtick.

However, simply adding the -LiteralPath switch to Set-Acl has taken care of the problem.

Here is my new version of the code, for use with PS 3.0:

`$badFolders = "d:\Powershell\FolderPermissions\badfolders.txt"

ForEach($location in (Get-Content $badFolders))
{
#takeown /F $location /R /A /D Y
#Search recursivly through location defined;
get-childitem -r $location | foreach{
     $tempLocation = $_.FullName;
     #Get ACL for tempLocation;
     $acl = get-acl -LiteralPath $tempLocation;
     
	 # set access ruile protection to remove inheritance and do not copy to subfolders
	 $acl.SetAccessRuleProtection($true,$false) 
	 set-acl -aclobject $acl -LiteralPath $tempLocation
	 
	 # set access rule protection to add inheritance
     $acl.SetAccessRuleProtection($false,$false)
	 set-acl -aclobject $acl -LiteralPath $tempLocation
	 $templocation
}
}`

I am not seeing a way to provide a Best Answer credit for you, unfortunately!

Thanks, again!

May 23, 2013 at 10:39 am

Excellent. I'm glad you worked it out, and thanks for sharing the final version of your script for others!