Skip to content

PowerShell Module (OfficeScrubC2R.psm1)

Calvindd2f edited this page Jan 14, 2026 · 1 revision

PowerShell Module (OfficeScrubC2R.psm1)

Relevant source files

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

Purpose and Overview

The OfficeScrubC2R.psm1 file is the main PowerShell module that provides a lightweight wrapper around the native C# library (OfficeScrubNative.dll). It serves as the PowerShell-to-native bridge layer, exposing five core functions that enable PowerShell scripts to leverage high-performance native operations for Office Click-to-Run cleanup.

The module's responsibilities include:

  • Loading and caching the OfficeScrubNative.dll assembly
  • Creating instances of OfficeScrubOrchestrator from the native library
  • Providing PowerShell-friendly wrappers for C2R path and scope testing
  • Exposing access to specialized helper classes (RegistryHelper, FileHelper, etc.)
  • Managing assembly lifecycle and error handling

This is a thin orchestration layer—the heavy lifting is performed by the native C# code documented in section 4. For module metadata and PowerShell Gallery integration, see section 3.2.

Sources: OfficeScrubC2R.psm1:1-99, docs/memory-bank/structure.md:62-79


Module Structure and Initialization

The module consists of five exported functions and three script-level variables that manage the native assembly lifecycle.

Module-Level Variables

graph LR
    subgraph "Script Scope Variables"
        ModuleRoot["$script:ModuleRoot<br/>$PSScriptRoot<br/>Module directory path"]
        AssemblyPath["$script:NativeAssemblyPath<br/>Join-Path ModuleRoot<br/>'OfficeScrubNative.dll'"]
        Assembly["$script:NativeAssembly<br/>Cached assembly object<br/>Initially $null"]
    end
    
    subgraph "Initialization"
        Import["Import-Module<br/>OfficeScrubC2R"]
    end
    
    Import --> ModuleRoot
    ModuleRoot --> AssemblyPath
    AssemblyPath --> Assembly
Loading

Diagram: Script-level variables managing native assembly state

The module initializes three script-scope variables upon loading OfficeScrubC2R.psm1:6-8:

Variable Purpose Initial Value
$script:ModuleRoot Base directory for the module $PSScriptRoot (module's directory)
$script:NativeAssemblyPath Full path to OfficeScrubNative.dll Join-Path $script:ModuleRoot 'OfficeScrubNative.dll'
$script:NativeAssembly Cached reference to loaded assembly $null (lazy-loaded on first use)

This design enables lazy loading—the native DLL is only loaded when first accessed, reducing module import time and memory footprint.

Sources: OfficeScrubC2R.psm1:6-8

Exported Functions

graph TB
    subgraph "Public API"
        ImportNative["Import-OfficeScrubNative<br/>Load OfficeScrubNative.dll"]
        NewOrch["New-OfficeScrubOrchestrator<br/>Create OfficeScrubOrchestrator"]
        TestPath["Test-OfficeC2RPath<br/>Validate C2R paths"]
        TestScope["Test-OfficeProductScope<br/>Check product in scope"]
        GetHelpers["Get-OfficeScrubHelpers<br/>Access helper classes"]
    end
    
    subgraph "Native Layer"
        DLL["OfficeScrubNative.dll"]
        Orchestrator["OfficeScrubOrchestrator class"]
        Helpers["Helper Classes<br/>RegistryHelper, FileHelper, etc."]
    end
    
    ImportNative --> DLL
    NewOrch --> Orchestrator
    TestPath --> Orchestrator
    TestScope --> Orchestrator
    GetHelpers --> Helpers
Loading

Diagram: Five exported functions mapping to native layer components

The module exports exactly five functions OfficeScrubC2R.psm1:98:

  1. Import-OfficeScrubNative: Loads and caches the native assembly
  2. New-OfficeScrubOrchestrator: Factory function for orchestrator instances
  3. Test-OfficeC2RPath: Wrapper for Orchestrator.IsC2RPath() method
  4. Test-OfficeProductScope: Wrapper for Orchestrator.IsInScope() method
  5. Get-OfficeScrubHelpers: Returns PSCustomObject with all helper class references

Sources: OfficeScrubC2R.psm1:1-99


Assembly Loading: Import-OfficeScrubNative

The Import-OfficeScrubNative function implements a caching assembly loader with validation and error handling.

Function Signature and Parameters

function Import-OfficeScrubNative {
    [CmdletBinding()]
    param(
        [string]$Path = $script:NativeAssemblyPath
    )
}
Parameter Type Default Purpose
Path string $script:NativeAssemblyPath Custom path to OfficeScrubNative.dll (optional)

Sources: OfficeScrubC2R.psm1:10-15

Loading Logic and Caching Strategy

flowchart TD
    Start["Import-OfficeScrubNative<br/>-Path parameter"] --> Resolve["Resolve-Path -Path $Path<br/>Get absolute path"]
    
    Resolve --> PathCheck{"Test-Path<br/>$resolvedPath"}
    PathCheck -->|"Not Found"| ThrowError["throw 'Native assembly not found'"]
    PathCheck -->|"Exists"| CacheCheck{"$script:NativeAssembly<br/>already loaded?<br/>Location matches?"}
    
    CacheCheck -->|"Yes - cached"| ReturnCached["return $script:NativeAssembly"]
    CacheCheck -->|"No"| DomainCheck["GetAssemblies()<br/>Check AppDomain"]
    
    DomainCheck --> FindInDomain{"Find assembly<br/>by Location?"}
    FindInDomain -->|"Found"| CacheIt["$script:NativeAssembly = found"]
    FindInDomain -->|"Not Found"| LoadNew["Assembly::LoadFrom()<br/>Load from disk"]
    
    LoadNew --> CacheNew["$script:NativeAssembly = loaded"]
    CacheIt --> ReturnCached
    CacheNew --> ReturnCached
Loading

Diagram: Assembly loading sequence with three-tier caching strategy

The loading process implements a three-tier caching strategy OfficeScrubC2R.psm1:17-34:

Tier 1: Module-Level Cache Check OfficeScrubC2R.psm1:23-25

  • Checks if $script:NativeAssembly is already set
  • Verifies the cached assembly's Location matches the requested path
  • Returns cached assembly immediately if valid

Tier 2: AppDomain Assembly Search OfficeScrubC2R.psm1:27-28

  • Enumerates [AppDomain]::CurrentDomain.GetAssemblies()
  • Searches for assembly with matching Location property
  • Caches and returns if found (handles cases where assembly was loaded by another module)

Tier 3: File System Load OfficeScrubC2R.psm1:30-31

  • Calls [System.Reflection.Assembly]::LoadFrom($resolvedPath)
  • Loads DLL from disk into current AppDomain
  • Caches the loaded assembly for future calls

This multi-tier approach prevents redundant loads, handles assembly sharing across modules, and provides efficient caching.

Sources: OfficeScrubC2R.psm1:10-35

Error Handling and Path Validation

The function includes defensive validation OfficeScrubC2R.psm1:17-21:

  1. Path Resolution: Uses Resolve-Path -ErrorAction Stop to convert relative paths to absolute paths and validate existence
  2. File Type Validation: Verifies the resolved path points to a file (-PathType Leaf), not a directory
  3. Descriptive Error: Throws a clear error message if the DLL is missing, guiding users to ensure proper module installation

Sources: OfficeScrubC2R.psm1:17-21


Orchestrator Factory: New-OfficeScrubOrchestrator

The New-OfficeScrubOrchestrator function creates instances of the OfficeScrubOrchestrator class from the native library.

Function Signature and Architecture Detection

function New-OfficeScrubOrchestrator {
    [CmdletBinding()]
    param(
        [bool]$Is64Bit = [Environment]::Is64BitOperatingSystem
    )
}
Parameter Type Default Purpose
Is64Bit bool [Environment]::Is64BitOperatingSystem Configures orchestrator for 32-bit or 64-bit OS

Sources: OfficeScrubC2R.psm1:37-42

Instantiation Process

sequenceDiagram
    participant Caller
    participant Factory as New-OfficeScrubOrchestrator
    participant Import as Import-OfficeScrubNative
    participant Reflection as .NET Reflection
    participant Native as OfficeScrubNative.dll
    
    Caller->>Factory: New-OfficeScrubOrchestrator -Is64Bit $true
    Factory->>Import: Import-OfficeScrubNative
    Import->>Import: Check cache
    Import->>Native: Load assembly (if needed)
    Import-->>Factory: Return Assembly object
    
    Factory->>Reflection: [OfficeScrubNative.OfficeScrubOrchestrator]::new($Is64Bit)
    Reflection->>Native: Invoke constructor
    Native->>Native: Initialize helpers<br/>RegistryHelper, FileHelper, etc.
    Native-->>Reflection: Return orchestrator instance
    Reflection-->>Factory: Return instance
    Factory-->>Caller: Return orchestrator
Loading

Diagram: Orchestrator instantiation sequence showing assembly loading and constructor invocation

The factory function performs two operations OfficeScrubC2R.psm1:44-45:

  1. Assembly Loading: Calls Import-OfficeScrubNative | Out-Null to ensure the native DLL is loaded (output suppressed with Out-Null)
  2. Constructor Invocation: Uses PowerShell's type casting to instantiate [OfficeScrubNative.OfficeScrubOrchestrator]::new($Is64Bit)

The $Is64Bit parameter is critical—it determines whether the orchestrator uses native 64-bit registry views or WOW64 32-bit views. This affects all registry operations performed by RegistryHelper. For details on WOW64 handling, see section 2.5.

Sources: OfficeScrubC2R.psm1:37-46

Why a Factory Function?

The factory pattern provides several benefits:

  • Encapsulation: Hides the assembly loading complexity from consumers
  • Automatic Detection: Defaults to correct architecture without manual specification
  • Consistent Error Handling: Centralizes assembly loading errors in one place
  • Testability: Can be mocked/stubbed in unit tests

Users can create orchestrators with simple syntax:

$orchestrator = New-OfficeScrubOrchestrator

Sources: OfficeScrubC2R.psm1:37-46


Path and Scope Testing Functions

The module provides two lightweight wrapper functions for common validation operations.

Test-OfficeC2RPath Function

The Test-OfficeC2RPath function wraps the orchestrator's IsC2RPath() method to validate if a given path matches Click-to-Run installation patterns.

function Test-OfficeC2RPath {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$Path,
        [OfficeScrubNative.OfficeScrubOrchestrator]$Orchestrator
    )
}

Parameters:

Parameter Required Type Purpose
Path Yes string File system path to validate
Orchestrator No OfficeScrubOrchestrator Existing orchestrator (auto-created if omitted)

Sources: OfficeScrubC2R.psm1:48-53

Orchestrator Injection Pattern:

flowchart TD
    Call["Test-OfficeC2RPath<br/>-Path 'C:\\Program Files\\Microsoft Office'"] --> CheckParam{"$Orchestrator<br/>parameter provided?"}
    
    CheckParam -->|"No"| Create["New-OfficeScrubOrchestrator<br/>Create new instance"]
    CheckParam -->|"Yes"| Use["Use provided orchestrator"]
    
    Create --> Invoke["Orchestrator.IsC2RPath($Path)"]
    Use --> Invoke
    
    Invoke --> Native["OfficeScrubNative.dll<br/>IsC2RPath() method"]
    Native --> Patterns["Check against C2R patterns:<br/>*\\Office\\Data\\*<br/>*\\Microsoft Office\\root\\*"]
    Patterns --> Return["return [bool]"]
Loading

Diagram: Test-OfficeC2RPath workflow showing orchestrator auto-creation and native method delegation

The function implements an orchestrator injection pattern OfficeScrubC2R.psm1:55-57:

  • If the caller provides an $Orchestrator parameter, it's used directly
  • If omitted, a new orchestrator is created via New-OfficeScrubOrchestrator
  • The orchestrator's IsC2RPath($Path) method is invoked OfficeScrubC2R.psm1:59
  • Returns the boolean result directly

Sources: OfficeScrubC2R.psm1:48-60

Test-OfficeProductScope Function

The Test-OfficeProductScope function wraps the orchestrator's IsInScope() method to determine if a product code is within the cleanup scope.

function Test-OfficeProductScope {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$ProductCode,
        [OfficeScrubNative.OfficeScrubOrchestrator]$Orchestrator
    )
}

Parameters:

Parameter Required Type Purpose
ProductCode Yes string Office product GUID or identifier
Orchestrator No OfficeScrubOrchestrator Existing orchestrator (auto-created if omitted)

Sources: OfficeScrubC2R.psm1:62-67

Scope Validation Logic:

flowchart TD
    Call["Test-OfficeProductScope<br/>-ProductCode '{GUID}'"] --> CheckParam{"$Orchestrator<br/>parameter provided?"}
    
    CheckParam -->|"No"| Create["New-OfficeScrubOrchestrator<br/>Create new instance"]
    CheckParam -->|"Yes"| Use["Use provided orchestrator"]
    
    Create --> Invoke["Orchestrator.IsInScope($ProductCode)"]
    Use --> Invoke
    
    Invoke --> Native["OfficeScrubNative.dll<br/>IsInScope() method"]
    Native --> Check["Check against:<br/>- OfficeConstants.ProductCodes<br/>- OfficeConstants.UpgradeCodes<br/>- Pattern matching logic"]
    Check --> Return["return [bool]"]
Loading

Diagram: Test-OfficeProductScope workflow showing scope validation against product/upgrade code lists

The function uses the same injection pattern OfficeScrubC2R.psm1:69-73:

  • Auto-creates orchestrator if not provided
  • Delegates to Orchestrator.IsInScope($ProductCode) method
  • Returns boolean indicating if product is in cleanup scope

The IsInScope() method checks the product code against predefined lists in the native library's OfficeConstants class. This determines whether the product should be included in cleanup operations. For the complete list of product codes, see section 7.2.

Sources: OfficeScrubC2R.psm1:62-74

Why Wrapper Functions?

These wrappers provide PowerShell-idiomatic interfaces with:

  • Parameter Binding: Leverages PowerShell's [Parameter(Mandatory)] attribute
  • Auto-Creation: Eliminates boilerplate orchestrator creation for single-use scenarios
  • Type Safety: Declares explicit parameter types for IntelliSense support
  • Consistent Patterns: Matches PowerShell verb-noun naming conventions (Test-*)

Sources: OfficeScrubC2R.psm1:48-74


Helper Class Access: Get-OfficeScrubHelpers

The Get-OfficeScrubHelpers function provides PowerShell-friendly access to all eight specialized helper classes from the native library.

Function Design and Return Object

function Get-OfficeScrubHelpers {
    [CmdletBinding()]
    param(
        [OfficeScrubNative.OfficeScrubOrchestrator]$Orchestrator
    )
}

Parameters:

Parameter Required Type Purpose
Orchestrator No OfficeScrubOrchestrator Existing orchestrator (auto-created if omitted)

Sources: OfficeScrubC2R.psm1:76-80

Helper Class Mapping

graph TB
    subgraph "Get-OfficeScrubHelpers Function"
        Entry["Get-OfficeScrubHelpers<br/>-Orchestrator (optional)"]
    end
    
    subgraph "OfficeScrubOrchestrator Properties"
        Registry["Orchestrator.Registry<br/>RegistryHelper instance"]
        Files["Orchestrator.Files<br/>FileHelper instance"]
        Processes["Orchestrator.Processes<br/>ProcessHelper instance"]
        Shell["Orchestrator.Shell<br/>ShellHelper instance"]
        WI["Orchestrator.WindowsInstaller<br/>WindowsInstallerHelper instance"]
        TypeLib["Orchestrator.TypeLib<br/>TypeLibHelper instance"]
        License["Orchestrator.License<br/>LicenseHelper instance"]
        Services["Orchestrator.Services<br/>ServiceHelper instance"]
    end
    
    subgraph "Returned PSCustomObject"
        RetReg["RegistryHelper"]
        RetFiles["FileHelper"]
        RetProc["ProcessHelper"]
        RetShell["ShellHelper"]
        RetWI["WindowsInstallerHelper"]
        RetTL["TypeLibHelper"]
        RetLic["LicenseHelper"]
        RetSvc["ServiceHelper"]
    end
    
    Entry --> Registry
    Entry --> Files
    Entry --> Processes
    Entry --> Shell
    Entry --> WI
    Entry --> TypeLib
    Entry --> License
    Entry --> Services
    
    Registry --> RetReg
    Files --> RetFiles
    Processes --> RetProc
    Shell --> RetShell
    WI --> RetWI
    TypeLib --> RetTL
    License --> RetLic
    Services --> RetSvc
Loading

Diagram: Helper class extraction from orchestrator properties to PSCustomObject

The function returns a PSCustomObject with eight properties OfficeScrubC2R.psm1:86-95:

[pscustomobject]@{
    RegistryHelper         = $Orchestrator.Registry
    FileHelper             = $Orchestrator.Files
    ProcessHelper          = $Orchestrator.Processes
    ShellHelper            = $Orchestrator.Shell
    WindowsInstallerHelper = $Orchestrator.WindowsInstaller
    TypeLibHelper          = $Orchestrator.TypeLib
    LicenseHelper          = $Orchestrator.License
    ServiceHelper          = $Orchestrator.Services
}

Helper Class Summary:

Property Native Class Primary Responsibility
RegistryHelper RegistryHelper Registry operations with WOW64 support (section 4.3.1)
FileHelper FileHelper File/directory deletion with reboot scheduling (section 4.3.2)
ProcessHelper ProcessHelper Process termination with parallel execution (section 4.3.3)
WindowsInstallerHelper WindowsInstallerHelper MSI metadata cleanup (section 4.3.4)
ShellHelper ShellHelper Shell integration cleanup
TypeLibHelper TypeLibHelper COM type library cleanup
LicenseHelper LicenseHelper OSPP and SPP license operations
ServiceHelper ServiceHelper Windows service management

Sources: OfficeScrubC2R.psm1:76-96

Usage Pattern

This function enables direct access to helper class methods from PowerShell:

$helpers = Get-OfficeScrubHelpers
$helpers.RegistryHelper.DeleteKey("HKLM\Software\Microsoft\Office")
$helpers.FileHelper.DeleteDirectory("C:\Program Files\Microsoft Office")
$helpers.ProcessHelper.TerminateProcesses(@("WINWORD", "EXCEL"), 5000)

The pattern provides:

  • Discoverability: PowerShell's Get-Member reveals all available methods
  • Type Safety: IntelliSense shows method signatures and documentation
  • Reusability: Single orchestrator can be reused across multiple operations

Sources: OfficeScrubC2R.psm1:76-96


Integration with Native Layer

The module serves as the PowerShell-to-Native bridge, translating PowerShell conventions to C# method calls.

Assembly Type System Integration

graph TB
    subgraph "PowerShell Type System"
        PSTypes["PowerShell Type Accelerators"]
        TypeCast["Type Casting [Type]::new()"]
        ParamBinding["Parameter Type Binding"]
    end
    
    subgraph "Module Functions"
        Import["Import-OfficeScrubNative"]
        NewOrch["New-OfficeScrubOrchestrator"]
        TestPath["Test-OfficeC2RPath"]
        TestScope["Test-OfficeProductScope"]
        GetHelpers["Get-OfficeScrubHelpers"]
    end
    
    subgraph "Native Assembly Types"
        Orch["[OfficeScrubNative.OfficeScrubOrchestrator]"]
        RegHelper["[OfficeScrubNative.RegistryHelper]"]
        FileHelper["[OfficeScrubNative.FileHelper]"]
        ProcHelper["[OfficeScrubNative.ProcessHelper]"]
        ShellHelper["[OfficeScrubNative.ShellHelper]"]
        WIHelper["[OfficeScrubNative.WindowsInstallerHelper]"]
        TypeLibHelper["[OfficeScrubNative.TypeLibHelper]"]
        LicenseHelper["[OfficeScrubNative.LicenseHelper]"]
        ServiceHelper["[OfficeScrubNative.ServiceHelper]"]
    end
    
    Import --> PSTypes
    PSTypes --> Orch
    NewOrch --> TypeCast
    TypeCast --> Orch
    
    TestPath --> ParamBinding
    TestScope --> ParamBinding
    GetHelpers --> ParamBinding
    ParamBinding --> Orch
    
    Orch --> RegHelper
    Orch --> FileHelper
    Orch --> ProcHelper
    Orch --> ShellHelper
    Orch --> WIHelper
    Orch --> TypeLibHelper
    Orch --> LicenseHelper
    Orch --> ServiceHelper
Loading

Diagram: Type system integration showing how PowerShell functions bridge to native C# classes

The module leverages PowerShell's type system features:

Type Loading OfficeScrubC2R.psm1:31

  • [System.Reflection.Assembly]::LoadFrom() loads the DLL into the current AppDomain
  • All types in the assembly become available to PowerShell
  • Types can be referenced using full CLR names: [OfficeScrubNative.OfficeScrubOrchestrator]

Type Casting and Instantiation OfficeScrubC2R.psm1:45

  • PowerShell's ::new() syntax calls .NET constructors
  • Constructor overloads are automatically resolved
  • Example: [OfficeScrubNative.OfficeScrubOrchestrator]::new($true)

Parameter Type Binding OfficeScrubC2R.psm1:52,66,79

  • Functions declare C# types in parameter definitions
  • PowerShell performs automatic type conversion
  • IntelliSense provides method/property completion

Sources: OfficeScrubC2R.psm1:1-99

Performance Delegation Pattern

sequenceDiagram
    participant User as PowerShell User
    participant Module as OfficeScrubC2R.psm1
    participant Orch as OfficeScrubOrchestrator
    participant Helper as Helper Classes
    participant WinAPI as Win32 APIs
    
    User->>Module: Import-OfficeScrubNative
    Module->>Module: Load OfficeScrubNative.dll
    
    User->>Module: New-OfficeScrubOrchestrator
    Module->>Orch: Create instance
    Orch->>Helper: Initialize 8 helpers
    Orch-->>Module: Return orchestrator
    
    User->>Module: Test-OfficeC2RPath
    Module->>Orch: IsC2RPath($Path)
    Orch->>Orch: Pattern matching (native C#)
    Orch-->>Module: Return bool
    
    User->>Module: Get-OfficeScrubHelpers
    Module->>Orch: Access .Registry, .Files, etc.
    Orch-->>Module: Return helper references
    
    User->>Helper: DeleteKey("HKLM\\Software\\...")
    Helper->>WinAPI: RegDeleteKeyEx (P/Invoke)
    WinAPI-->>Helper: Return status
    Helper-->>User: Return bool
Loading

Diagram: Performance delegation showing how PowerShell operations delegate to optimized native code

The module follows a delegation pattern where:

  1. PowerShell handles: User interaction, parameter validation, orchestration workflow
  2. Native C# handles: Performance-critical operations (registry enumeration, file operations, process management)
  3. Win32 APIs handle: Direct OS integration via P/Invoke

This hybrid architecture achieves 10-50x performance improvements over pure PowerShell implementations while maintaining PowerShell's user-friendly interface.

Sources: OfficeScrubC2R.psm1:1-99, docs/memory-bank/structure.md:80-106


Module Exports and API Surface

The module declares its public API through explicit exports, following PowerShell best practices.

Export Declaration

Export-ModuleMember -Function Import-OfficeScrubNative, 
                              New-OfficeScrubOrchestrator, 
                              Test-OfficeC2RPath, 
                              Test-OfficeProductScope, 
                              Get-OfficeScrubHelpers

Sources: OfficeScrubC2R.psm1:98

Public API Surface

graph TB
    subgraph "Exported Functions"
        F1["Import-OfficeScrubNative<br/>Load native assembly"]
        F2["New-OfficeScrubOrchestrator<br/>Create orchestrator instance"]
        F3["Test-OfficeC2RPath<br/>Validate C2R paths"]
        F4["Test-OfficeProductScope<br/>Check product in scope"]
        F5["Get-OfficeScrubHelpers<br/>Access helper classes"]
    end
    
    subgraph "Native Types Exposed"
        T1["[OfficeScrubNative.OfficeScrubOrchestrator]"]
        T2["[OfficeScrubNative.RegistryHelper]"]
        T3["[OfficeScrubNative.FileHelper]"]
        T4["[OfficeScrubNative.ProcessHelper]"]
        T5["[OfficeScrubNative.*Helper]<br/>5 additional helpers"]
    end
    
    subgraph "User Code"
        Import["Import-Module<br/>OfficeScrubC2R"]
        Usage["User Scripts"]
    end
    
    Import --> F1
    Import --> F2
    Import --> F3
    Import --> F4
    Import --> F5
    
    F1 --> T1
    F2 --> T1
    F5 --> T2
    F5 --> T3
    F5 --> T4
    F5 --> T5
    
    F1 --> Usage
    F2 --> Usage
    F3 --> Usage
    F4 --> Usage
    F5 --> Usage
Loading

Diagram: Public API showing five exported functions and their relationship to native types

The explicit export pattern ensures:

  • Controlled API Surface: Only these five functions are publicly accessible
  • Semantic Versioning: Breaking changes to these functions require major version bump
  • Discoverability: Get-Command -Module OfficeScrubC2R shows only exported functions
  • IntelliSense Support: PowerShell ISE/VSCode provide completion for exported functions

Sources: OfficeScrubC2R.psm1:98

Module Discoverability

Users can discover the module's capabilities through standard PowerShell commands:

# List all exported functions
Get-Command -Module OfficeScrubC2R

# View function help
Get-Help New-OfficeScrubOrchestrator -Detailed

# Explore orchestrator methods
$orch = New-OfficeScrubOrchestrator
$orch | Get-Member

Sources: OfficeScrubC2R.psm1:1-99


Relationship to Other Components

The root module acts as the orchestration layer connecting user input to the execution pipeline:

graph LR
    User["User/Script"]
    
    subgraph "OfficeScrubC2R.psm1"
        Entry["Invoke-OfficeScrubC2R<br/>Parameter processing"]
        VarMap["Variable mapping<br/>$script:* variables"]
        CallMain["Main() invocation"]
    end
    
    subgraph "OfficeScrubC2R.ps1"
        Main["Main()<br/>Pipeline orchestrator"]
        Stage0["Stage 0: Detection"]
        Stage1["Stage 1: Uninstall"]
        Stage2["Stage 2: Cleanup"]
    end
    
    subgraph "OfficeScrubC2R-Utilities.psm1"
        Utils["Utility functions<br/>Registry, File, Process ops"]
    end
    
    subgraph "OfficeScrubNative.dll"
        Orchestrator["OfficeScrubOrchestrator<br/>Native helpers"]
    end
    
    User -->|Invoke-OfficeScrubC2R| Entry
    Entry --> VarMap
    VarMap --> CallMain
    CallMain --> Main
    Main --> Stage0
    Main --> Stage1
    Main --> Stage2
    Stage0 --> Utils
    Stage1 --> Utils
    Stage2 --> Utils
    Utils --> Orchestrator
Loading

Diagram: Component relationships showing data flow from user input through the module layers to native code execution

  • To Main Script OfficeScrubC2R.ps1: The root module delegates all execution logic to the Main function
  • To Utilities OfficeScrubC2R-Utilities.psm1: The root module imports utilities globally and exports selected utility functions
  • To Manifest OfficeScrubC2R.psd1: The manifest references this file as the RootModule
  • To Native Library: Indirectly through utilities module which wraps OfficeScrubOrchestrator

Sources: OfficeScrubC2R.psm1:1-233

Clone this wiki locally