OfficeScrubC2R.psm1
# # OfficeScrubC2R Module # PowerShell/C# implementation of Microsoft's Office Scrub C2R tool # Version: 2.19.0 # #Requires -Version 5.1 # Import the utilities module $utilitiesPath = Join-Path $PSScriptRoot "OfficeScrubC2R-Utilities.psm1" if (Test-Path $utilitiesPath) { Import-Module $utilitiesPath -Force -Global } else { throw "Required module not found: $utilitiesPath" } # Dot source the main script functions $mainScriptPath = Join-Path $PSScriptRoot "OfficeScrubC2R.ps1" if (Test-Path $mainScriptPath) { . $mainScriptPath } else { throw "Main script not found: $mainScriptPath" } <# .SYNOPSIS Removes Office Click-to-Run (C2R) products from the system. .DESCRIPTION Invoke-OfficeScrubC2R provides comprehensive removal of Office 2013, 2016, 2019, and Office 365 Click-to-Run installations when standard uninstall methods fail. This is a PowerShell/C# port of Microsoft's OffScrubC2R.vbs with 10-50x performance improvements. The tool performs the following operations: - Stops all Office processes - Uninstalls Office products using ODT - Removes registry keys and values - Deletes Office files and folders - Cleans up Windows Installer metadata - Removes scheduled tasks and services - Clears Office licenses (optional) Requires Administrator privileges. .PARAMETER Quiet Run in quiet mode with minimal output. .PARAMETER DetectOnly Only detect installed products without removing them. .PARAMETER Force Force removal without user confirmation. .PARAMETER RemoveAll Remove all Office products. .PARAMETER KeepLicense Keep Office licensing information. .PARAMETER Offline Run in offline mode (skip ODT download). .PARAMETER ForceArpUninstall Force ARP-based uninstall. .PARAMETER ClearTaskBand Clear taskband shortcuts. .PARAMETER UnpinMode Unpin shortcuts from taskbar and start menu. .PARAMETER SkipSD Skip scheduled deletion operations. .PARAMETER NoElevate Do not attempt elevation (will fail if not already elevated). .PARAMETER LogPath Specify custom log path. .EXAMPLE Invoke-OfficeScrubC2R Interactive mode - will prompt for confirmation before removal. .EXAMPLE Invoke-OfficeScrubC2R -Quiet -Force Silent removal without prompts or confirmation. .EXAMPLE Invoke-OfficeScrubC2R -DetectOnly Detect installed Office C2R products without removing them. .EXAMPLE Invoke-OfficeScrubC2R -KeepLicense -LogPath "C:\Logs" Remove Office but keep licenses, saving logs to custom location. .NOTES Author: Calvin (PowerShell/C# port) Original: Microsoft Corporation (OffScrubC2R.vbs) Version: 2.19.0 Requires: PowerShell 5.1+, .NET Framework 4.5+, Administrator privileges .LINK https://github.com/Calvindd2f/OfficeScrubC2R .LINK Get-InstalledOfficeProducts .LINK Test-IsC2R #> function Invoke-OfficeScrubC2R { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] [Alias('Remove-OfficeC2R', 'Uninstall-OfficeC2R')] param( [Parameter(HelpMessage = "Run in quiet mode with minimal output")] [switch]$Quiet, [Parameter(HelpMessage = "Only detect installed products without removing them")] [switch]$DetectOnly, [Parameter(HelpMessage = "Force removal without user confirmation")] [switch]$Force, [Parameter(HelpMessage = "Remove all Office products")] [switch]$RemoveAll, [Parameter(HelpMessage = "Keep Office licensing information")] [switch]$KeepLicense, [Parameter(HelpMessage = "Run in offline mode")] [switch]$Offline, [Parameter(HelpMessage = "Force ARP-based uninstall")] [switch]$ForceArpUninstall, [Parameter(HelpMessage = "Clear taskband shortcuts")] [switch]$ClearTaskBand, [Parameter(HelpMessage = "Unpin shortcuts from taskbar")] [switch]$UnpinMode, [Parameter(HelpMessage = "Skip scheduled deletion")] [switch]$SkipSD, [Parameter(HelpMessage = "Do not attempt elevation")] [switch]$NoElevate, [Parameter(HelpMessage = "Specify custom log path")] [string]$LogPath ) begin { # Check for Administrator privileges if (-not $NoElevate) { $currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent()) $isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { throw "This command requires Administrator privileges. Please run PowerShell as Administrator." } } # Validate PowerShell version if ($PSVersionTable.PSVersion.Major -lt 5) { throw "This module requires PowerShell 5.1 or later. Current version: $($PSVersionTable.PSVersion)" } } process { if ($PSCmdlet.ShouldProcess("Office Click-to-Run Products", "Remove")) { try { # Build parameters for main script $params = @{} if ($Quiet) { $params['Quiet'] = $true } if ($DetectOnly) { $params['DetectOnly'] = $true } if ($Force) { $params['Force'] = $true } if ($RemoveAll) { $params['RemoveAll'] = $true } if ($KeepLicense) { $params['KeepLicense'] = $true } if ($Offline) { $params['Offline'] = $true } if ($ForceArpUninstall) { $params['ForceArpUninstall'] = $true } if ($ClearTaskBand) { $params['ClearTaskBand'] = $true } if ($UnpinMode) { $params['UnpinMode'] = $true } if ($SkipSD) { $params['SkipSD'] = $true } if ($NoElevate) { $params['NoElevate'] = $true } if ($LogPath) { $params['LogPath'] = $LogPath } # Execute the main script $mainScriptBlock = Join-Path $PSScriptRoot "OfficeScrubC2R.ps1" & $mainScriptBlock @params } catch { Write-Error "Failed to execute OfficeScrubC2R: $_" throw } } } end { # Cleanup is handled by the main script } } # Export module members Export-ModuleMember -Function @( 'Invoke-OfficeScrubC2R', 'Get-InstalledOfficeProducts', 'Test-IsC2R', 'Initialize-Environment', 'Stop-OfficeProcesses' ) -Alias @( 'Remove-OfficeC2R', 'Uninstall-OfficeC2R' ) # Initialize environment after all exports # This must happen after the utilities module is fully loaded try { Initialize-Environment Write-Verbose "OfficeScrubC2R environment initialized successfully" } catch { Write-Warning "Failed to initialize OfficeScrubC2R environment: $_" } |