Repository navigation
PowerShell Module (OfficeScrubC2R.psm1)
Relevant source files
The following files were used as context for generating this wiki page:
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.dllassembly - Creating instances of
OfficeScrubOrchestratorfrom 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
The module consists of five exported functions and three script-level variables that manage the native assembly lifecycle.
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
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
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
Diagram: Five exported functions mapping to native layer components
The module exports exactly five functions OfficeScrubC2R.psm1:98:
- Import-OfficeScrubNative: Loads and caches the native assembly
- New-OfficeScrubOrchestrator: Factory function for orchestrator instances
-
Test-OfficeC2RPath: Wrapper for
Orchestrator.IsC2RPath()method -
Test-OfficeProductScope: Wrapper for
Orchestrator.IsInScope()method - Get-OfficeScrubHelpers: Returns PSCustomObject with all helper class references
Sources: OfficeScrubC2R.psm1:1-99
The Import-OfficeScrubNative function implements a caching assembly loader with validation and error handling.
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
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
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:NativeAssemblyis already set - Verifies the cached assembly's
Locationmatches 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
Locationproperty - 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
The function includes defensive validation OfficeScrubC2R.psm1:17-21:
-
Path Resolution: Uses
Resolve-Path -ErrorAction Stopto convert relative paths to absolute paths and validate existence -
File Type Validation: Verifies the resolved path points to a file (
-PathType Leaf), not a directory - Descriptive Error: Throws a clear error message if the DLL is missing, guiding users to ensure proper module installation
Sources: OfficeScrubC2R.psm1:17-21
The New-OfficeScrubOrchestrator function creates instances of the OfficeScrubOrchestrator class from the native library.
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
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
Diagram: Orchestrator instantiation sequence showing assembly loading and constructor invocation
The factory function performs two operations OfficeScrubC2R.psm1:44-45:
-
Assembly Loading: Calls
Import-OfficeScrubNative | Out-Nullto ensure the native DLL is loaded (output suppressed withOut-Null) -
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
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-OfficeScrubOrchestratorSources: OfficeScrubC2R.psm1:37-46
The module provides two lightweight wrapper functions for common validation operations.
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]"]
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
$Orchestratorparameter, 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
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]"]
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
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
The Get-OfficeScrubHelpers function provides PowerShell-friendly access to all eight specialized helper classes from the native library.
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
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
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
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
The module serves as the PowerShell-to-Native bridge, translating PowerShell conventions to C# method calls.
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
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
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
Diagram: Performance delegation showing how PowerShell operations delegate to optimized native code
The module follows a delegation pattern where:
- PowerShell handles: User interaction, parameter validation, orchestration workflow
- Native C# handles: Performance-critical operations (registry enumeration, file operations, process management)
- 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
The module declares its public API through explicit exports, following PowerShell best practices.
Export-ModuleMember -Function Import-OfficeScrubNative,
New-OfficeScrubOrchestrator,
Test-OfficeC2RPath,
Test-OfficeProductScope,
Get-OfficeScrubHelpersSources: OfficeScrubC2R.psm1:98
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
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 OfficeScrubC2Rshows only exported functions - IntelliSense Support: PowerShell ISE/VSCode provide completion for exported functions
Sources: OfficeScrubC2R.psm1:98
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-MemberSources: OfficeScrubC2R.psm1:1-99
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
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
Mainfunction - 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