Private/Resolve-WUSystemPartition.ps1

function Resolve-WUSystemPartition {
    <#
    .SYNOPSIS
        Resolves System Reserved Partition disk space issues for Windows Update.
 
    .DESCRIPTION
        Mounts the System Reserved partition and performs cleanup operations to free disk space
        for Windows Update operations. Includes font file cleanup and manufacturer-specific
        optimizations.
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $result = Resolve-WUSystemPartition -LogPath "C:\Logs\wu.log"
 
    .NOTES
        This function requires Administrator privileges.
        Returns an object with Success, SpaceFreed, and RebootRequired properties.
    #>


    [CmdletBinding()]
    param(
        [string]$LogPath
    )

    # Initialize result object
    $result = [PSCustomObject]@{
        Success = $false
        SpaceFreed = 0
        RebootRequired = $false
        ActionsPerformed = @()
        ErrorMessage = $null
    }

    Write-WULog -Message "Starting System Reserved Partition remediation" -LogPath $LogPath

    try {
        # Mount the system reserved partition to Y:
        Write-WULog -Message "Mounting System Reserved partition to Y:..." -LogPath $LogPath
        
        $mountResult = & cmd.exe /c "mountvol Y: /s" 2>&1
        
        if (!(Test-Path 'Y:\')) { 
            throw "Failed to mount System Reserved partition to Y:. Output: $mountResult"
        }
        
        Write-WULog -Message "System Reserved partition mounted successfully" -LogPath $LogPath

        # Get initial free space
        try {
            $initialSpace = (Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "Y:" }).FreeSpace
            Write-WULog -Message "Initial free space on System Reserved: $([math]::Round($initialSpace / 1MB, 2)) MB" -LogPath $LogPath
        }
        catch {
            Write-WULog -Message "Could not determine initial free space" -Level Warning -LogPath $LogPath
            $initialSpace = 0
        }

        # Delete all .ttf font files in the Fonts directory
        $fontsPath = 'Y:\EFI\Microsoft\Boot\Fonts'
        if (Test-Path $fontsPath) {
            try {
                $ttfFiles = Get-ChildItem -Path $fontsPath -Filter *.ttf -ErrorAction SilentlyContinue
                if ($ttfFiles) {
                    $totalSize = ($ttfFiles | Measure-Object -Property Length -Sum).Sum
                    Write-WULog -Message "Found $($ttfFiles.Count) font files totaling $([math]::Round($totalSize / 1MB, 2)) MB" -LogPath $LogPath
                    
                    Remove-Item -Path "$fontsPath\*.ttf" -Force -ErrorAction Stop
                    Write-WULog -Message "Font files deleted successfully" -LogPath $LogPath
                    $result.ActionsPerformed += "Removed $($ttfFiles.Count) font files ($([math]::Round($totalSize / 1MB, 2)) MB)"
                    $result.SpaceFreed += $totalSize
                } else {
                    Write-WULog -Message "No .ttf files found in $fontsPath" -LogPath $LogPath
                }
            }
            catch {
                Write-WULog -Message "Error cleaning font files: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
            }
        } else {
            Write-WULog -Message "$fontsPath does not exist" -Level Warning -LogPath $LogPath
        }

        # Handle manufacturer-specific cleanup
        try {
            $manufacturer = (Get-CimInstance -ClassName Win32_ComputerSystem).Manufacturer
            Write-WULog -Message "Detected Manufacturer: $manufacturer" -LogPath $LogPath

            switch -Wildcard ($manufacturer) {
                "*HP*" {
                    $hpPath = 'Y:\EFI\HP\DEVFW'
                    if (Test-Path $hpPath) {
                        $hpFiles = Get-ChildItem -Path $hpPath -File -ErrorAction SilentlyContinue
                        if ($hpFiles) {
                            $destDir = 'C:\CSOLVE\HPDEVFW'
                            $totalSize = ($hpFiles | Measure-Object -Property Length -Sum).Sum
                            Write-WULog -Message "Found HP DEVFW files totaling $([math]::Round($totalSize / 1MB, 2)) MB" -LogPath $LogPath
                            
                            if (!(Test-Path $destDir)) {
                                New-Item -Path $destDir -ItemType Directory -Force | Out-Null
                                Write-WULog -Message "Created backup directory: $destDir" -LogPath $LogPath
                            }
                            
                            Move-Item -Path "$hpPath\*" -Destination $destDir -Force -ErrorAction Stop
                            Write-WULog -Message "HP DEVFW files moved successfully to $destDir" -LogPath $LogPath
                            $result.ActionsPerformed += "Moved HP DEVFW files to backup location ($([math]::Round($totalSize / 1MB, 2)) MB)"
                            $result.SpaceFreed += $totalSize
                        } else {
                            Write-WULog -Message "No files found in HP DEVFW directory" -LogPath $LogPath
                        }
                    } else {
                        Write-WULog -Message "No HP DEVFW directory found" -LogPath $LogPath
                    }
                }
                "*Dell*" {
                    Write-WULog -Message "Dell system detected - checking for Dell-specific cleanup opportunities" -LogPath $LogPath
                    
                    # Check for Dell BIOS update files that might be taking space
                    $dellPaths = @('Y:\EFI\Dell', 'Y:\Dell')
                    foreach ($dellPath in $dellPaths) {
                        if (Test-Path $dellPath) {
                            $dellFiles = Get-ChildItem -Path $dellPath -File -Recurse -ErrorAction SilentlyContinue
                            if ($dellFiles) {
                                $totalSize = ($dellFiles | Measure-Object -Property Length -Sum).Sum
                                if ($totalSize -gt 10MB) {  # Only clean if significant space
                                    Write-WULog -Message "Found Dell files in $dellPath totaling $([math]::Round($totalSize / 1MB, 2)) MB" -LogPath $LogPath
                                    # For Dell, we'll just log but not automatically clean - could be important BIOS files
                                    Write-WULog -Message "Dell BIOS files detected but not automatically removed for safety" -Level Warning -LogPath $LogPath
                                }
                            }
                        }
                    }
                }
                "*Lenovo*" {
                    Write-WULog -Message "Lenovo system detected - checking for Lenovo-specific cleanup opportunities" -LogPath $LogPath
                    
                    # Check for Lenovo UEFI files
                    $lenovoPath = 'Y:\EFI\Lenovo'
                    if (Test-Path $lenovoPath) {
                        $lenovoFiles = Get-ChildItem -Path $lenovoPath -File -Recurse -ErrorAction SilentlyContinue
                        if ($lenovoFiles) {
                            $totalSize = ($lenovoFiles | Measure-Object -Property Length -Sum).Sum
                            Write-WULog -Message "Found Lenovo files totaling $([math]::Round($totalSize / 1MB, 2)) MB - leaving in place for system stability" -LogPath $LogPath
                        }
                    }
                }
                default {
                    Write-WULog -Message "No manufacturer-specific cleanup available for: $manufacturer" -LogPath $LogPath
                }
            }
        }
        catch {
            Write-WULog -Message "Error during manufacturer-specific cleanup: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Additional cleanup - old Windows Update cache files on System Reserved
        try {
            $updateCachePaths = @(
                'Y:\$Windows.~BT',
                'Y:\$Windows.~WS', 
                'Y:\Windows.old'
            )
            
            foreach ($cachePath in $updateCachePaths) {
                if (Test-Path $cachePath) {
                    $cacheFiles = Get-ChildItem -Path $cachePath -Recurse -File -ErrorAction SilentlyContinue
                    if ($cacheFiles) {
                        $totalSize = ($cacheFiles | Measure-Object -Property Length -Sum).Sum
                        if ($totalSize -gt 0) {
                            Write-WULog -Message "Found old Windows Update cache in $cachePath totaling $([math]::Round($totalSize / 1MB, 2)) MB" -LogPath $LogPath
                            
                            # Only remove if it's actually taking significant space and is old
                            $cacheAge = (Get-Date) - (Get-Item $cachePath).LastWriteTime
                            if ($cacheAge.TotalDays -gt 7 -and $totalSize -gt 50MB) {
                                Remove-Item -Path $cachePath -Recurse -Force -ErrorAction Stop
                                Write-WULog -Message "Removed old Windows Update cache from $cachePath" -LogPath $LogPath
                                $result.ActionsPerformed += "Removed old Windows Update cache ($([math]::Round($totalSize / 1MB, 2)) MB)"
                                $result.SpaceFreed += $totalSize
                            }
                        }
                    }
                }
            }
        }
        catch {
            Write-WULog -Message "Error cleaning Windows Update cache: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Check final free space
        try {
            $finalSpace = (Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq "Y:" }).FreeSpace
            $freedSpace = $finalSpace - $initialSpace
            Write-WULog -Message "Final free space on System Reserved: $([math]::Round($finalSpace / 1MB, 2)) MB" -LogPath $LogPath
            Write-WULog -Message "Space freed: $([math]::Round($freedSpace / 1MB, 2)) MB" -LogPath $LogPath
            
            # Update the actual space freed (may be different from file sizes due to cluster sizes)
            if ($freedSpace -gt 0) {
                $result.SpaceFreed = $freedSpace
            }
        }
        catch {
            Write-WULog -Message "Could not determine final free space" -Level Warning -LogPath $LogPath
        }

        $result.Success = $true

    }
    catch {
        $result.ErrorMessage = $_.Exception.Message
        Write-WULog -Message "Error during System Reserved partition remediation: $($_.Exception.Message)" -Level Error -LogPath $LogPath
    }
    finally {
        # Always attempt to unmount
        Write-WULog -Message "Unmounting System Reserved partition..." -LogPath $LogPath
        
        try {
            $unmountResult = & cmd.exe /c "mountvol Y: /d" 2>&1
            Write-WULog -Message "Unmount command output: $unmountResult" -LogPath $LogPath
            
            # Give it a moment to unmount
            Start-Sleep -Seconds 2
            
            if (Test-Path 'Y:\') {
                Write-WULog -Message "Y: drive still mounted after unmount attempt" -Level Warning -LogPath $LogPath
                
                # Try force unmount
                try {
                    & cmd.exe /c "mountvol Y: /d" 2>&1 | Out-Null
                    Start-Sleep -Seconds 1
                }
                catch {
                    Write-WULog -Message "Force unmount also failed" -Level Warning -LogPath $LogPath
                }
            } else {
                Write-WULog -Message "System Reserved partition unmounted successfully" -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Error during unmount: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }
    }

    # Summary
    if ($result.Success) {
        Write-WULog -Message "System Reserved Partition remediation completed successfully" -LogPath $LogPath
        if ($result.ActionsPerformed.Count -gt 0) {
            Write-WULog -Message "Actions performed:" -LogPath $LogPath
            foreach ($action in $result.ActionsPerformed) {
                Write-WULog -Message " - $action" -LogPath $LogPath
            }
        }
        if ($result.SpaceFreed -gt 0) {
            Write-WULog -Message "Total space freed: $([math]::Round($result.SpaceFreed / 1MB, 2)) MB" -LogPath $LogPath
        }
    } else {
        Write-WULog -Message "System Reserved Partition remediation failed: $($result.ErrorMessage)" -Level Error -LogPath $LogPath
    }

    return $result
}