When managing user transitions between full-time employment and contractor status, one critical task is auditing and modifying their existing NTFS permissions. The native Windows tools like cacls
or icacls
don't provide an easy way to filter permissions by username across an entire directory structure.
Here's a PowerShell script that recursively scans directories and outputs permissions for a specific user:
function Get-UserPermissions {
param (
[string]$RootPath,
[string]$UserName
)
$aclList = @()
$dirs = Get-ChildItem -Path $RootPath -Recurse -Directory
foreach ($dir in $dirs) {
$acl = Get-Acl -Path $dir.FullName
foreach ($access in $acl.Access) {
if ($access.IdentityReference -like "*$UserName*") {
$aclList += [PSCustomObject]@{
Path = $dir.FullName
User = $access.IdentityReference
Permission = $access.FileSystemRights
AccessType = $access.AccessControlType
Inheritance = $access.IsInherited
}
}
}
}
return $aclList
}
# Example usage:
$userPermissions = Get-UserPermissions -RootPath "C:\Shared" -UserName "jdoe"
$userPermissions | Export-Csv -Path "user_permissions_report.csv" -NoTypeInformation
Once you've identified all permissions, you can use this script to remove them:
function Remove-UserPermissions {
param (
[string]$RootPath,
[string]$UserName
)
$dirs = Get-ChildItem -Path $RootPath -Recurse -Directory
foreach ($dir in $dirs) {
$acl = Get-Acl -Path $dir.FullName
$accessRules = $acl.Access | Where-Object { $_.IdentityReference -like "*$UserName*" }
foreach ($rule in $accessRules) {
$acl.RemoveAccessRule($rule) | Out-Null
}
Set-Acl -Path $dir.FullName -AclObject $acl
}
}
# Example usage:
Remove-UserPermissions -RootPath "C:\Shared" -UserName "jdoe"
For enterprise environments with thousands of folders, consider these tools:
- AccessChk from Sysinternals (command-line version)
- NTFS Permissions Reporter (commercial tool with free trial)
- PowerShell Module NTFSSecurity (more advanced functionality)
When transitioning users:
- Always create a backup of current permissions
- Use security groups rather than individual user assignments
- Document all permission changes for audit purposes
- Test new permissions before removing old ones
Here's a complete workflow script that:
- Audits current permissions
- Removes existing access
- Grants new contractor permissions
# Full transition script
$user = "jdoe"
$backupFile = "permissions_backup_$(Get-Date -Format 'yyyyMMdd').csv"
$sharedPath = "C:\Shared"
$contractorGroup = "Contractors_RW"
# Step 1: Backup current permissions
Get-UserPermissions -RootPath $sharedPath -UserName $user | Export-Csv -Path $backupFile
# Step 2: Remove existing permissions
Remove-UserPermissions -RootPath $sharedPath -UserName $user
# Step 3: Add to contractor group with read/write access
Add-ADGroupMember -Identity $contractorGroup -Members $user
# Step 4: Verify new permissions
$newPermissions = Get-ADGroupMember -Identity $contractorGroup | Where-Object { $_.SamAccountName -eq $user }
if ($newPermissions) {
Write-Output "User $user successfully transitioned to contractor permissions"
}
Managing NTFS permissions for departing employees who transition to contractor roles is a common enterprise scenario. When users have complex, granular access across multiple folders, identifying all their permissions becomes critical for security compliance.
While GUI tools like AccessEnum fall short, PowerShell provides the perfect solution with its Get-Acl
and Get-ChildItem
cmdlets. Here's a comprehensive script that audits a user's access across all drives:
# Define the target user and search scope
$username = "DOMAIN\contractor_user"
$searchPath = "D:\Shared" # Modify for your environment
# Recursive permission audit function
function Get-UserPermissions {
param (
[string]$path,
[string]$user
)
Get-ChildItem -Path $path -Recurse -Directory | ForEach-Object {
$acl = Get-Acl -Path $_.FullName
foreach ($access in $acl.Access) {
if ($access.IdentityReference -like "*$user*") {
[PSCustomObject]@{
FolderPath = $_.FullName
User = $access.IdentityReference
AccessType = $access.AccessControlType
Permissions = $access.FileSystemRights
Inheritance = $access.IsInherited
}
}
}
}
}
# Execute the audit
$userPermissions = Get-UserPermissions -path $searchPath -user $username.Split('\')[1]
$userPermissions | Export-Csv -Path "C:\Audit\UserPermissions_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
After identifying all access points, use this script to remove and replace permissions:
# Remove existing permissions
$userPermissions | ForEach-Object {
$acl = Get-Acl $_.FolderPath
$acl.RemoveAccessRuleSpecific(
(New-Object System.Security.AccessControl.FileSystemAccessRule(
$_.User,
$_.Permissions,
$_.Inheritance,
"None", # Propagation flags
$_.AccessType
))
)
Set-Acl -Path $_.FolderPath -AclObject $acl
}
# Add new contractor permissions (example)
$newPermissions = @(
@{Path="D:\Shared\ProjectX"; Rights="Read,Write"},
@{Path="D:\Shared\VendorDocs"; Rights="Read"}
)
foreach ($perm in $newPermissions) {
$acl = Get-Acl $perm.Path
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$username,
$perm.Rights,
"ContainerInherit,ObjectInherit",
"None",
"Allow"
)
$acl.SetAccessRule($accessRule)
Set-Acl -Path $perm.Path -AclObject $acl
}
For enterprises with thousands of folders, consider these tools:
- Microsoft's AccessChk (Sysinternals suite)
- NTFS Permissions Reporter (GUI alternative)
- icacls command-line utility for batch processing
Always:
- Run audits during low-usage periods
- Backup ACLs using
icacls * /save permissions.txt /T
- Test changes in a staging environment first
- Document all permission modifications