Repository navigation
Installation
Relevant source files
The following files were used as context for generating this wiki page:
This document covers the installation process for the OfficeScrubC2R PowerShell module, including the three supported installation methods, module loading mechanisms, and post-installation verification. For system prerequisites, see System Requirements. For usage instructions after installation, see Quick Start.
OfficeScrubC2R supports three installation methods: PowerShell Gallery (recommended), GitHub clone, and manual installation. All methods require administrator privileges for full functionality during execution, though the module itself can be installed in user scope.
The PowerShell Gallery provides the simplest installation path and automatic updates. The module is published as OfficeScrubC2R and can be installed using Install-Module.
# Install for current user only (no admin required)
Install-Module -Name OfficeScrubC2R -Scope CurrentUser
# Install system-wide (requires administrator)
Install-Module -Name OfficeScrubC2R -Scope AllUsersThe -Scope CurrentUser option installs to $HOME\Documents\PowerShell\Modules\OfficeScrubC2R (PowerShell 7+) or $HOME\Documents\WindowsPowerShell\Modules\OfficeScrubC2R (Windows PowerShell 5.1). The -Scope AllUsers option installs to C:\Program Files\PowerShell\Modules\OfficeScrubC2R.
Module Import:
# Import the module
Import-Module OfficeScrubC2R
# Verify installation
Get-Module OfficeScrubC2R -ListAvailableSources: README.md:30-38, OfficeScrubC2R.psd1:1-175
Direct installation from the GitHub repository provides access to the latest development version and source code:
# Clone the repository
git clone https://github.com/Calvindd2f/OfficeScrubC2R.git
cd OfficeScrubC2R
# Import the module directly
Import-Module .\OfficeScrubC2R.psd1This method loads the module from the local directory without copying to a module path. The module remains loaded until the PowerShell session ends or Remove-Module is called.
Sources: README.md:40-49
Manual installation involves downloading the release archive, extracting files, and placing them in a PowerShell module directory:
Step 1: Extract Files
Extract the release archive to one of the following locations:
| Scope | Path | Requires Admin |
|---|---|---|
| Current User | $HOME\Documents\PowerShell\Modules\OfficeScrubC2R |
No |
| Current User (Windows PS) | $HOME\Documents\WindowsPowerShell\Modules\OfficeScrubC2R |
No |
| All Users | C:\Program Files\PowerShell\Modules\OfficeScrubC2R |
Yes |
| All Users (Windows PS) | C:\Program Files\WindowsPowerShell\Modules\OfficeScrubC2R |
Yes |
Step 2: Unblock Files
Windows marks files downloaded from the internet with the Zone.Identifier alternate data stream. This must be removed to allow module loading:
# Navigate to module directory
cd "$HOME\Documents\PowerShell\Modules\OfficeScrubC2R"
# Unblock all files
Get-ChildItem -Recurse | Unblock-FileStep 3: Import Module
Import-Module OfficeScrubC2RSources: README.md:51-58, docs/memory-bank/tech.md:121-124
The module consists of multiple interdependent files that are loaded in a specific sequence. Understanding this structure is essential for troubleshooting installation issues.
The manifest at OfficeScrubC2R.psd1:89-100 defines the complete file list:
| File | Purpose | Type |
|---|---|---|
OfficeScrubC2R.psd1 |
Module manifest with metadata | PowerShell Data File |
OfficeScrubC2R.psm1 |
Root module with public API | PowerShell Module |
OfficeScrubC2R.ps1 |
Main script with pipeline logic | PowerShell Script |
OfficeScrubC2R-Utilities.psm1 |
Nested utilities module | PowerShell Module |
OfficeScrubC2R-Native.cs |
C# source for fallback compilation | C# Source |
OfficeScrubNative.dll |
Pre-compiled native library | .NET Assembly |
build.ps1 |
Build script for native DLL | PowerShell Script |
LICENSE |
MIT license text | Text |
README.md |
Documentation | Markdown |
The module manifest specifies these dependencies at OfficeScrubC2R.psd1:50 (RequiredAssemblies), OfficeScrubC2R.psd1:62 (NestedModules), and OfficeScrubC2R.psd1:89-100 (FileList).
Sources: OfficeScrubC2R.psd1:89-100, docs/memory-bank/structure.md:5-12
OfficeScrubC2R/
├── OfficeScrubC2R.psd1 # Manifest (loads first)
├── OfficeScrubC2R.psm1 # Root module (loads second)
├── OfficeScrubC2R.ps1 # Main script (dot-sourced)
├── OfficeScrubC2R-Utilities.psm1 # Nested module (imported)
├── OfficeScrubC2R-Native.cs # C# source (fallback)
├── OfficeScrubNative.dll # Pre-compiled assembly
├── build.ps1 # Build automation
├── en-US/
│ └── about_OfficeScrubC2R.help.txt
├── LICENSE
└── README.md
Sources: README.md:146-159, docs/memory-bank/structure.md:21-33
The module initialization follows a specific sequence defined by PowerShell's module loading conventions and the manifest configuration. Understanding this sequence is critical for diagnosing loading failures.
sequenceDiagram
participant User
participant PowerShell as "PowerShell Engine"
participant Manifest as "OfficeScrubC2R.psd1"
participant RootModule as "OfficeScrubC2R.psm1"
participant NativeDLL as "OfficeScrubNative.dll"
participant Compiler as "C# Compiler"
participant NativeCS as "OfficeScrubC2R-Native.cs"
participant Utilities as "OfficeScrubC2R-Utilities.psm1"
participant MainScript as "OfficeScrubC2R.ps1"
User->>PowerShell: Import-Module OfficeScrubC2R
PowerShell->>Manifest: Load manifest
Note over Manifest: Validate metadata<br/>ModuleVersion 2.19.2<br/>PowerShellVersion 5.1+<br/>DotNetFrameworkVersion 4.5+
Manifest->>NativeDLL: Load RequiredAssemblies
alt DLL exists and not blocked
NativeDLL-->>Manifest: Assembly loaded
else DLL missing or blocked
Manifest->>Compiler: Attempt fallback compilation
Compiler->>NativeCS: Compile C# source
NativeCS-->>Compiler: Compilation result
alt Compilation successful
Compiler-->>Manifest: Runtime DLL available
else Compilation failed
Compiler-->>Manifest: ERROR: Native layer unavailable
end
end
Manifest->>RootModule: Load RootModule
RootModule->>Utilities: Import NestedModules
Note over Utilities: Import-Module -Force -Global
Utilities-->>RootModule: Functions exported to global scope
RootModule->>MainScript: Dot-source script
Note over MainScript: . $PSScriptRoot\OfficeScrubC2R.ps1
MainScript-->>RootModule: Functions available in module scope
RootModule->>RootModule: Initialize-Environment
Note over RootModule: Auto-execute on module load<br/>Set $script:LogDir<br/>Create orchestrator instance
RootModule->>PowerShell: Export-ModuleMember
Note over RootModule: Export functions:<br/>Invoke-OfficeScrubC2R<br/>Get-InstalledOfficeProducts<br/>Test-IsC2R<br/>Initialize-Environment<br/>Stop-OfficeProcesses
PowerShell-->>User: Module ready
Key Loading Steps:
- Manifest Validation - OfficeScrubC2R.psd1:1-175 validates metadata, PowerShell version, and .NET Framework version
-
Native Assembly Loading - OfficeScrubC2R.psd1:50 loads
OfficeScrubNative.dllviaRequiredAssemblies - Fallback Compilation - If DLL load fails, the root module attempts runtime compilation from OfficeScrubC2R-Native.cs
- Root Module Execution - OfficeScrubC2R.psm1 executes, importing nested modules
-
Utilities Import - OfficeScrubC2R.psd1:62 specifies
OfficeScrubC2R-Utilities.psm1as nested module - Main Script Dot-Sourcing - Root module dot-sources OfficeScrubC2R.ps1 into module scope
-
Environment Initialization -
Initialize-Environmentfunction executes automatically - Function Export - OfficeScrubC2R.psd1:65-71 defines exported functions and OfficeScrubC2R.psd1:80 defines aliases
Sources: OfficeScrubC2R.psd1:1-175, docs/memory-bank/structure.md:96-103
The module implements a smart fallback strategy for the native DLL. If OfficeScrubNative.dll cannot be loaded (due to missing file, zone blocking, or security policy), the root module attempts to compile OfficeScrubC2R-Native.cs at runtime.
flowchart TD
Start["Module Import Begins"]
LoadManifest["Load OfficeScrubC2R.psd1"]
CheckDLL{"OfficeScrubNative.dll<br/>exists and not blocked?"}
LoadDLL["Load pre-compiled DLL<br/>(OptimizedPath)"]
CheckCSC{"C# compiler<br/>(csc.exe)<br/>available?"}
CompileSource["Compile OfficeScrubC2R-Native.cs<br/>using Add-Type"]
CheckCompile{"Compilation<br/>successful?"}
UseDLL["Use native performance layer<br/>(10-50x speedup)"]
Fallback["WARN: Native layer unavailable<br/>Continue with PowerShell-only mode"]
LoadRootModule["Load OfficeScrubC2R.psm1"]
Complete["Module initialization complete"]
Start --> LoadManifest
LoadManifest --> CheckDLL
CheckDLL -->|Yes| LoadDLL
CheckDLL -->|No| CheckCSC
LoadDLL --> UseDLL
CheckCSC -->|Yes| CompileSource
CheckCSC -->|No| Fallback
CompileSource --> CheckCompile
CheckCompile -->|Yes| UseDLL
CheckCompile -->|No| Fallback
UseDLL --> LoadRootModule
Fallback --> LoadRootModule
LoadRootModule --> Complete
Compiler Detection:
The module searches for csc.exe in the following locations:
-
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe(64-bit) -
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe(32-bit)
If compilation fails, the module continues in PowerShell-only mode with degraded performance. The native layer provides 10-50x performance improvements, so fallback should only be used when necessary.
Sources: docs/memory-bank/tech.md:28-47, README.md:175-179
The module has specific runtime dependencies that must be satisfied for successful loading.
| Dependency | Source | Required By | Failure Impact |
|---|---|---|---|
| PowerShell 5.1+ | OfficeScrubC2R.psd1:38 | Module loading | Module import fails |
| .NET Framework 4.5+ | OfficeScrubC2R.psd1:41 | Native assembly | DLL load fails, fallback triggers |
OfficeScrubNative.dll |
OfficeScrubC2R.psd1:50 | Performance layer | Fallback to compilation |
OfficeScrubC2R-Utilities.psm1 |
OfficeScrubC2R.psd1:62 | Helper functions | Module load fails |
| Administrator privileges | Runtime | Cleanup operations | Operations fail with access denied |
The native DLL requires the following .NET assemblies:
-
System.dll(core types) -
System.Management.dll(WMI operations for license cleanup) -
Microsoft.CSharp.dll(dynamic compilation support)
These are part of the .NET Framework 4.5+ installation and do not require separate installation.
Sources: OfficeScrubC2R.psd1:38-50, docs/memory-bank/tech.md:16-21
After installation, verify that the module loaded correctly and all components are functional.
Step 1: Check Module Availability
# List installed module
Get-Module OfficeScrubC2R -ListAvailable
# Expected output:
# ModuleType Version Name PSEdition ExportedCommands
# ---------- ------- ---- --------- ----------------
# Script 2.19.2 OfficeScrubC2R Desk {Invoke-OfficeScrubC2R, Get-InstalledOfficeProducts...}Step 2: Import Module
# Import with verbose output
Import-Module OfficeScrubC2R -Verbose
# Check imported module
Get-Module OfficeScrubC2RStep 3: Verify Exported Functions
# List exported functions
Get-Command -Module OfficeScrubC2R
# Expected functions (from OfficeScrubC2R.psd1:65-71):
# - Invoke-OfficeScrubC2R
# - Get-InstalledOfficeProducts
# - Test-IsC2R
# - Initialize-Environment
# - Stop-OfficeProcessesStep 4: Verify Aliases
# Check aliases
Get-Alias | Where-Object { $_.Source -eq 'OfficeScrubC2R' }
# Expected aliases (from OfficeScrubC2R.psd1:80):
# - Remove-OfficeC2R -> Invoke-OfficeScrubC2R
# - Uninstall-OfficeC2R -> Invoke-OfficeScrubC2RStep 5: Test Native Layer
# Run detection-only mode (requires admin for full access)
Invoke-OfficeScrubC2R -DetectOnly -Verbose
# Check for native layer initialization messages in verbose output
# Look for "OfficeScrubOrchestrator" references indicating native DLL loadedSources: OfficeScrubC2R.psd1:65-80, README.md:60-79
graph TB
ImportModule["Import-Module OfficeScrubC2R"]
subgraph "Manifest Loading"
LoadManifest["Load OfficeScrubC2R.psd1"]
CheckVersion["Verify PowerShell >= 5.1"]
CheckDotNet["Verify .NET >= 4.5"]
end
subgraph "Assembly Loading"
LoadDLL["Load OfficeScrubNative.dll"]
DLLSuccess{"DLL Loaded?"}
CompileFallback["Compile OfficeScrubC2R-Native.cs"]
NativeReady["Native Layer Ready"]
NativeUnavailable["Native Layer Unavailable"]
end
subgraph "Module Loading"
LoadRoot["Load OfficeScrubC2R.psm1"]
LoadUtilities["Import OfficeScrubC2R-Utilities.psm1"]
DotSource["Dot-source OfficeScrubC2R.ps1"]
InitEnv["Execute Initialize-Environment"]
end
subgraph "Export Phase"
ExportFunctions["Export Functions:<br/>Invoke-OfficeScrubC2R<br/>Get-InstalledOfficeProducts<br/>Test-IsC2R<br/>Initialize-Environment<br/>Stop-OfficeProcesses"]
ExportAliases["Export Aliases:<br/>Remove-OfficeC2R<br/>Uninstall-OfficeC2R"]
end
Complete["Module Ready"]
ImportModule --> LoadManifest
LoadManifest --> CheckVersion
CheckVersion --> CheckDotNet
CheckDotNet --> LoadDLL
LoadDLL --> DLLSuccess
DLLSuccess -->|Yes| NativeReady
DLLSuccess -->|No| CompileFallback
CompileFallback --> NativeReady
CompileFallback --> NativeUnavailable
NativeReady --> LoadRoot
NativeUnavailable --> LoadRoot
LoadRoot --> LoadUtilities
LoadUtilities --> DotSource
DotSource --> InitEnv
InitEnv --> ExportFunctions
ExportFunctions --> ExportAliases
ExportAliases --> Complete
Sources: OfficeScrubC2R.psd1:1-175, docs/memory-bank/structure.md:96-118
Windows attaches the Zone.Identifier alternate data stream to files downloaded from the internet, marking them as potentially unsafe. PowerShell blocks execution of such files by default.
# Navigate to module directory
$modulePath = (Get-Module OfficeScrubC2R -ListAvailable)[0].ModuleBase
cd $modulePath
# Check for Zone.Identifier streams
Get-ChildItem -Recurse | Get-Item -Stream Zone.Identifier -ErrorAction SilentlyContinueMethod 1: PowerShell Cmdlet (Recommended)
# Unblock all files in module directory
Get-ChildItem -Path $modulePath -Recurse | Unblock-FileMethod 2: File Properties (GUI)
- Right-click the DLL file (
OfficeScrubNative.dll) - Select "Properties"
- Check "Unblock" at the bottom of the General tab
- Click "Apply" then "OK"
- Repeat for all
.dll,.ps1, and.psm1files
Method 3: Remove Alternate Data Stream Directly
# Remove Zone.Identifier stream
Get-ChildItem -Recurse | ForEach-Object {
Remove-Item -Path $_.FullName -Stream Zone.Identifier -ErrorAction SilentlyContinue
}Sources: README.md:57, README.md:209-217
Symptoms:
Import-Module : Could not load file or assembly 'OfficeScrubNative.dll'
Causes:
- DLL is blocked (Zone.Identifier present)
- .NET Framework version mismatch
- DLL corruption or missing file
Resolution:
# Step 1: Verify .NET version
[System.Environment]::Version
# Step 2: Unblock DLL
$modulePath = (Get-Module OfficeScrubC2R -ListAvailable)[0].ModuleBase
Unblock-File "$modulePath\OfficeScrubNative.dll"
# Step 3: Rebuild DLL from source (if available)
cd $modulePath
.\build.ps1
# Step 4: Import with verbose output
Import-Module OfficeScrubC2R -Verbose -ForceSources: README.md:209-217, docs/memory-bank/tech.md:16-21
Symptoms:
Import-Module : This module requires PowerShell version 5.1 or later
Resolution:
Check PowerShell version:
$PSVersionTable.PSVersion
# Expected: Major >= 5, Minor >= 1If version is below 5.1, upgrade PowerShell:
- Windows 10/11: Windows PowerShell 5.1 is included
- Windows 7/8.1: Install Windows Management Framework 5.1
- PowerShell Core: Install PowerShell 7+ from https://github.com/PowerShell/PowerShell
Sources: OfficeScrubC2R.psd1:38
Symptoms:
Import-Module : File cannot be loaded because running scripts is disabled
Resolution:
Check execution policy:
Get-ExecutionPolicy -ListSet execution policy (requires admin for system-wide):
# For current user only (recommended)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# System-wide (requires admin)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachineSources: docs/memory-bank/tech.md:135
Symptoms:
Install-Module : Access to the path 'C:\Program Files\PowerShell\Modules' is denied
Resolution:
Option 1: Install to user scope (no admin required):
Install-Module -Name OfficeScrubC2R -Scope CurrentUserOption 2: Run PowerShell as Administrator:
Start-Process powershell -Verb RunAsThen re-run installation with -Scope AllUsers.
Sources: README.md:30-38
Symptoms: Verbose output shows:
WARNING: Failed to load native assembly, attempting fallback compilation
ERROR: Native layer unavailable, continuing in PowerShell-only mode
Causes:
- C# compiler (
csc.exe) not found - .NET Framework SDK not installed
- Insufficient permissions to write temporary files
Resolution:
Verify compiler availability:
# Check for 64-bit compiler
Test-Path 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe'
# Check for 32-bit compiler
Test-Path 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe'If compiler is missing, install .NET Framework Developer Pack 4.5 or later.
Workaround: Pre-compile the DLL on another machine and copy to module directory:
# On build machine:
cd <module-path>
.\build.ps1
# Copy OfficeScrubNative.dll to target machine module directorySources: docs/memory-bank/tech.md:28-47, README.md:175-187
Symptoms:
Import-Module : The specified module 'OfficeScrubC2R-Utilities.psm1' was not loaded
Resolution:
Verify file integrity:
$modulePath = (Get-Module OfficeScrubC2R -ListAvailable)[0].ModuleBase
# Check for utilities module
Test-Path "$modulePath\OfficeScrubC2R-Utilities.psm1"
# Check FileList in manifest matches actual files
$manifest = Import-PowerShellDataFile "$modulePath\OfficeScrubC2R.psd1"
$manifest.FileList | ForEach-Object {
$exists = Test-Path "$modulePath\$_"
[PSCustomObject]@{
File = $_
Exists = $exists
}
}If files are missing, reinstall the module.
Sources: OfficeScrubC2R.psd1:89-100
Developers and users in restricted environments may need to build the native DLL from source.
The build.ps1 script compiles OfficeScrubC2R-Native.cs into OfficeScrubNative.dll:
# Navigate to module directory
cd <module-path>
# Build DLL
.\build.ps1
# Clean and rebuild
.\build.ps1 -Clean| Requirement | Purpose | Location |
|---|---|---|
C# Compiler (csc.exe) |
Compile C# source to DLL | C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ |
| .NET Framework 4.5+ | Runtime target | System-wide |
| PowerShell 5.1+ | Execute build script | System-wide |
The build process produces:
-
OfficeScrubNative.dll- Compiled assembly (required by manifest) -
build.log- Compilation output and errors (if any)
After building, reimport the module:
Import-Module .\OfficeScrubC2R.psd1 -ForceSources: README.md:175-187, docs/memory-bank/tech.md:28-47
Installation of OfficeScrubC2R requires:
- PowerShell 5.1+ and .NET Framework 4.5+ installed
- Module files extracted to a PowerShell module path
- Files unblocked using
Unblock-File - Module imported using
Import-Module - Native DLL loaded or compiled from source
The module's smart fallback mechanism ensures functionality even when the pre-compiled DLL cannot be loaded, though performance is degraded in PowerShell-only mode. Verification after installation confirms that all components loaded successfully and functions are exported correctly.
For usage instructions, see Quick Start. For troubleshooting runtime issues, see Troubleshooting.