3

I wish to remove a user from folder permissions using PowerShell. I have found plenty of examples on how to remove the user permissions but I actually want to remove the user entirely.

The equivalent would be to the do the following in Windows Explorer: 1. Right click folder and select Properties. 2. Click Security tab 3. Click Edit 4. Highlight user or group. 5. Click Remove

It is the clicking of remove that I'm trying to mimic in PowerShell.

Thanks in advance.

Simon Darlow
  • 129
  • 1
  • 1
  • 4
  • Can you link to an example of the powershell scripts you are finding that somehow remove access, but aren't removing the associated access control entry (ACE)? Are you sure that you are using them correctly, with considerations to how the inheritance might need to apply to your ACLs? – Zoredache Feb 21 '17 at 23:18
  • BTW you might want to look at using one of the modules for dealing with ACLs in powershell [NTFSSecurity](https://www.powershellgallery.com/packages/NTFSSecurity/4.2.3) is somewhat popular, – Zoredache Feb 21 '17 at 23:20

5 Answers5

4

As Simon suggested, the following commands will achieve what you're looking for to just remove a specific user or group.

Using the NTFSSecurity module (https://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85)

Remove-NTFSAccess -AccessRights FullControl -Account DOMAIN\Group -Path c:\temp -AccessType Deny -AppliesTo ThisFolderSubfoldersAndFiles
Remove-NTFSAccess -AccessRights FullControl -Account DOMAIN\Group -Path c:\temp -AccessType Allow -AppliesTo ThisFolderSubfoldersAndFiles

I wrote a little script to remove all security groups from a folder except groups I explicitly excluded.

$path = "C:\Path\To\Folder"
$users = @{}

$users = Get-NTFSAccess $path | Where-Object {$_.Account -ne "DOMAIN\Exclude"} | Select-Object Account

foreach ($user in $users) {
    $removalAccount = $user.Account
    Write-Host "Removing account - $($removalAccount)"
    Remove-NTFSAccess -Path $path -Account $removalAccount -AccessRights FullControl -AccessType Allow
    Remove-NTFSAccess -Path $path -Account $removalAccount -AccessRights FullControl -AccessType Deny    
}
Brandon
  • 41
  • 3
3

Generally speaking, a combination of Get-Acl and Set-Acl should be able to accomplish what you need. However, Get-Acl has an annoying limitation that can manifest as being unable to write the modified ACL back using Set-Acl due to insufficient permissions (unless you have rights to also change ownership). More info on that problem can be found in this SO question.

In any case, for filesystem permissions you can work around Get-Acl's limitation by using a method from the object returned by Get-Item instead.

$acl = (Get-Item C:\myfolder).GetAccessControl('Access')

If you examine the $acl.Access property of the returned object, you'll find that it's a collection of FileSystemAccessRule objects (a.k.a. ACE objects). Ultimately, you want to find the subset of those ACEs that match the user you're trying to remove and also ignore any that are inherited. You can't actually remove inherited ACEs and even Windows Explorer will tell you as much if you try and remove them using the GUI. In any case, here's how you might get that subset of ACEs.

$acesToRemove = $acl.Access | ?{ $_.IsInherited -eq $false -and $_.IdentityReference -eq 'MYCOMPUTER\myuser' }

Now that you have the ACEs to remove, you just need to remove them from your original ACL and write it back to the folder.

$acl.RemoveAccessRuleAll($acesToRemove)
Set-Acl -AclObject $acl C:\myfolder\
Ryan Bolger
  • 16,755
  • 4
  • 42
  • 64
  • I did try the above two but was getting an error that $acesToRemove was null. – Simon Darlow Feb 22 '17 at 00:38
  • That just means the filter against the original Access list was either wrong or didn't actually have any non-inherited permissions. – Ryan Bolger Feb 22 '17 at 06:26
  • Glad you got it working anyway. – Ryan Bolger Feb 22 '17 at 06:26
  • 1
    NB: For the above to work `$acesToRemove` has to be exactly 1 record. It may be better to put a loop over it (`foreach ($removeMe in $acesToRemove) {$acl.RemoveAccessRuleAll($removeMe)}`) to avoid issues where 0 or multiple results are returned – JohnLBevan Feb 16 '23 at 16:49
  • With a name like `RemoveAccessRuleAll`, you'd think it could take multiple, but you're right. The [docs](https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.directoryobjectsecurity.removeaccessruleall) make it more clear why. It is not actually removing the explicit ACE that you pass, it's removing all ACEs that match the SID of the ACE you pass. So for the purposes of this question, it's probably sufficient to just add a `Select -First 1` after the where clause. – Ryan Bolger Feb 17 '23 at 01:11
1

This function that I created will invoke the scriptBlock for you on the target machine to remove the permissions for a user.

function Remove-OGRemoteACL (){
<#
.SYNOPSIS
Invoke a script block on a target to remove ACL permissions

.DESCRIPTION
Invoke a script block on a target to change ACL permissions to remove the crazy delay GET-ACL can encounter.

.PARAMETER serverFQDN
the server that the script block is run on

.PARAMETER remotePath
the UNC path of the share to remove the permisions for the user from.

.PARAMETER userName
the user name of the domain user.

.EXAMPLE
Remove-OGRemoteACL -serverFQDN "bigserver.awesomedomain.net" -remotePath "\\bigserver.awesomedomain.net\my\amazingShare" -userName "awesomedomain\myuser"

.NOTES
    Name:       Remove-OGRemoteACL
    Author:     Richie Schuster - SCCMOG.com
    GitHub:     https://github.com/SCCMOG/PS.SCCMOG.TOOLS
    Website:    https://www.sccmog.com
    Contact:    @RichieJSY
    Created:    2023-03-14
    Updated:    -

    Version history:
    1.0.0 - 2023-03-14 Function Created
#>
[cmdletbinding()]
param (
    [parameter(Mandatory=$True,ValueFromPipeline=$true,Position=0)]
    [string]$serverFQDN,
    [parameter(Mandatory=$True,ValueFromPipeline=$true,Position=1)]
    [string]$remotePath,
    [parameter(Mandatory=$True,ValueFromPipeline=$true,Position=2)]
    [string]$userName
)
try{
    Write-Verbose "Invoking ACL removal commmand [Server: $($serverFQDN)] [userName: $($userName)] [Server: $($remotePath)]"
    Invoke-Command -ComputerName "$($serverFQDN)" -ScriptBlock { 
        $acl = Get-Acl $using:remotePath
        $userPrincipal = New-Object System.Security.Principal.Ntaccount("$using:userName")
        $acl.PurgeAccessRules($userPrincipal)
        $acl | Set-Acl $using:remotePath
    }
    Write-Verbose "Success invoking ACL removal commmand [Server: $($serverFQDN)] [userName: $($userName)] [Server: $($remotePath)]"
}
catch{
    Write-Error "Error - Failed invoking ACL removal commmand [Server: $($serverFQDN)] [userName: $($userName)] [Server: $($remotePath)]. Error: $($_.Exception.Message)"
}

}

Example:

Remove-OGRemoteACL -serverFQDN "bigserver.awesomedomain.net" -remotePath "\\bigserver.awesomedomain.net\my\amazingShare" -userName "awesomedomain\myuser" -Verbose
SCCMOG
  • 11
  • 2
0

After some tests, I'd say that there's no need to use an external module for this matter.

As you can read here: https://blog.netwrix.com/2018/04/18/how-to-manage-file-system-acls-with-powershell-scripts/

You can use the method "PurgeAccessRules" to remove all right rules of a user or group. Code:

$acl = Get-Acl C:\MyFolder
$usersid = New-Object System.Security.Principal.Ntaccount("DOMAIN\Group")
$acl.PurgeAccessRules($usersid)
$acl | Set-Acl C:\MyFolder
-1

I have managed to get this working using the NTFSSecurity module that zoredache recommended.

Remove-NTFSAccess -AccessRights FullControl -Account DOMAIN\Group -Path c:\temp -AccessType Deny -AppliesTo ThisFolderSubfoldersAndFiles
Remove-NTFSAccess -AccessRights FullControl -Account DOMAIN\Group -Path c:\temp -AccessType Allow -AppliesTo ThisFolderSubfoldersAndFiles

The above two commands have stripped out all the security and the user/group has disappeared from permissions list. I will likely do more investigation to see if this can be streamlined but it does exactly what i need.

Thanks for your help.

Simon Darlow
  • 129
  • 1
  • 1
  • 4