none
Remove explicit permission to share RRS feed

  • Question

  • Hi

    I'm trying to remove explicit permissions from folders and file.  I have used this to list the explicit permissions

    Get-childitem '\\Server\d$\Path\to\Folder' -recurse |
    Get-Acl | % {
              $path = $_.Path
              $_.Access | % {
                       New-Object PSObject -Property @{
                                 Folder = $path.Replace("Microsoft.PowerShell.Core\FileSystem::", "")
                                 Access = $_.FileSystemRights
                                 Control = $_.AccessControlType
                                 User = $_.IdentityReference
                                 Inheritance = $_.IsInherited
                       }
              }
    } | ? { -not $_.Inheritance } | export-csv C:\temp\test_dump1.csv -force


    I thought this would modify it to remove instead of list the permissions.

    Get-childitem '\\Server\d$\Path\to\Folder' -recurse |
    Get-Acl | % {
              $path = $_.Path
              $_.Access | % {
                       New-Object PSObject -Property @{
                                 Folder = $path.Replace("Microsoft.PowerShell.Core\FileSystem::", "")
                                 Access = $_.FileSystemRights
                                 Control = $_.AccessControlType
                                 User = $_.IdentityReference
                                 Inheritance = $_.IsInherited
                       }
              }
    } | ? { -not $_.Inheritance } | $_.User.RemoveAccessRule($_.Access)

    but keep getting this:

    Remove-ExplicitPermissions.ps1 (30, 5): ERROR: At Line: 30 char: 5
    ERROR: + } | $_.User.RemoveAccessRule($_.Access)
    ERROR: +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ERROR: Expressions are only allowed as the first element of a pipeline.
    ERROR:     + CategoryInfo          : ParserError: (:) [], ParseException
    ERROR:     + FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
    ERROR:

    How do I use the New-Object to remove the permissions?

    Thanks
    Tony


    Monday, March 13, 2017 10:19 AM

Answers

  • Hi Tony,

    well ..... to put it bluntly, it won't work that way. Using a pipeline for this will require a lot of redesign, so ... here's an example:

    foreach ($path in (Get-childitem '\\Server\d$\Path\to\Folder' -recurse))
    {
    	$acl = Get-Acl $path
    	$changed = $false
    	foreach ($rule in $acl.Access)
    	{
    		if (-not $rule.IsInherited)
    		{
    			$acl.RemoveAccessRule($rule)
    			$changed = $true
    		}
    	}
    	
    	if ($changed) { Set-Acl -Path $path -AclObject $acl }
    }

    Key points:

    • Pipeline is not always the easiest path to go
    • Building custom objects will remove all methods the original object had
    • Try working with the Get-Member cmdlet, as this will show you what properties and methods an object has
    • If you don't commit the change back into the object with Set-Acl, you will only change things in memory without changing the actual acl - won't do you any good
    • Note how I only update permissions where changes occured

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Monday, March 13, 2017 12:42 PM

All replies

  • Hi Tony,

    well ..... to put it bluntly, it won't work that way. Using a pipeline for this will require a lot of redesign, so ... here's an example:

    foreach ($path in (Get-childitem '\\Server\d$\Path\to\Folder' -recurse))
    {
    	$acl = Get-Acl $path
    	$changed = $false
    	foreach ($rule in $acl.Access)
    	{
    		if (-not $rule.IsInherited)
    		{
    			$acl.RemoveAccessRule($rule)
    			$changed = $true
    		}
    	}
    	
    	if ($changed) { Set-Acl -Path $path -AclObject $acl }
    }

    Key points:

    • Pipeline is not always the easiest path to go
    • Building custom objects will remove all methods the original object had
    • Try working with the Get-Member cmdlet, as this will show you what properties and methods an object has
    • If you don't commit the change back into the object with Set-Acl, you will only change things in memory without changing the actual acl - won't do you any good
    • Note how I only update permissions where changes occured

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Monday, March 13, 2017 12:42 PM
  • Thanks Fred, with a slight modification that worked.

    foreach ($path in (Get-childitem '\\Server\D$\Path\to\Folder' -recurse))
    {
    	$acl = Get-Acl $path.FullName
    	$changed = $false
    	foreach ($rule in $acl.Access)
    	{
    		if (-not $rule.IsInherited)
    		{
    			$acl.RemoveAccessRule($rule)
    			$changed = $true
    		}
    	}
    	
    	if ($changed)
    	{
    		# If you don't commit the change back into the object with Set-Acl, you will only change things in memory without changing the actual acl - won't do you any good
    		Set-Acl -Path $path.FullName -AclObject $acl
    	}
    }

    Had to change $Path to $Path.fullname

    Cheers
    Tony


    Monday, March 13, 2017 2:04 PM
  • Some useful pipeline mechanics or how to use a filter to save the current pipeline object.

    # setting selected ACLs in a pipeline
    
    # filter function to store a selected acl
    # for use later in the pipeline. Only the current ACL
    # is retained
    filter Set-GVar {
    	$global:acl = $_
    	$_
    }
    
    #Changed ACLs are displayed
    Get-childitem d:\test -recurse | 
    	Get-Acl  |
    	Set-GVar |
    	Select -expand Access |
    	?{-not $_.IsInherited} |
    	%{$acl.RemoveAccessRule($_)} |
    	%{$acl} |
    	sort path -Unique | 
    	Set-Acl -PassThru -Whatif}

    Remove "whatif" to get ACL output.

    This allows for a more fluid, declarative approach to a problem.


    \_(ツ)_/

    • Edited by jrv Monday, March 13, 2017 4:17 PM
    Monday, March 13, 2017 3:52 PM
  • More pipeline mechanics.

    For WMF 4 and later

    #Changed ACLs are displayed
    Get-childitem d:\test -recurse |
    	Get-Acl -PipelineVariable p_acl |
    	Select -Expand Access |
    	?{ -not $_.IsInherited } |
    	%{ $p_acl.RemoveAccessRule($_) } |
    	%{ $p_acl } |
    	sort path -Unique |
    	Set-Acl -Passthru -WhatIf
    Setting pipeline variables does the same thing we used filters for in earlier versions of PowerShell.


    \_(ツ)_/




    • Edited by jrv Monday, March 13, 2017 4:19 PM
    Monday, March 13, 2017 4:11 PM