Functions/Revoke-Permission.ps1
# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. function Revoke-Permission { <# .SYNOPSIS Revokes *explicit* permissions on a file, directory, registry key, or certificate's private key/key container. .DESCRIPTION Revokes all of an identity's *explicit* permissions on a file, directory, registry key, or certificate's private key/key container. Only explicit permissions are considered; inherited permissions are ignored. If the identity doesn't have permission, nothing happens, not even errors written out. .LINK Carbon_Permission .LINK Disable-AclInheritance .LINK Enable-AclInheritance .LINK Get-Permission .LINK Grant-Permission .LINK Test-Permission .EXAMPLE Revoke-Permission -Identity ENTERPRISE\Engineers -Path 'C:\EngineRoom' Demonstrates how to revoke all of the 'Engineers' permissions on the `C:\EngineRoom` directory. .EXAMPLE Revoke-Permission -Identity ENTERPRISE\Interns -Path 'hklm:\system\WarpDrive' Demonstrates how to revoke permission on a registry key. .EXAMPLE Revoke-Permission -Identity ENTERPRISE\Officers -Path 'cert:\LocalMachine\My\1234567890ABCDEF1234567890ABCDEF12345678' Demonstrates how to revoke the Officers' permission to the `cert:\LocalMachine\My\1234567890ABCDEF1234567890ABCDEF12345678` certificate's private key/key container. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [Parameter(Mandatory=$true)] [string] # The path on which the permissions should be revoked. Can be a file system, registry, or certificate path. $Path, [Parameter(Mandatory=$true)] [string] # The identity losing permissions. $Identity ) Set-StrictMode -Version 'Latest' Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState $Path = Resolve-Path -Path $Path if( -not $Path ) { return } $providerName = Get-PathProvider -Path $Path | Select-Object -ExpandProperty 'Name' if( $providerName -eq 'Certificate' ) { $providerName = 'CryptoKey' } $rulesToRemove = Get-Permission -Path $Path -Identity $Identity if( $rulesToRemove ) { $Identity = Resolve-IdentityName -Name $Identity $rulesToRemove | ForEach-Object { Write-Verbose ('[{0}] [{1}] {2} -> ' -f $Path,$Identity,$_."$($providerName)Rights") } Get-Item $Path -Force | ForEach-Object { if( $_.PSProvider.Name -eq 'Certificate' ) { [Security.Cryptography.X509Certificates.X509Certificate2]$certificate = $_ [Security.AccessControl.CryptoKeySecurity]$keySecurity = $certificate.PrivateKey.CspKeyContainerInfo.CryptoKeySecurity $rulesToRemove | ForEach-Object { [void] $keySecurity.RemoveAccessRule($_) } Set-CryptoKeySecurity -Certificate $certificate -CryptoKeySecurity $keySecurity -Action ('revoke {0}''s permissions' -f $Identity) } else { # We don't use Get-Acl because it returns the whole security descriptor, which includes owner information. # When passed to Set-Acl, this causes intermittent errors. So, we just grab the ACL portion of the security descriptor. # See http://www.bilalaslam.com/2010/12/14/powershell-workaround-for-the-security-identifier-is-not-allowed-to-be-the-owner-of-this-object-with-set-acl/ $currentAcl = $_.GetAccessControl('Access') $rulesToRemove | ForEach-Object { [void]$currentAcl.RemoveAccessRule($_) } if( $PSCmdlet.ShouldProcess( $Path, ('revoke {0}''s permissions' -f $Identity)) ) { Set-Acl -Path $Path -AclObject $currentAcl } } } } } |