-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathOptimize-OneDriveVDI.ps1
More file actions
73 lines (59 loc) · 2.63 KB
/
Optimize-OneDriveVDI.ps1
File metadata and controls
73 lines (59 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<#
.SYNOPSIS
Optimizes OneDrive disk usage for VDI environments (Logoff Script).
.DESCRIPTION
This script performs the following actions to minimize FSLogix/Profile container size:
1. Forcefully terminates the OneDrive process to release file locks.
2. Uses the native 'attrib.exe' tool to dehydrate all files in the OneDrive folder.
- Sets attribute +U (Unpinned / Cloud Only).
- Sets attribute -P (Remove Pinned / Remove "Always keep on this device").
Result: Files occupy 0 bytes on the disk but remain visible in Explorer.
.NOTES
Name: Optimize-OneDriveVDI.ps1
Author: Thomas Koetzing | www.koetzingit.de
Date: 2026-02-11
Version: 2.0 (Native Attribute Version)
Requirements / OS Compatibility:
- Windows 10 Build 1709 (Fall Creators Update) or newer
- Windows 11 (all versions)
- Windows Server 2019 / 2022 / 2025
- NOT compatible with Server 2016 or older (missing +U switch in attrib.exe)
.EXAMPLE
Powershell.exe -ExecutionPolicy Bypass -File .\Optimize-OneDriveVDI.ps1
#>
# --- CONFIGURATION ---
$OneDrivePath = $env:OneDrive
$LogTag = "[OneDrive-Opt]"
# --- PRE-CHECK ---
If (-not (Test-Path -Path $OneDrivePath)) {
Write-Output "$LogTag No OneDrive folder found at '$OneDrivePath'. Script skipped."
Exit 0
}
# --- STEP 1: Terminate OneDrive Process ---
# Essential to release file handles; otherwise, 'attrib' might fail on locked files.
Write-Output "$LogTag Terminating OneDrive process..."
Stop-Process -Name "OneDrive" -Force -ErrorAction SilentlyContinue
# Short delay to allow the OS to release NTFS handles (Race Condition Prevention)
Start-Sleep -Milliseconds 2000
# --- STEP 2: Set Attributes (Dehydration) ---
# Using attrib.exe is approx. 100x faster than PowerShell Get-ChildItem loops.
# +U = Unpinned (Cloud only)
# -P = Unpin (Removes "Always keep on this device" flag)
# /s = Recursive (Subfolders)
# /d = Apply to folders as well
Write-Output "$LogTag Starting dehydration (attrib.exe +U -P)..."
$processInfo = New-Object System.Diagnostics.ProcessStartInfo
$processInfo.FileName = "attrib.exe"
# IMPORTANT: Quotes around path to handle spaces in usernames
$processInfo.Arguments = "+U -P `"$OneDrivePath\*`" /s /d"
$processInfo.RedirectStandardOutput = $true
$processInfo.UseShellExecute = $false
$processInfo.CreateNoWindow = $true
$process = [System.Diagnostics.Process]::Start($processInfo)
$process.WaitForExit()
# --- COMPLETION ---
If ($process.ExitCode -eq 0) {
Write-Output "$LogTag Disk space successfully freed. (Exit Code 0)"
} Else {
Write-Warning "$LogTag Error executing attrib.exe. Exit Code: $($process.ExitCode)"
}