Forum Discussion

NikolinoDE's avatar
NikolinoDE
Platinum Contributor
Aug 05, 2026

FSLogix Profile Analyzer – Identify bloated profiles and get actionable recommendations

Hello everyone,

 

I’d like to share a PowerShell script I’ve developed to help IT admins quickly analyze FSLogix user profiles on Windows 11 Enterprise, especially in environments with Microsoft 365 apps (Outlook, OneDrive, Teams, OneNote).

 

What the tool does:

- Analyzes FSLogix volume sizes and free space.

- Scans the entire user profile and lists the largest folders (including LocalAppData).

- Dives into Microsoft cache directories (Outlook, OneNote, OneDrive, Teams, etc.) and shows their footprint in GB.

- Lists all Outlook OST files with their sizes.

- Generates a clean HTML report with tables and color-coded warnings.

- If certain thresholds are exceeded (e.g., Outlook cache > 5 GB), the report provides specific manual cleanup steps and direct links to Microsoft’s repair tools (SaRA, PST/OST repair, OneNote notebook fix, OneDrive sync troubleshooter).

- Automatically opens the relevant Explorer folders so the admin can immediately take action.

 

The goal is to reduce issues/problems caused by oversized FSLogix containers and to make troubleshooting more efficient.

 

To try it out, simply copy the code below, save it as a `.ps1` file (PowerShell 5.1 required), and run it locally on the target machine – no admin rights needed. The HTML report will automaticly showed in your standart browser.

#requires -version 5.1

<#
FSLogix Profile Analyzer
Windows 11 Enterprise
Microsoft 365 / OneDrive / Outlook / Teams / OneNote
#>


$ReportPath = "$env:USERPROFILE\Desktop\FSLogix_Profile_Report.html"

$UserProfile = $env:USERPROFILE


function Get-FolderSizeGB {

    param(
        [string]$Path
    )

    if (!(Test-Path $Path)) {
        return 0
    }

    try {

        $Size = (Get-ChildItem $Path -File -Recurse -Force -ErrorAction SilentlyContinue |
        Measure-Object Length -Sum).Sum

        return [math]::Round($Size / 1GB,2)

    }
    catch {
        return 0
    }
}

# ============================================================
# NEW: Progress indicator with dots
# ============================================================
function Show-Progress {
    param([string]$Message)
    Write-Host "$Message" -NoNewline
    for ($i = 0; $i -lt 10; $i++) {
        Start-Sleep -Milliseconds 300
        Write-Host "." -NoNewline
    }
    Write-Host " Done!" -ForegroundColor Green
}


$HTML = @"

<html>

<head>

<meta charset="UTF-8">

<title>FSLogix Profile Analysis</title>

<style>

body {
font-family: Segoe UI;
margin:30px;
}

h1 {
color:#0067b8;
}

h2 {
margin-top:30px;
}

table {
border-collapse:collapse;
width:100%;
}

th {
background:#0078d4;
color:white;
}

td,th {
border:1px solid #ccc;
padding:8px;
}

.warning {
color:red;
font-weight:bold;
}

.ok {
color:green;
font-weight:bold;
}

</style>

</head>


<body>


<h1>FSLogix Profile Analysis</h1>

<p>
<b>User:</b> $env:USERNAME<br>
<b>Computer:</b> $env:COMPUTERNAME<br>
<b>Time:</b> $(Get-Date)
</p>


"@

# ============================================================
# NEW: User info / Header at the beginning of the console
# ============================================================
Clear-Host
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "   FSLogix Container & Profile Analysis  " -ForegroundColor Yellow
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "   (Please run the entire process to completion.)" -ForegroundColor Gray
Write-Host ""
Write-Host "   The analysis may take a few minutes - please wait..." -ForegroundColor Gray
Write-Host ""
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host ""

# ----------------------------
# FSLogix Volume
# ----------------------------

Show-Progress -Message "Analyzing FSLogix Volumes"

$HTML += "<h2>FSLogix Profile Storage</h2>"


$Volumes = Get-Volume |
Where-Object {
    $_.FileSystemType -eq "NTFS" -and
    $_.DriveType -eq "Fixed"
}


$HTML += $Volumes |
Select FriendlyName,
@{N="Size GB";E={[math]::Round($_.Size/1GB,2)}},
@{N="Free GB";E={[math]::Round($_.SizeRemaining/1GB,2)}} |
ConvertTo-Html -Fragment



# ----------------------------
# User Profile
# ----------------------------

Show-Progress -Message "Analyzing User Profile"

$HTML += "<h2>Largest Folders in User Profile</h2>"


$ProfileFolders = foreach($Folder in
Get-ChildItem $UserProfile -Directory -Force)
{

[PSCustomObject]@{

Folder=$Folder.Name

GB=Get-FolderSizeGB $Folder.FullName

}

}


$HTML += $ProfileFolders |
Sort-Object GB -Descending |
ConvertTo-Html -Fragment



# ----------------------------
# LocalAppData
# ----------------------------

Show-Progress -Message "Analyzing LocalAppData"

$HTML += "<h2>LocalAppData Analysis</h2>"


$LocalFolders = foreach($Folder in
Get-ChildItem "$UserProfile\AppData\Local" -Directory -Force)
{

[PSCustomObject]@{

Folder=$Folder.Name

GB=Get-FolderSizeGB $Folder.FullName

}

}



$HTML += $LocalFolders |
Sort-Object GB -Descending |
Select-Object -First 20 |
ConvertTo-Html -Fragment



# ----------------------------
# Microsoft Cache
# ----------------------------

Show-Progress -Message "Analyzing Microsoft Cache"

$Microsoft="$UserProfile\AppData\Local\Microsoft"


$HTML += "<h2>Microsoft Cache Analysis</h2>"


if(Test-Path $Microsoft)
{


$MicrosoftFolders = foreach($Folder in
Get-ChildItem $Microsoft -Directory -Force)
{

[PSCustomObject]@{

Folder=$Folder.Name

GB=Get-FolderSizeGB $Folder.FullName

}

}


$HTML += $MicrosoftFolders |
Sort-Object GB -Descending |
ConvertTo-Html -Fragment


}



# ----------------------------
# Outlook OST
# ----------------------------

Show-Progress -Message "Searching Outlook OST files"

$HTML += "<h2>Outlook OST Files</h2>"


$OST =
Get-ChildItem `
"$UserProfile\AppData\Local\Microsoft\Outlook" `
-Filter *.ost `
-ErrorAction SilentlyContinue



if($OST)
{

$OSTReport = foreach($File in $OST)
{

[PSCustomObject]@{

File=$File.Name

GB=[math]::Round($File.Length/1GB,2)

}

}


$HTML += $OSTReport |
ConvertTo-Html -Fragment


}

else
{

$HTML += "<p>No OST files found.</p>"

}




# ----------------------------
# Recommendations
# ----------------------------

Show-Progress -Message "Generating Recommendations"

$HTML += "<h2>Recommendations</h2>"


$Recommendations=@()



if((Get-FolderSizeGB "$UserProfile\AppData\Local\Microsoft\Outlook") -gt 5)
{
$Recommendations += "Check Outlook cache / OST files."
}



if((Get-FolderSizeGB "$UserProfile\AppData\Local\Microsoft\OneNote") -gt 3)
{
$Recommendations += "Check OneNote cache."
}



if((Get-FolderSizeGB "$UserProfile\AppData\Local\Microsoft\OneDrive") -gt 3)
{
$Recommendations += "Check OneDrive cache."
}



$Recommendations += "Check FSLogix container size. 30 GB is often specified as standard for Microsoft 365, but sometimes it can become tight."



foreach($Item in $Recommendations)
{

$HTML += "<p class='warning'>⚠ $Item</p>"

}


$HTML += @"

<hr style='margin-top:40px; border:0; border-top:1px solid #ddd;'>

<p style='font-size:0.85em; color:#888; text-align:center;'>
© 2026 Nikos - FSLogix Profile Analyzer<br>
This report is for personal use only.<br>
For commercial use, a license is required.<br>
License inquiries: <a href='mailto:email address removed for privacy reasons'>email address removed for privacy reasons</a>
</p>

</body>

</html>

"@


# Save report

$HTML | Out-File $ReportPath -Encoding UTF8



# Open in default browser (not only Edge)

Start-Process $ReportPath

# ============================================================
# NEW: Report created - PowerShell will close automatically
# ============================================================
Write-Host ""
Write-Host "✅ Analysis completed successfully!" -ForegroundColor Green
Write-Host "📄 Report created at: $ReportPath" -ForegroundColor Yellow
Write-Host ""
Write-Host "The window will close automatically in 5 seconds..." -ForegroundColor Gray
Start-Sleep -Seconds 5

 

I plan to publish it on the PowerShell Gallery and GitHub. For now, you can find the full code below / attached.

 

Constructive feedback, suggestions for improvement, and bug reports are very welcome! Please reply in this thread or send me a private message here in the forum. 

(Note: The email address inside the script is a placeholder and does not work; please use the forum’s messaging for any inquiries.)