Skip to content

Module Manifest (OfficeScrubC2R.psd1)

Calvindd2f edited this page Jan 14, 2026 · 1 revision

Module Manifest (OfficeScrubC2R.psd1)

Relevant source files

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

Purpose and Scope

The module manifest (OfficeScrubC2R.psd1) is a PowerShell data file that defines the module's metadata, exported functions, dependencies, and loading behavior. It serves as the entry point for module import operations and PowerShell Gallery publishing.

The manifest specifies that OfficeScrubC2R.psm1 is the RootModule and defines five helper functions that wrap the native OfficeScrubNative.dll library. The v3.0.0 architecture represents a streamlined design where the PowerShell layer is a thin wrapper around the native C# library, with the original VBScript and direct conversion sources retained for reference.

For information about the PowerShell module's implementation, see PowerShell Module (OfficeScrubC2R.psm1). For the native library architecture, see Native Library Overview.


Module Manifest Structure

The manifest is a hashtable stored in a .psd1 file. PowerShell reads this hashtable during Import-Module to validate requirements and load the module components.

Manifest Loading Sequence

sequenceDiagram
    participant PS as "PowerShell Engine"
    participant Manifest as "OfficeScrubC2R.psd1"
    participant Root as "OfficeScrubC2R.psm1"
    participant Native as "OfficeScrubNative.dll"
    
    PS->>Manifest: "Import-Module OfficeScrubC2R"
    Note over Manifest: "Parse hashtable<br/>Validate structure"
    
    Manifest->>Manifest: "Check PowerShellVersion >= 5.1"
    Manifest->>Manifest: "Check DotNetFrameworkVersion >= 4.5"
    Manifest->>Manifest: "Check CompatiblePSEditions"
    
    Note over Manifest: "RequiredAssemblies = @()<br/>NestedModules = @()<br/>(Both empty)"
    
    Manifest->>Root: "Load RootModule"
    Note over Root: "Execute module script<br/>Import-OfficeScrubNative"
    
    Root->>Native: "Dynamic load via reflection"
    Note over Native: "Add-Type or [Reflection.Assembly]::LoadFrom"
    Native-->>Root: "Types available"
    
    Root-->>Manifest: "Define and export functions"
    
    Manifest->>Manifest: "Export-ModuleMember"
    Note over Manifest: "FunctionsToExport (5 functions)<br/>AliasesToExport = @()"
    
    Manifest-->>PS: "Module ready"
Loading

Sources: OfficeScrubC2R.psd1:1-157


Module Metadata

The manifest defines metadata for module identification and PowerShell Gallery publishing.

Field Value Purpose
ModuleVersion 3.0.0 Current version (semantic versioning)
GUID f8e7c4d1-5a3b-4e2d-9c8f-1b6a4d7e9c3a Unique module identifier
Author Calvin Module author
CompanyName @Calvindd2f Publisher identifier
Copyright (c) 2025 Calvin. All rights reserved. MIT License. Derived from Microsoft OffScrubC2R.vbs. License and attribution
CompatiblePSEditions @('Desktop', 'Core') Both Windows PowerShell 5.1+ and PowerShell 7+

OfficeScrubC2R.psd1:6, OfficeScrubC2R.psd1:12, OfficeScrubC2R.psd1:15, OfficeScrubC2R.psd1:18, OfficeScrubC2R.psd1:21, OfficeScrubC2R.psd1:9

The Description field documents the module's architecture:

OfficeScrubC2R.psd1:24-26

This description emphasizes that the PowerShell module is a lightweight wrapper that exposes the native DLL's functionality through helper functions. The original VBScript source and C# direct conversion remain in the repository for reference and comparison.

Sources: OfficeScrubC2R.psd1:6-26


Dependencies and Requirements

The manifest specifies runtime requirements validated during module import.

Version Requirements

graph TB
    Manifest["OfficeScrubC2R.psd1"]
    
    subgraph "Runtime Requirements"
        PSVer["PowerShellVersion: 5.1"]
        DotNetVer["DotNetFrameworkVersion: 4.5"]
        ProcArch["ProcessorArchitecture: None"]
    end
    
    subgraph "Edition Support"
        Desktop["CompatiblePSEditions:<br/>Desktop"]
        Core["CompatiblePSEditions:<br/>Core"]
    end
    
    subgraph "Module Dependencies"
        RequiredMods["RequiredModules = @()"]
        RequiredAsm["RequiredAssemblies = @()"]
    end
    
    Manifest --> PSVer
    Manifest --> DotNetVer
    Manifest --> ProcArch
    Manifest --> Desktop
    Manifest --> Core
    Manifest --> RequiredMods
    Manifest --> RequiredAsm
    
    Note1["OfficeScrubNative.dll<br/>loaded dynamically<br/>by root module"]
    RequiredAsm -.not in manifest.-> Note1
Loading

OfficeScrubC2R.psd1:29, OfficeScrubC2R.psd1:32, OfficeScrubC2R.psd1:35, OfficeScrubC2R.psd1:9

Assembly Loading Strategy

OfficeScrubC2R.psd1:40-43

The RequiredAssemblies field is empty. OfficeScrubNative.dll is loaded dynamically by the Import-OfficeScrubNative function in the root module to avoid conflicts when the assembly is already loaded in the PowerShell session. This provides flexibility for multiple import/reload scenarios during development and testing.

Sources: OfficeScrubC2R.psd1:29-43


Module Structure Definition

The manifest defines a simplified module structure with no nested modules or pre-loaded assemblies.

Root Module Structure

graph TB
    Manifest["OfficeScrubC2R.psd1"]
    
    subgraph "Manifest Fields"
        RootField["RootModule:<br/>'OfficeScrubC2R.psm1'"]
        NestedField["NestedModules = @()"]
        AssemblyField["RequiredAssemblies = @()"]
    end
    
    subgraph "Root Module Contents"
        ImportFunc["Import-OfficeScrubNative<br/>(Dynamic DLL loader)"]
        NewOrch["New-OfficeScrubOrchestrator<br/>(Factory function)"]
        TestPath["Test-OfficeC2RPath<br/>(Path validator)"]
        TestScope["Test-OfficeProductScope<br/>(Product filter)"]
        GetHelpers["Get-OfficeScrubHelpers<br/>(Helper accessor)"]
    end
    
    Manifest --> RootField
    Manifest --> NestedField
    Manifest --> AssemblyField
    
    RootField --> ImportFunc
    RootField --> NewOrch
    RootField --> TestPath
    RootField --> TestScope
    RootField --> GetHelpers
    
    ImportFunc -.dynamically loads.-> NativeDLL["OfficeScrubNative.dll"]
Loading
Field Value Purpose
RootModule OfficeScrubC2R.psm1 Main module script containing all exported functions
NestedModules @() No nested modules
RequiredAssemblies @() No pre-loaded assemblies (DLL loaded dynamically)

OfficeScrubC2R.psd1:3, OfficeScrubC2R.psd1:55, OfficeScrubC2R.psd1:40-43

This streamlined structure eliminates nested modules and static assembly loading. The root module handles all functionality, including dynamic loading of OfficeScrubNative.dll through the Import-OfficeScrubNative function.

Sources: OfficeScrubC2R.psd1:3, OfficeScrubC2R.psd1:40-43, OfficeScrubC2R.psd1:55


Exported Functions

The manifest explicitly declares exported functions for performance and API documentation.

FunctionsToExport List

OfficeScrubC2R.psd1:58-64

The module exports five wrapper functions that provide access to the native library:

Function Purpose Native Component
Import-OfficeScrubNative Loads OfficeScrubNative.dll dynamically Reflection assembly loading
New-OfficeScrubOrchestrator Creates OfficeScrubOrchestrator instance OfficeScrubOrchestrator class
Test-OfficeC2RPath Validates Click-to-Run installation paths Pattern matching logic
Test-OfficeProductScope Filters products by scope criteria IsInScope() delegate
Get-OfficeScrubHelpers Returns helper class instances RegistryHelper, FileHelper, etc.

Function-to-Native Mapping

graph TB
    subgraph "PowerShell Functions"
        ImportFunc["Import-OfficeScrubNative"]
        NewOrch["New-OfficeScrubOrchestrator"]
        TestPath["Test-OfficeC2RPath"]
        TestScope["Test-OfficeProductScope"]
        GetHelpers["Get-OfficeScrubHelpers"]
    end
    
    subgraph "OfficeScrubNative.dll Classes"
        Orch["OfficeScrubOrchestrator"]
        RegHelper["RegistryHelper"]
        FileHelper["FileHelper"]
        ProcHelper["ProcessHelper"]
        WIHelper["WindowsInstallerHelper"]
        TypeLib["TypeLibHelper"]
        License["LicenseHelper"]
        Service["ServiceHelper"]
        Shell["ShellHelper"]
        Guid["GuidHelper"]
    end
    
    ImportFunc -.loads.-> Orch
    NewOrch --> Orch
    GetHelpers --> RegHelper
    GetHelpers --> FileHelper
    GetHelpers --> ProcHelper
    GetHelpers --> WIHelper
    GetHelpers --> TypeLib
    GetHelpers --> License
    GetHelpers --> Service
    GetHelpers --> Shell
    GetHelpers --> Guid
Loading

No Exported Aliases

OfficeScrubC2R.psd1:73

The AliasesToExport field is an empty array. The v3.0.0 architecture does not provide command aliases, requiring explicit function names for clarity.

Sources: OfficeScrubC2R.psd1:58-64, OfficeScrubC2R.psd1:67, OfficeScrubC2R.psd1:70, OfficeScrubC2R.psd1:73


File List and Packaging

The FileList field documents files included in the PowerShell Gallery package.

File List (v3.0.0)

OfficeScrubC2R.psd1:82-91

File Purpose Required
OfficeScrubC2R.psd1 Module manifest Yes
OfficeScrubC2R.psm1 Root module with helper functions Yes
OfficeScrubNative.dll Pre-compiled native library Yes
OfficeScrubC2R-Native.cs C# source code Yes (reference)
direct_conversion.cs Direct VBScript-to-C# conversion Yes (reference)
docs\source\OfficeScrubC2R.vbs Original Microsoft VBScript Yes (reference)
LICENSE MIT license file Yes
README.md User documentation Yes

File List Architecture

graph TB
    subgraph "Core Runtime"
        Manifest["OfficeScrubC2R.psd1<br/>(Manifest)"]
        Module["OfficeScrubC2R.psm1<br/>(PowerShell wrapper)"]
        DLL["OfficeScrubNative.dll<br/>(Native library)"]
    end
    
    subgraph "Reference Sources"
        NativeCS["OfficeScrubC2R-Native.cs<br/>(Optimized C#)"]
        DirectCS["direct_conversion.cs<br/>(Direct conversion)"]
        VBS["docs/source/OfficeScrubC2R.vbs<br/>(Original VBScript)"]
    end
    
    subgraph "Documentation"
        License["LICENSE<br/>(MIT)"]
        Readme["README.md<br/>(Usage guide)"]
    end
    
    Manifest --> Module
    Module --> DLL
    
    NativeCS -.compiled to.-> DLL
    DirectCS -.reference.-> NativeCS
    VBS -.original source.-> DirectCS
Loading

The v3.0.0 architecture includes three implementations side-by-side:

  1. Original VBScript (docs\source\OfficeScrubC2R.vbs) - Microsoft's implementation
  2. Direct Conversion (direct_conversion.cs) - Line-by-line C# port maintaining VBScript structure
  3. Optimized Implementation (OfficeScrubC2R-Native.cs) - Rewritten with performance optimizations

Users interact with the compiled DLL through the PowerShell wrapper. The source files provide transparency and enable build-from-source scenarios.

Sources: OfficeScrubC2R.psd1:82-91


PowerShell Gallery Metadata

The PrivateData.PSData hashtable contains metadata for PowerShell Gallery publishing and module discovery.

Tags for Module Discovery

OfficeScrubC2R.psd1:97-112

Tags enable search and categorization on PowerShell Gallery:

Category Tags
Product Office, Microsoft, Office365, O365
Technology ClickToRun, C2R
Purpose Uninstall, Removal, Scrub, Maintenance
Platform Windows, Administration
Edition PSEdition_Desktop, PSEdition_Core

URIs and Documentation Links

OfficeScrubC2R.psd1:115, OfficeScrubC2R.psd1:118, OfficeScrubC2R.psd1:153

graph LR
    PSGallery["PowerShell Gallery<br/>Module Page"]
    
    LicenseUri["LicenseUri"]
    ProjectUri["ProjectUri"]
    HelpUri["HelpInfoURI"]
    
    GitHub["GitHub Repository<br/>Calvindd2f/OfficeScrubC2R"]
    
    PSGallery --> LicenseUri
    PSGallery --> ProjectUri
    PSGallery --> HelpUri
    
    LicenseUri --> GitHub
    ProjectUri --> GitHub
    HelpUri --> GitHub
Loading

Release Notes (v3.0.0)

OfficeScrubC2R.psd1:124-137

The inline release notes document the v3.0.0 architectural changes:

  • Streamlined PowerShell module focused on loading the native binary
  • Helper functions for creating the orchestrator and checking product scope
  • Repository cleaned to highlight the native binary alongside the original sources
  • Legacy script-based functions removed in favor of the native wrapper

Publishing Configuration

OfficeScrubC2R.psd1:143, OfficeScrubC2R.psd1:146

RequireLicenseAcceptance = $false
ExternalModuleDependencies = @()

The module does not require license acceptance (MIT license) and has no external module dependencies.

Sources: OfficeScrubC2R.psd1:94-150


Version Compatibility Matrix

The manifest defines compatibility requirements across PowerShell editions and .NET Framework versions.

Component Minimum Version Notes
PowerShell 5.1 Both Desktop and Core editions
.NET Framework 4.5 Required for OfficeScrubNative.dll
Windows 7 SP1+ Server 2012+ also supported
Architecture x86 or x64 Native library compiled as AnyCPU

OfficeScrubC2R.psd1:29, OfficeScrubC2R.psd1:32, OfficeScrubC2R.psd1:35, OfficeScrubC2R.psd1:9

Edition Compatibility

graph TB
    Module["OfficeScrubC2R<br/>v3.0.0"]
    
    subgraph "PowerShell Desktop"
        Desktop["Windows PowerShell 5.1"]
        DesktopDotNet[".NET Framework 4.5+"]
    end
    
    subgraph "PowerShell Core"
        Core["PowerShell 7.0+"]
        CoreDotNet[".NET Core Runtime<br/>+ Windows Compatibility Pack"]
    end
    
    Module --> Desktop
    Module --> Core
    
    Desktop --> DesktopDotNet
    Core --> CoreDotNet
Loading

The CompatiblePSEditions field ensures the module works in both Windows PowerShell 5.1 (Desktop edition) and PowerShell 7+ (Core edition). The native DLL targets .NET Framework 4.5, which is available on both platforms through the Windows Compatibility Pack in PowerShell Core.

Sources: OfficeScrubC2R.psd1:9, OfficeScrubC2R.psd1:29, OfficeScrubC2R.psd1:32


Manifest Validation

PowerShell validates the manifest during Import-Module and Publish-Module operations.

Import Validation Flow

graph TB
    Start["Import-Module OfficeScrubC2R"]
    
    ParseManifest["Parse .psd1 hashtable"]
    ValidateStructure["Validate hashtable structure"]
    CheckPS["Check PowerShellVersion >= 5.1"]
    CheckDotNet["Check DotNetFrameworkVersion >= 4.5"]
    CheckEdition["Check CompatiblePSEditions"]
    CheckFiles["Verify FileList entries"]
    LoadRoot["Load RootModule"]
    ExportFunctions["Export FunctionsToExport"]
    
    Success["Module ready"]
    FailStructure["Error: Invalid manifest syntax"]
    FailPS["Error: PowerShell version incompatible"]
    FailDotNet["Error: .NET Framework not found"]
    FailEdition["Error: PSEdition incompatible"]
    FailRoot["Error: RootModule failed to load"]
    
    Start --> ParseManifest
    ParseManifest -->|Valid| ValidateStructure
    ParseManifest -->|Invalid| FailStructure
    
    ValidateStructure --> CheckPS
    CheckPS -->|Pass| CheckDotNet
    CheckPS -->|Fail| FailPS
    
    CheckDotNet -->|Pass| CheckEdition
    CheckDotNet -->|Fail| FailDotNet
    
    CheckEdition -->|Pass| CheckFiles
    CheckEdition -->|Fail| FailEdition
    
    CheckFiles --> LoadRoot
    LoadRoot -->|Success| ExportFunctions
    LoadRoot -->|Fail| FailRoot
    
    ExportFunctions --> Success
Loading

Test-ModuleManifest

The manifest is validated using Test-ModuleManifest:

Test-ModuleManifest -Path .\OfficeScrubC2R.psd1

This cmdlet verifies:

  • Hashtable syntax is valid PowerShell
  • Required fields are present (ModuleVersion, GUID, Author)
  • RootModule file exists
  • FunctionsToExport are valid PowerShell identifiers
  • FileList entries exist (warning if missing)

Sources: OfficeScrubC2R.psd1:1-157


Summary

The module manifest (OfficeScrubC2R.psd1) serves as the definitive source for module configuration and metadata. Key aspects:

  1. Version Management: Semantic versioning with critical fix history (v2.19.1 → v2.19.2)
  2. Dependency Declaration: Explicit requirements for PowerShell, .NET Framework, and native DLL
  3. Module Structure: Defines loading order (assemblies → nested modules → root module)
  4. Public API: Explicitly exports five functions and two aliases
  5. Package Definition: FileList ensures all required files are distributed (v2.19.2 fix)
  6. Gallery Metadata: Tags, URIs, and release notes for discoverability and documentation

The v2.19.2 release demonstrates the critical importance of the FileList field for module distribution. Without OfficeScrubC2R.ps1 included in the package, the module cannot function despite importing successfully.

Sources: OfficeScrubC2R.psd1:1-175, docs/CHANGELOG.md:8-33

Clone this wiki locally