Shrink and Defrag AVD Fslogix Profiles

https://github.com/FSLogix/Invoke-FslShrinkDisk

# Define the folder path containing the virtual disks
$folderPath = "\\xxxxxx\fslogix-o365"

# Function to get an available drive letter, excluding floppy and CD-ROM drives
function Get-AvailableDriveLetter {
    # Get used drive letters
    $usedLetters = Get-Partition | Where-Object { $_.DriveLetter } | Select-Object -ExpandProperty DriveLetter
    # Get drive letters assigned to CD-ROM drives
    $cdromLetters = Get-CimInstance -ClassName Win32_CDROMDrive | Select-Object -ExpandProperty Drive | ForEach-Object { $_[0] }
    # Define reserved letters for floppy disks
    $reservedLetters = @('A', 'B')
    # Combine used, CD-ROM, and reserved letters
    $excludedLetters = $usedLetters + $cdromLetters + $reservedLetters | Sort-Object | Get-Unique
    # Get available letters from C to Z, excluding the ones above
    $availableLetters = [char[]](67..90) | Where-Object { $_ -notin $excludedLetters }
    if ($availableLetters) {
        return $availableLetters[0]
    }
    throw "No available drive letters found"
}

# Function to get the disk number of a newly mounted VHD
function Get-MountedVHDDiskNumber {
    param (
        [string]$VHDPath
    )
    # Get disk information after mounting
    $disks = Get-Disk
    # Look for the disk with the VHD path in its location or signature
    $mountedDisk = $disks | Where-Object { $_.Location -eq $VHDPath -or $_.Path -eq $VHDPath }
    if ($mountedDisk) {
        return $mountedDisk.Number
    }
    throw "Could not determine disk number for VHD: $VHDPath"
}

# Get all VHD and VHDX files in the folder
$vdiskFiles = Get-ChildItem -Recurse -Path $folderPath -Filter *.vhdx -File

# Loop through each virtual disk file and compact it
foreach ($vdisk in $vdiskFiles) {
    Write-Host "Compacting $($vdisk.FullName)..."

    try {
        # Mount the VHD
        Mount-VHD $vdisk.FullName -ErrorAction Stop

        # Get the disk number of the mounted VHD
        $diskNumber = Get-MountedVHDDiskNumber -VHDPath $vdisk.FullName
        Write-Host "Mounted VHD is on Disk $diskNumber"

        # Find an available drive letter
        $driveLetter = Get-AvailableDriveLetter
        Write-Host "Using drive letter $driveLetter"

        # Assign the drive letter to the partition (assuming first partition, typically 1 for VHDs)
        Get-Partition -DiskNumber $diskNumber -PartitionNumber 1 | Set-Partition -NewDriveLetter $driveLetter

        # Run disk maintenance commands
        chkdsk "$($driveLetter):" /f /x /forceofflinefix /scan
        chkdsk "$($driveLetter):" /sdcleanup /x
        defrag "$($driveLetter):" /x
        defrag "$($driveLetter):" /k /l
        defrag "$($driveLetter):" /x
        defrag "$($driveLetter):" /k

        # Dismount the VHD
        Dismount-VHD $vdisk.FullName

        # Optimize the VHD
        Optimize-VHD -Path $vdisk.FullName -Mode Full

        Write-Host "Compaction of $($vdisk.FullName) completed."
    }
    catch {
        Write-Host "Error processing $($vdisk.FullName): $_"
        # Ensure VHD is dismounted in case of error
        try { Dismount-VHD $vdisk.FullName -ErrorAction SilentlyContinue } catch {}
    }
}

Write-Host "All virtual disks in the folder have been compacted."
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...