Set-ACL fails on [ in filename

Tagged: , ,

This topic contains 5 replies, has 2 voices, and was last updated by Profile photo of Poshoholic Poshoholic 3 years, 11 months ago.

  • Author
    Posts
  • #6840
    Profile photo of Dan Draeger
    Dan Draeger
    Participant

    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?

  • #6863
    Profile photo of Poshoholic
    Poshoholic
    Member

    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.

  • #6874
    Profile photo of Dan Draeger
    Dan Draeger
    Participant

    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`
  • #6881
    Profile photo of Poshoholic
    Poshoholic
    Member

    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.

  • #6894
    Profile photo of Dan Draeger
    Dan Draeger
    Participant

    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!

  • #6895
    Profile photo of Poshoholic
    Poshoholic
    Member

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

You must be logged in to reply to this topic.