# Check-FSLogixPermissions.ps1
# Script to verify permissions for all FSLogix profile folders and their VHD/VHDX files in a parent folder
# Handles folder names as SID or SID_username
param (
[Parameter(Mandatory=$true)]
[string]$ParentFolderPath
)
# Function to check if folder exists
function Test-FolderExists {
param (
[string]$Path
)
if (-not (Test-Path -Path $Path -PathType Container)) {
Write-Host "Error: The parent folder '$Path' does not exist." -ForegroundColor Red
exit 1
}
}
# Function to extract and validate SID from folder name
function Get-SIDFromFolderName {
param (
[string]$FolderName
)
# Handle folder names like SID or SID_username
$parts = $FolderName -split '_'
$sid = $parts | Where-Object { $_ -match '^S-1-[0-9-]+$' } | Select-Object -First 1
if (-not $sid) {
Write-Host "Skipping folder '$FolderName': No valid SID found in name." -ForegroundColor Yellow
return $null
}
return $sid
}
# Function to get expected permissions for FSLogix folder or VHD/VHDX
function Get-ExpectedPermissions {
param (
[string]$UserSID
)
$expected = @(
@{
Identity = $UserSID
Access = "FullControl"
Inherited = $false
},
@{
Identity = "NT AUTHORITY\SYSTEM"
Access = "FullControl"
Inherited = $false
},
@{
Identity = "BUILTIN\Administrators"
Access = "FullControl"
Inherited = $false
}
)
return $expected
}
# Function to check actual permissions against expected
function Check-Permissions {
param (
[string]$Path,
[array]$ExpectedPermissions,
[string]$ItemType
)
Write-Host "Checking $ItemType permissions for: $Path" -ForegroundColor Cyan
$acl = Get-Acl -Path $Path
$results = @()
$issuesFound = $false
# Check each expected permission
foreach ($expected in $ExpectedPermissions) {
$identity = $expected.Identity
$expectedAccess = $expected.Access
$expectedInherited = $expected.Inherited
$rule = $acl.Access | Where-Object {
$_.IdentityReference -eq $identity -and
$_.FileSystemRights -eq $expectedAccess -and
$_.IsInherited -eq $expectedInherited
}
if ($rule) {
$results += [PSCustomObject]@{
Identity = $identity
Status = "Correct"
Details = "Permission '$expectedAccess' is correctly set (Inherited: $expectedInherited)."
}
} else {
$issuesFound = $true
$actualRule = $acl.Access | Where-Object { $_.IdentityReference -eq $identity }
if ($actualRule) {
$results += [PSCustomObject]@{
Identity = $identity
Status = "Incorrect"
Details = "Expected '$expectedAccess' (Inherited: $expectedInherited), but found '$($actualRule.FileSystemRights)' (Inherited: $($actualRule.IsInherited))."
}
} else {
$results += [PSCustomObject]@{
Identity = $identity
Status = "Missing"
Details = "Permission '$expectedAccess' is missing for '$identity'."
}
}
}
}
# Check for unexpected permissions
$unexpected = $acl.Access | Where-Object {
$_.IdentityReference -notin $ExpectedPermissions.Identity -and
$_.IsInherited -eq $false
}
if ($unexpected) {
$issuesFound = $true
foreach ($rule in $unexpected) {
$results += [PSCustomObject]@{
Identity = $rule.IdentityReference
Status = "Unexpected"
Details = "Unexpected permission '$($rule.FileSystemRights)' found for '$($rule.IdentityReference)'."
}
}
}
return $results, $issuesFound
}
# Main script
try {
# Verify parent folder exists
Test-FolderExists -Path $ParentFolderPath
# Get all subfolders
$profileFolders = Get-ChildItem -Path $ParentFolderPath -Directory
$allResults = @()
$anyIssuesFound = $false
foreach ($folder in $profileFolders) {
$folderPath = $folder.FullName
$folderName = $folder.Name
# Extract SID from folder name
$userSID = Get-SIDFromFolderName -FolderName $folderName
if (-not $userSID) {
continue
}
Write-Host "`nProcessing profile folder for SID: $userSID" -ForegroundColor Cyan
# Get expected permissions for the folder
$expectedPermissions = Get-ExpectedPermissions -UserSID $userSID
# Check folder permissions
$folderResults, $folderIssues = Check-Permissions -Path $folderPath -ExpectedPermissions $expectedPermissions -ItemType "Folder"
$allResults += $folderResults | ForEach-Object {
[PSCustomObject]@{
Item = $folderPath
Type = "Folder"
Identity = $_.Identity
Status = $_.Status
Details = $_.Details
}
}
if ($folderIssues) { $anyIssuesFound = $true }
# Check for VHD/VHDX file
$vhdxFile = Get-ChildItem -Path $folderPath -File | Where-Object { $_.Extension -in @('.vhd', '.vhdx') } | Select-Object -First 1
if ($vhdxFile) {
$vhdxPath = $vhdxFile.FullName
$vhdxResults, $vhdxIssues = Check-Permissions -Path $vhdxPath -ExpectedPermissions $expectedPermissions -ItemType "VHD/VHDX File"
$allResults += $vhdxResults | ForEach-Object {
[PSCustomObject]@{
Item = $vhdxPath
Type = "VHD/VHDX File"
Identity = $_.Identity
Status = $_.Status
Details = $_.Details
}
}
if ($vhdxIssues) { $anyIssuesFound = $true }
} else {
Write-Host "No VHD/VHDX file found in folder: $folderPath" -ForegroundColor Yellow
}
}
# Output consolidated results
Write-Host "`nConsolidated Permission Check Results:" -ForegroundColor Cyan
$allResults | Format-Table -Property Item, Type, Identity, Status, Details -AutoSize
if ($anyIssuesFound) {
Write-Host "Permission issues detected in one or more folders/files. Please review the output above." -ForegroundColor Yellow
} else {
Write-Host "All permissions are correctly set for all FSLogix folders and VHD/VHDX files." -ForegroundColor Green
}
}
catch {
Write-Host "An error occurred: $_" -ForegroundColor Red
exit 1
}