Set-ACL fails on [ in filename

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?

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.

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: (:slight_smile: , 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: (:slight_smile: [Set-Acl], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.SetAclCommand`

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.

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!

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