Skip to content

Function Reference

Calvindd2f edited this page Jan 14, 2026 · 1 revision

Function Reference

Relevant source files

The following files were used as context for generating this wiki page:

This page provides a complete alphabetical reference for all exported PowerShell functions in the OfficeScrubC2R module. Each function entry includes its synopsis, parameters, return values, and usage examples.

For information about command-line parameters and operational modes, see Command-Line Parameters and Operational Modes. For details about the underlying native C# helper classes that power many of these functions, see Helper Classes.


Function Categories

The module exports 35 public functions organized into nine functional categories:

graph TB
    subgraph "Primary Interface"
        InvokeMain["Invoke-OfficeScrubC2R<br/>Main entry point<br/>with aliases"]
    end
    
    subgraph "Product Detection"
        GetProducts["Get-InstalledOfficeProducts"]
        TestC2R["Test-IsC2R"]
        TestScope["Test-ProductInScope"]
    end
    
    subgraph "Environment & System"
        InitEnv["Initialize-Environment"]
        GetSysInfo["Get-SystemInfo"]
        TestElev["Test-IsElevated"]
    end
    
    subgraph "Logging Functions"
        InitLog["Initialize-Log"]
        WriteHeader["Write-LogHeader"]
        WriteSubHeader["Write-LogSubHeader"]
        WriteLog["Write-Log"]
        WriteLogOnly["Write-LogOnly"]
        CloseLog["Close-Log"]
    end
    
    subgraph "Error Handling"
        SetError["Set-ErrorCode"]
        ClearError["Clear-ErrorCode"]
        SetReturn["Set-ReturnValue"]
    end
    
    subgraph "Registry Operations"
        GetRegValue["Get-RegistryValue"]
        SetRegValue["Set-RegistryValue"]
        RemoveRegKey["Remove-RegistryKey"]
        RemoveRegValue["Remove-RegistryValue"]
        GetRegKeys["Get-RegistryKeys"]
        GetRegValues["Get-RegistryValues"]
        TestRegKey["Test-RegistryKeyExists"]
    end
    
    subgraph "File Operations"
        RemoveFolder["Remove-FolderRecursive"]
        RemoveFile["Remove-FileForced"]
        AddPending["Add-PendingFileDelete"]
    end
    
    subgraph "Process & Service Operations"
        StopProc["Stop-OfficeProcesses"]
        TestProc["Test-ProcessRunning"]
        RemoveService["Remove-Service"]
    end
    
    subgraph "Cleanup Operations"
        ClearLicense["Clear-OfficeLicenses"]
        ClearWI["Clear-WindowsInstallerMetadata"]
        ClearTypeLib["Clear-TypeLibRegistrations"]
        ClearShell["Clear-ShellIntegration"]
        ClearShortcuts["Clear-Shortcuts"]
    end
    
    InvokeMain --> GetProducts
    InvokeMain --> StopProc
    InvokeMain --> RemoveFolder
    InvokeMain --> ClearLicense
    
    GetProducts --> TestC2R
    GetProducts --> TestScope
    
    InitEnv --> GetSysInfo
    InitEnv --> TestElev
    
    RemoveRegKey --> GetRegValue
    RemoveFolder --> AddPending
    
    ClearWI --> TestScope
    ClearShell --> RemoveRegKey
    ClearShortcuts --> TestC2R
Loading

Diagram: Function Categories and Relationships

Sources: OfficeScrubC2R.psm1:212-221, OfficeScrubC2R-Utilities.psm1:1011-1045


Function-to-File Mapping

graph LR
    subgraph "OfficeScrubC2R.psm1"
        M1["Invoke-OfficeScrubC2R<br/>Lines 118-209"]
    end
    
    subgraph "OfficeScrubC2R-Utilities.psm1"
        U1["Initialize-Environment<br/>Lines 154-198"]
        U2["Get-InstalledOfficeProducts<br/>Lines 575-717"]
        U3["Test-IsC2R<br/>Lines 719-729"]
        U4["Test-ProductInScope<br/>Lines 731-741"]
        U5["Stop-OfficeProcesses<br/>Lines 549-562"]
        U6["Registry Functions<br/>Lines 382-471"]
        U7["File Functions<br/>Lines 477-543"]
        U8["Logging Functions<br/>Lines 223-327"]
        U9["Error Functions<br/>Lines 333-376"]
        U10["Cleanup Functions<br/>Lines 773-1005"]
    end
    
    subgraph "OfficeScrubC2R.ps1"
        S1["Main<br/>Lines 924-1001"]
        S2["Initialize-Script<br/>Lines 87-136"]
        S3["Internal Functions<br/>Lines 138-918"]
    end
    
    M1 --> S1
    U2 --> U3
    U2 --> U4
    U1 -.initializes.-> Script["`$script:Orchestrator`"]
    U6 -.uses.-> Script
    U7 -.uses.-> Script
    U10 -.uses.-> Script
Loading

Diagram: Function Source File Locations

Sources: OfficeScrubC2R.psm1:1-233, OfficeScrubC2R-Utilities.psm1:1-1091, OfficeScrubC2R.ps1:1-1009


Alphabetical Function Reference

Add-PendingFileDelete

Schedules a file for deletion on next system reboot when the file cannot be deleted immediately due to being locked or in use.

Syntax:

Add-PendingFileDelete -Path <string>

Parameters:

Parameter Type Required Description
Path String Yes Full path to the file to schedule for deletion

Return Value: None (void)

Behavior:

  • Adds file path to PendingFileRenameOperations registry key
  • Sets $script:RebootRequired to $true
  • Sets ERROR_REBOOT_REQUIRED error code
  • Adds path to $script:DelInUse hashtable

Example:

Add-PendingFileDelete -Path "C:\Program Files\Microsoft Office\root\locked.dll"

Sources: OfficeScrubC2R-Utilities.psm1:535-543


Clear-ErrorCode

Clears specific error bits from the accumulated error code and automatically clears the ERROR_FAIL flag if clearing critical errors.

Syntax:

Clear-ErrorCode -ErrorBit <int>

Parameters:

Parameter Type Required Description
ErrorBit Int32 Yes Error code constant to clear (e.g., $script:ERROR_SCRIPTINIT)

Return Value: None (void)

Behavior:

  • Uses bitwise AND with negated mask to clear specific bits
  • Automatically clears ERROR_FAIL when clearing elevation or initialization errors
  • Modifies $script:ErrorCode variable

Example:

Clear-ErrorCode $script:ERROR_SCRIPTINIT

Sources: OfficeScrubC2R-Utilities.psm1:349-362


Clear-OfficeLicenses

Removes Office licensing information including OSPP licenses and VNext license cache unless the KeepLicense flag is set.

Syntax:

Clear-OfficeLicenses

Parameters: None

Return Value: None (void)

Behavior:

  • Skipped if $script:KeepLicense is $true
  • Calls $script:Orchestrator.License.CleanOSPP() for OSPP cleanup
  • Calls $script:Orchestrator.License.ClearVNextLicenseCache() for VNext cache
  • Logs all operations

Example:

Clear-OfficeLicenses

Sources: OfficeScrubC2R-Utilities.psm1:773-798


Clear-Shortcuts

Removes or unpins Office-related shortcuts from specified root path, checking if shortcut targets are C2R-related or contain Office product GUIDs.

Syntax:

Clear-Shortcuts -RootPath <string> [-Delete] [-Unpin]

Parameters:

Parameter Type Required Description
RootPath String Yes Root directory path to scan for shortcuts
Delete Switch No Delete matching shortcuts
Unpin Switch No Unpin shortcuts from taskbar and start menu

Return Value: None (void)

Behavior:

  • Skipped if $script:SkipSD is $true
  • Recursively finds all .lnk files
  • Uses COM object to read shortcut targets
  • Checks targets with Test-IsC2R and Test-ProductInScope
  • Calls $script:Orchestrator.Shell.UnpinFromTaskbar() and UnpinFromStartMenu() if -Unpin
  • Deletes matching shortcuts if -Delete

Example:

Clear-Shortcuts -RootPath "C:\Users\Public" -Delete -Unpin

Sources: OfficeScrubC2R-Utilities.psm1:949-1005


Clear-ShellIntegration

Removes Office shell integration including protocol handlers, context menu handlers, shell extensions, BHOs, and namespace extensions.

Syntax:

Clear-ShellIntegration

Parameters: None

Return Value: None (void)

Behavior:

  • Removes OSF protocol handler
  • Removes context menu handler CLSIDs
  • Removes Groove shell icon overlay identifiers
  • Removes shell extension GUIDs from Approved list
  • Removes Browser Helper Objects (BHOs)
  • Removes OneNote and SharePoint namespace extensions
  • Removes Volume Cache entries
  • Restarts Explorer via $script:Orchestrator.Shell.RestartExplorer()

Example:

Clear-ShellIntegration

Sources: OfficeScrubC2R-Utilities.psm1:855-947


Clear-TypeLibRegistrations

Removes Office COM type library registrations from the registry using the native TypeLib helper.

Syntax:

Clear-TypeLibRegistrations

Parameters: None

Return Value: None (void)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.TypeLib.CleanupKnownTypeLibs()
  • Removes known Office type library GUIDs

Example:

Clear-TypeLibRegistrations

Sources: OfficeScrubC2R-Utilities.psm1:837-849


Clear-WindowsInstallerMetadata

Cleans Windows Installer metadata including UpgradeCodes, Products, Components, and PublishedComponents for in-scope Office products.

Syntax:

Clear-WindowsInstallerMetadata

Parameters: None

Return Value: None (void)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Creates predicate function using Test-ProductInScope
  • Calls $script:Orchestrator.WindowsInstaller.CleanupUpgradeCodes()
  • Calls $script:Orchestrator.WindowsInstaller.CleanupProducts()
  • Calls $script:Orchestrator.WindowsInstaller.CleanupComponents()
  • Calls $script:Orchestrator.WindowsInstaller.CleanupPublishedComponents()

Example:

Clear-WindowsInstallerMetadata

Sources: OfficeScrubC2R-Utilities.psm1:804-831


Close-Log

Flushes and closes the log file stream, releasing file handles.

Syntax:

Close-Log

Parameters: None

Return Value: None (void)

Behavior:

  • Calls Flush(), Close(), and Dispose() on $script:LogStream
  • Sets $script:LogStream to $null
  • Should be called in finally block to ensure cleanup

Example:

try {
    # Operations
} finally {
    Close-Log
}

Sources: OfficeScrubC2R-Utilities.psm1:320-327


Get-InstalledOfficeProducts

Detects all installed Office Click-to-Run products by scanning multiple registry locations including O15, O16, Office C2R configurations, and ARP entries.

Syntax:

Get-InstalledOfficeProducts

Parameters: None

Return Value: Hashtable with product IDs as keys and version strings as values

Behavior:

  • Scans O15 Configuration registry (SOFTWARE\Microsoft\Office\15.0\ClickToRun\Configuration)
  • Scans O15 PropertyBag registry
  • Scans Office C2R active configuration (QR8+)
  • Scans Office C2R QR7 configuration
  • Scans O16 Configuration (QR6)
  • Scans ARP entries for C2R uninstall strings
  • Populates $script:InstalledSku and $script:C2RSuite hashtables
  • Logs all found products

Example:

$products = Get-InstalledOfficeProducts
foreach ($key in $products.Keys) {
    Write-Host "$key : $($products[$key])"
}

Sources: OfficeScrubC2R-Utilities.psm1:575-717


Get-RegistryKeys

Enumerates subkey names under a specified registry key using the native RegistryHelper for 30x performance improvement.

Syntax:

Get-RegistryKeys -Hive <RegistryHiveType> -SubKey <string>

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive (LocalMachine, CurrentUser, ClassesRoot, etc.)
SubKey String Yes Registry subkey path

Return Value: String array of subkey names, or empty array if key doesn't exist

Example:

$subkeys = Get-RegistryKeys -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\ClickToRun"
foreach ($key in $subkeys) {
    Write-Host $key
}

Sources: OfficeScrubC2R-Utilities.psm1:443-451


Get-RegistryValue

Retrieves a value from the registry using the native RegistryHelper with WOW64 support for 30x performance improvement.

Syntax:

Get-RegistryValue -Hive <RegistryHiveType> -SubKey <string> -ValueName <string> [-DefaultValue <object>]

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive enumeration value
SubKey String Yes Registry subkey path
ValueName String Yes Value name to retrieve
DefaultValue Object No Default value if key or value doesn't exist

Return Value: Object containing the registry value, or default value if not found

Example:

$version = Get-RegistryValue -Hive LocalMachine `
    -SubKey "SOFTWARE\Microsoft\Office\ClickToRun\Configuration" `
    -ValueName "VersionToReport" `
    -DefaultValue "Unknown"

Sources: OfficeScrubC2R-Utilities.psm1:382-391


Get-RegistryValues

Enumerates value names under a specified registry key using the native RegistryHelper.

Syntax:

Get-RegistryValues -Hive <RegistryHiveType> -SubKey <string>

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive (LocalMachine, CurrentUser, ClassesRoot, etc.)
SubKey String Yes Registry subkey path

Return Value: String array of value names, or empty array if key doesn't exist

Example:

$values = Get-RegistryValues -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\ClickToRun\Configuration"
foreach ($valueName in $values) {
    $data = Get-RegistryValue -Hive LocalMachine -SubKey $SubKey -ValueName $valueName
    Write-Host "$valueName = $data"
}

Sources: OfficeScrubC2R-Utilities.psm1:453-461


Get-SystemInfo

Retrieves operating system and computer system information, populating script-level variables with OS caption, version, and architecture.

Syntax:

Get-SystemInfo

Parameters: None

Return Value: None (void)

Behavior:

  • Queries Win32_OperatingSystem via CIM
  • Queries Win32_ComputerSystem via CIM
  • Sets $script:OSInfo with formatted string
  • Sets $script:Is64Bit based on system type

Example:

Get-SystemInfo
Write-Host $script:OSInfo

Sources: OfficeScrubC2R-Utilities.psm1:200-211


Initialize-Environment

Initializes the OfficeScrubC2R environment including loading native C# types, creating the orchestrator instance, and setting environment path variables.

Syntax:

Initialize-Environment

Parameters: None

Return Value: None (void)

Behavior:

  • Skips if already initialized (checks $script:Orchestrator)
  • Calls Initialize-NativeTypes to load DLL or compile C# source
  • Creates OfficeScrubNative.OfficeScrubOrchestrator instance
  • Sets environment paths: ProgramFiles, CommonProgramFiles, ProgramData, etc.
  • Sets 64-bit specific paths if applicable
  • Creates $script:ScrubDir temporary directory
  • Sets $script:LogDir default location

Example:

Initialize-Environment
Write-Host "Orchestrator: $($script:Orchestrator -ne $null)"
Write-Host "Program Files: $script:ProgramFiles"

Sources: OfficeScrubC2R-Utilities.psm1:154-198


Initialize-Log

Creates a new log file with timestamp and computer name, initializes the log stream, and writes header information.

Syntax:

Initialize-Log [-LogPath <string>]

Parameters:

Parameter Type Required Description
LogPath String No Custom log directory path; defaults to $script:LogDir

Return Value: None (void)

Behavior:

  • Creates log filename: {ComputerName}_{Timestamp}_ScrubLog.txt
  • Creates StreamWriter with UTF8 encoding and auto-flush
  • Writes log header with version, OS info, and start time
  • Sets $script:LogStream for subsequent logging operations

Example:

Initialize-Log -LogPath "C:\Logs\OfficeScrub"

Sources: OfficeScrubC2R-Utilities.psm1:223-258


Invoke-OfficeScrubC2R

Primary entry point for removing Office Click-to-Run products. Orchestrates the complete three-stage removal pipeline including detection, uninstallation, and cleanup.

Syntax:

Invoke-OfficeScrubC2R [-Quiet] [-DetectOnly] [-Force] [-RemoveAll] [-KeepLicense] 
                      [-Offline] [-ForceArpUninstall] [-ClearTaskBand] [-UnpinMode] 
                      [-SkipSD] [-NoElevate] [-LogPath <string>]

Parameters:

Parameter Type Required Description
Quiet Switch No Run in quiet mode with minimal output
DetectOnly Switch No Only detect products without removing them
Force Switch No Force removal without user confirmation
RemoveAll Switch No Remove all Office products
KeepLicense Switch No Keep Office licensing information
Offline Switch No Skip ODT download (offline mode)
ForceArpUninstall Switch No Force ARP-based uninstall
ClearTaskBand Switch No Clear taskband shortcuts
UnpinMode Switch No Unpin shortcuts from taskbar/start menu
SkipSD Switch No Skip scheduled deletion operations
NoElevate Switch No Do not attempt elevation
LogPath String No Custom log directory path

Return Value: Int32 error code (0 = success, non-zero = error)

Behavior:

  • Validates Administrator privileges (unless -NoElevate)
  • Validates PowerShell version >= 5.1
  • Sets script-level variables from parameters
  • Calls Main function from dot-sourced script
  • Implements three-stage pipeline:
    • Stage 0: Detection via Find-InstalledOfficeProducts
    • Stage 1: Uninstall via Uninstall-OfficeProducts
    • Stage 2: Cleanup via Clean-OfficeRegistry and Complete-Cleanup
    • Stage 3: Summary via Show-Summary

Aliases:

  • Remove-OfficeC2R
  • Uninstall-OfficeC2R

Example:

# Interactive removal with confirmation
Invoke-OfficeScrubC2R

# Silent removal without prompts
Invoke-OfficeScrubC2R -Quiet -Force

# Detection only
Invoke-OfficeScrubC2R -DetectOnly

# Keep licenses and use custom log path
Invoke-OfficeScrubC2R -KeepLicense -LogPath "C:\Logs"

Sources: OfficeScrubC2R.psm1:118-209, OfficeScrubC2R.ps1:924-1001


Remove-FileForced

Deletes a file using the native FileHelper with optional reboot scheduling for locked files.

Syntax:

Remove-FileForced -Path <string> [-ScheduleOnFail]

Parameters:

Parameter Type Required Description
Path String Yes Full path to file to delete
ScheduleOnFail Switch No Schedule for reboot if deletion fails

Return Value: Boolean ($true if deleted immediately, $false if scheduled for reboot)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.Files.DeleteFile()
  • If deletion fails and -ScheduleOnFail is set:
    • Adds to PendingFileRenameOperations
    • Sets $script:RebootRequired to $true
    • Sets ERROR_REBOOT_REQUIRED error code

Example:

$deleted = Remove-FileForced -Path "C:\Program Files\Microsoft Office\locked.dll" -ScheduleOnFail
if (-not $deleted) {
    Write-Host "File scheduled for deletion on reboot"
}

Sources: OfficeScrubC2R-Utilities.psm1:506-533


Remove-FolderRecursive

Recursively deletes a directory and all contents using the native FileHelper with 15x performance improvement over native PowerShell.

Syntax:

Remove-FolderRecursive -Path <string> [-Force]

Parameters:

Parameter Type Required Description
Path String Yes Full path to directory to delete
Force Switch No (Currently ignored; always forces deletion)

Return Value: Boolean ($true if deleted, $false if scheduled for reboot)

Behavior:

  • Returns $true immediately if path doesn't exist
  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.Files.DeleteDirectory(path, recursive=true, scheduleOnFail=true)
  • Uses optimized cmd.exe for large directory trees
  • Automatically schedules locked files for reboot
  • Sets $script:RebootRequired if any files are locked

Example:

Remove-FolderRecursive -Path "C:\Program Files\Microsoft Office\Office16" -Force

Sources: OfficeScrubC2R-Utilities.psm1:477-504


Remove-RegistryKey

Recursively deletes a registry key and all subkeys using the native RegistryHelper with 30x performance improvement.

Syntax:

Remove-RegistryKey -Hive <RegistryHiveType> -SubKey <string> [-Recursive]

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive enumeration value
SubKey String Yes Registry subkey path to delete
Recursive Switch No Delete subkeys recursively (default: $true)

Return Value: Boolean ($true if deleted successfully)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.Registry.DeleteKey() with WOW64 support
  • Logs operation to log file only
  • Handles both 32-bit and 64-bit registry views on 64-bit systems

Example:

Remove-RegistryKey -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\15.0\ClickToRun" -Recursive

Sources: OfficeScrubC2R-Utilities.psm1:407-423


Remove-RegistryValue

Deletes a single registry value using the native RegistryHelper.

Syntax:

Remove-RegistryValue -Hive <RegistryHiveType> -SubKey <string> -ValueName <string>

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive enumeration value
SubKey String Yes Registry subkey path containing the value
ValueName String Yes Name of the value to delete

Return Value: Boolean ($true if deleted successfully)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.Registry.DeleteValue()
  • Logs operation to log file only

Example:

Remove-RegistryValue -Hive LocalMachine `
    -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" `
    -ValueName "Lync15"

Sources: OfficeScrubC2R-Utilities.psm1:425-441


Remove-Service

Deletes a Windows service using the native ServiceHelper.

Syntax:

Remove-Service -ServiceName <string>

Parameters:

Parameter Type Required Description
ServiceName String Yes Name of the service to delete

Return Value: Boolean ($true if deleted successfully)

Behavior:

  • Skipped if $script:DetectOnly is $true
  • Calls $script:Orchestrator.Services.DeleteService()
  • Stops service if running before deletion
  • Logs success or failure

Example:

Remove-Service -ServiceName "ClickToRunSvc"
Remove-Service -ServiceName "OfficeSvc"

Sources: OfficeScrubC2R-Utilities.psm1:747-767


Set-ErrorCode

Sets specific error bits in the accumulated error code using bitwise OR, automatically cascading critical errors to the ERROR_FAIL flag.

Syntax:

Set-ErrorCode -ErrorBit <int>

Parameters:

Parameter Type Required Description
ErrorBit Int32 Yes Error code constant to set (e.g., $script:ERROR_STAGE1)

Return Value: None (void)

Behavior:

  • Uses bitwise OR to set specific error bits
  • Automatically sets ERROR_FAIL if setting critical errors:
    • ERROR_DCAF_FAILURE
    • ERROR_STAGE2
    • ERROR_ELEVATION_USERDECLINED
    • ERROR_ELEVATION
    • ERROR_SCRIPTINIT
  • Modifies $script:ErrorCode variable

Example:

Set-ErrorCode $script:ERROR_REBOOT_REQUIRED
if ($script:ErrorCode -band $script:ERROR_REBOOT_REQUIRED) {
    Write-Host "Reboot is required"
}

Sources: OfficeScrubC2R-Utilities.psm1:333-347


Set-RegistryValue

Sets a registry value using the native RegistryHelper.

Syntax:

Set-RegistryValue -Hive <RegistryHiveType> -SubKey <string> -ValueName <string> 
                  -Value <object> [-Kind <RegistryValueKind>]

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive enumeration value
SubKey String Yes Registry subkey path
ValueName String Yes Name of the value to set
Value Object Yes Value data to write
Kind RegistryValueKind No Value type (String, DWord, Binary, etc.); default: String

Return Value: Boolean ($true if set successfully)

Example:

Set-RegistryValue -Hive LocalMachine `
    -SubKey "SOFTWARE\Microsoft\Office\ClickToRun\Configuration" `
    -ValueName "UpdatesEnabled" `
    -Value 0 `
    -Kind DWord

Sources: OfficeScrubC2R-Utilities.psm1:394-405


Set-ReturnValue

Writes the final exit code to a return value file for process communication.

Syntax:

Set-ReturnValue -Value <int>

Parameters:

Parameter Type Required Description
Value Int32 Yes Exit code value to write

Return Value: None (void)

Behavior:

  • Creates file at $script:ScrubDir\ScrubRetValFile.txt
  • Writes value as plain text
  • Used for inter-process communication

Example:

Set-ReturnValue $script:ErrorCode

Sources: OfficeScrubC2R-Utilities.psm1:364-376


Stop-OfficeProcesses

Terminates all Office-related processes using the native ProcessHelper with parallel execution for improved performance.

Syntax:

Stop-OfficeProcesses [-Force]

Parameters:

Parameter Type Required Description
Force Switch No (Currently unused; always forces termination)

Return Value: None (void)

Behavior:

  • Gets process list from [OfficeScrubNative.OfficeConstants]::OFFICE_PROCESSES
  • Calls $script:Orchestrator.Processes.TerminateProcesses() with 10-second timeout
  • Logs number of terminated processes
  • Waits 2 seconds after termination for cleanup
  • Processes include: WINWORD.EXE, EXCEL.EXE, POWERPNT.EXE, OUTLOOK.EXE, etc.

Example:

Stop-OfficeProcesses
Write-Host "Office processes terminated"

Sources: OfficeScrubC2R-Utilities.psm1:549-562


Test-IsC2R

Tests whether a path string contains Click-to-Run indicators using the orchestrator's pattern matching.

Syntax:

Test-IsC2R -Path <string>

Parameters:

Parameter Type Required Description
Path String Yes File path or registry value to test

Return Value: Boolean ($true if path is C2R-related)

Behavior:

  • Requires Initialize-Environment to be called first
  • Calls $script:Orchestrator.IsC2RPath()
  • Checks for patterns like:
    • ClickToRun
    • Office15
    • Office16
    • root\Office16
    • root\VFS
    • integrator.exe

Example:

$isC2R = Test-IsC2R -Path "C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE"
if ($isC2R) {
    Write-Host "This is a C2R installation"
}

Sources: OfficeScrubC2R-Utilities.psm1:719-729


Test-IsElevated

Checks whether the current PowerShell session is running with Administrator privileges.

Syntax:

Test-IsElevated

Parameters: None

Return Value: Boolean ($true if elevated, $false otherwise)

Behavior:

  • Gets current Windows identity
  • Creates security principal
  • Checks for Administrator built-in role

Example:

if (-not (Test-IsElevated)) {
    Write-Warning "This script requires Administrator privileges"
    exit 1
}

Sources: OfficeScrubC2R-Utilities.psm1:213-217


Test-ProcessRunning

Checks whether a process with the specified name is currently running.

Syntax:

Test-ProcessRunning -ProcessName <string>

Parameters:

Parameter Type Required Description
ProcessName String Yes Name of process to check (with or without .exe)

Return Value: Boolean ($true if process is running)

Behavior:

  • Calls $script:Orchestrator.Processes.IsProcessRunning()
  • Case-insensitive comparison

Example:

if (Test-ProcessRunning -ProcessName "WINWORD") {
    Write-Host "Microsoft Word is running"
}

Sources: OfficeScrubC2R-Utilities.psm1:564-569


Test-ProductInScope

Determines whether a product GUID is within the scope of Office products to be removed.

Syntax:

Test-ProductInScope -ProductCode <string>

Parameters:

Parameter Type Required Description
ProductCode String Yes Product GUID in standard format {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

Return Value: Boolean ($true if product is in scope for removal)

Behavior:

  • Requires Initialize-Environment to be called first
  • Calls $script:Orchestrator.IsInScope()
  • Checks against known Office product GUID prefixes and patterns
  • Used for selective cleanup of Windows Installer metadata

Example:

$guid = "{90160000-002E-0000-0000-0000000FF1CE}"
if (Test-ProductInScope -ProductCode $guid) {
    Write-Host "Product $guid is an Office product"
}

Sources: OfficeScrubC2R-Utilities.psm1:731-741


Test-RegistryKeyExists

Checks whether a registry key exists using the native RegistryHelper.

Syntax:

Test-RegistryKeyExists -Hive <RegistryHiveType> -SubKey <string>

Parameters:

Parameter Type Required Description
Hive RegistryHiveType Yes Registry hive enumeration value
SubKey String Yes Registry subkey path to check

Return Value: Boolean ($true if key exists)

Example:

$exists = Test-RegistryKeyExists -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\ClickToRun"
if ($exists) {
    Write-Host "Office ClickToRun registry key found"
}

Sources: OfficeScrubC2R-Utilities.psm1:463-471


Write-Log

Writes a timestamped message to both console (unless quiet mode) and log file.

Syntax:

Write-Log -Message <string>

Parameters:

Parameter Type Required Description
Message String Yes Message text to log

Return Value: None (void)

Behavior:

  • Prepends timestamp in HH:mm:ss format
  • Writes to console unless $script:Quiet is $true
  • Writes to $script:LogStream if initialized

Example:

Write-Log "Beginning Office removal process"

Sources: OfficeScrubC2R-Utilities.psm1:294-308


Write-LogHeader

Writes a major section header with underline to log and console.

Syntax:

Write-LogHeader -Message <string>

Parameters:

Parameter Type Required Description
Message String Yes Header text

Return Value: None (void)

Behavior:

  • Creates underline with = characters matching message length
  • Displays in cyan color on console (unless quiet)
  • Adds blank line before header for spacing

Example:

Write-LogHeader "Stage # 1 - Uninstall"

Sources: OfficeScrubC2R-Utilities.psm1:260-275


Write-LogOnly

Writes a timestamped message to the log file only, without console output.

Syntax:

Write-LogOnly -Message <string>

Parameters:

Parameter Type Required Description
Message String Yes Message text to log

Return Value: None (void)

Behavior:

  • Prepends timestamp in HH:mm:ss format
  • Writes only to $script:LogStream
  • Does not display on console
  • Used for verbose logging without cluttering console

Example:

Write-LogOnly "Removing registry key: HKLM\SOFTWARE\Microsoft\Office\15.0\ClickToRun"

Sources: OfficeScrubC2R-Utilities.psm1:310-318


Write-LogSubHeader

Writes a sub-section header with underline to log and console.

Syntax:

Write-LogSubHeader -Message <string>

Parameters:

Parameter Type Required Description
Message String Yes Sub-header text

Return Value: None (void)

Behavior:

  • Creates underline with - characters matching message length
  • Displays in yellow color on console (unless quiet)
  • Adds blank line before sub-header for spacing

Example:

Write-LogSubHeader "Clean registry"

Sources: OfficeScrubC2R-Utilities.psm1:277-292


Error Code Constants

The following error code constants are exported as module variables and can be combined using bitwise operations:

Constant Value Description
ERROR_SUCCESS 0 Operation completed successfully
ERROR_FAIL 1 General failure
ERROR_REBOOT_REQUIRED 2 System reboot required to complete
ERROR_USERCANCEL 4 User cancelled operation
ERROR_STAGE1 8 Stage 1 (Uninstall) failed
ERROR_STAGE2 16 Stage 2 (Cleanup) failed
ERROR_INCOMPLETE 32 Removal incomplete, reboot needed
ERROR_DCAF_FAILURE 64 Second attempt cleanup failed
ERROR_ELEVATION_USERDECLINED 128 User declined elevation prompt
ERROR_ELEVATION 256 Elevation failed
ERROR_SCRIPTINIT 512 Script initialization error
ERROR_RELAUNCH 1024 Error during relaunch attempt
ERROR_UNKNOWN 2048 Unknown error occurred

Example:

if ($script:ErrorCode -band $script:ERROR_REBOOT_REQUIRED) {
    Write-Host "Reboot required"
}
if ($script:ErrorCode -band $script:ERROR_FAIL) {
    Write-Host "Operation failed"
}

Sources: OfficeScrubC2R-Utilities.psm1:9-22


Script-Level Variables

The following script-level variables are exported and accessible after module import:

graph TB
    subgraph "State Variables"
        ErrorCode["`$script:ErrorCode`<br/>Accumulated error flags"]
        RebootRequired["`$script:RebootRequired`<br/>Boolean reboot flag"]
        IsElevated["`$script:IsElevated`<br/>Admin check result"]
        Is64Bit["`$script:Is64Bit`<br/>64-bit OS detection"]
    end
    
    subgraph "Configuration Variables"
        Quiet["`$script:Quiet`<br/>Silent mode flag"]
        DetectOnly["`$script:DetectOnly`<br/>Detection mode flag"]
        Force["`$script:Force`<br/>Force removal flag"]
        KeepLicense["`$script:KeepLicense`<br/>Preserve licenses flag"]
        Offline["`$script:Offline`<br/>Offline mode flag"]
    end
    
    subgraph "Data Collections"
        InstalledSku["`$script:InstalledSku`<br/>Hashtable of products"]
        C2RSuite["`$script:C2RSuite`<br/>C2R product registry"]
        DelInUse["`$script:DelInUse`<br/>Pending deletes"]
    end
    
    subgraph "Path Variables"
        ProgramFiles["`$script:ProgramFiles`<br/>Program Files path"]
        ProgramData["`$script:ProgramData`<br/>ProgramData path"]
        LogDir["`$script:LogDir`<br/>Log directory"]
        ScrubDir["`$script:ScrubDir`<br/>Temp work directory"]
    end
    
    subgraph "Core Components"
        Orchestrator["`$script:Orchestrator`<br/>OfficeScrubOrchestrator<br/>Native C# instance"]
        LogStream["`$script:LogStream`<br/>StreamWriter instance"]
    end
    
    ErrorCode -.updated by.-> SetErrorCode["Set-ErrorCode"]
    ErrorCode -.updated by.-> ClearErrorCode["Clear-ErrorCode"]
    
    InstalledSku -.populated by.-> GetProducts["Get-InstalledOfficeProducts"]
    C2RSuite -.populated by.-> GetProducts
    
    Orchestrator -.initialized by.-> InitEnv["Initialize-Environment"]
    LogStream -.initialized by.-> InitLog["Initialize-Log"]
    
    DelInUse -.populated by.-> AddPending["Add-PendingFileDelete"]
Loading

Diagram: Script-Level Variable Dependencies

Sources: OfficeScrubC2R-Utilities.psm1:4-71, OfficeScrubC2R-Utilities.psm1:1047-1088


Common Usage Patterns

Pattern 1: Initialize and Detect

# Import module
Import-Module OfficeScrubC2R

# Environment is auto-initialized on import
# Detect installed products
$products = Get-InstalledOfficeProducts

if ($products.Count -gt 0) {
    Write-Host "Found $($products.Count) Office products:"
    foreach ($key in $products.Keys) {
        Write-Host "  - $key : $($products[$key])"
    }
}

Pattern 2: Silent Removal

# Import and run in silent mode
Import-Module OfficeScrubC2R
$exitCode = Invoke-OfficeScrubC2R -Quiet -Force -LogPath "C:\Logs"

if ($exitCode -eq 0) {
    Write-Host "Office removed successfully"
} elseif ($exitCode -band 2) {
    Write-Host "Reboot required to complete removal"
}

Pattern 3: Conditional Registry Cleanup

# Check if C2R key exists before removing
$keyExists = Test-RegistryKeyExists -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\ClickToRun"

if ($keyExists) {
    $version = Get-RegistryValue -Hive LocalMachine `
        -SubKey "SOFTWARE\Microsoft\Office\ClickToRun\Configuration" `
        -ValueName "VersionToReport"
    
    Write-Host "Found C2R version: $version"
    
    Remove-RegistryKey -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\ClickToRun"
}

Pattern 4: Custom Cleanup Sequence

# Initialize environment
Initialize-Environment
Initialize-Log -LogPath "C:\CustomLogs"

try {
    # Stop processes
    Stop-OfficeProcesses
    
    # Clean specific areas
    Clear-ShellIntegration
    Clear-TypeLibRegistrations
    Clear-WindowsInstallerMetadata
    
    # Clean registry
    Remove-RegistryKey -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\15.0"
    Remove-RegistryKey -Hive LocalMachine -SubKey "SOFTWARE\Microsoft\Office\16.0"
    
    Write-Host "Custom cleanup completed"
}
finally {
    Close-Log
}

Sources: OfficeScrubC2R.psm1:118-209, OfficeScrubC2R-Utilities.psm1:1-1091

Clone this wiki locally