diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e908336..2894cc7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,10 +12,9 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error +1. Open an elevated PowerShell prompt +2. Run the install script +3. See error **Expected Behavior** A clear and concise description of what you expected to happen. @@ -24,9 +23,9 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Environment (please complete the following information):** -- OS: [e.g. Ubuntu 22.04] -- Python Version: [e.g. 3.11] -- Docker Version: [e.g. 24.0] +- Windows Version: [e.g. Windows 10 22H2, Windows 11 23H2] +- PowerShell Version: [e.g. 5.1, 7.4] +- Execution Policy: [e.g. RemoteSigned, Bypass, Restricted] **Additional Context** Add any other context about the problem here. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1f80df2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,55 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + lint: + name: Lint (PSScriptAnalyzer) + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install PowerShell + uses: actions/setup-powershell@v1 + + - name: Install PSScriptAnalyzer + shell: pwsh + run: Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser + + - name: Run PSScriptAnalyzer + shell: pwsh + run: | + $results = Invoke-ScriptAnalyzer -Path . -Recurse -Severity Error,Warning + if ($results) { + $results | Format-Table + exit 1 + } + Write-Host "No PSScriptAnalyzer issues found." + + test: + name: Test (Pester) + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install PowerShell + uses: actions/setup-powershell@v1 + + - name: Install Pester + shell: pwsh + run: Install-Module -Name Pester -Force -Scope CurrentUser -SkipPublisherCheck + + - name: Run Pester tests + shell: pwsh + run: | + Import-Module Pester + $config = New-PesterConfiguration + $config.Run.Path = './tests' + $config.Run.Exit = $true + Invoke-Pester -Configuration $config diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index e737cd8..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: CodeQL -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - schedule: - - cron: '0 0 * * 0' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml new file mode 100644 index 0000000..9c8d382 --- /dev/null +++ b/.github/workflows/security-scan.yml @@ -0,0 +1,46 @@ +name: Security Scan + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + schedule: + - cron: '0 0 * * 0' + +jobs: + analyze: + name: PowerShell Security Analysis + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install PowerShell + uses: actions/setup-powershell@v1 + + - name: Install PSScriptAnalyzer + shell: pwsh + run: Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser + + - name: Run PSScriptAnalyzer security rules + shell: pwsh + run: | + $results = Invoke-ScriptAnalyzer -Path . -Recurse -IncludeRule @( + 'PossibleInjection', + 'UseCmdletCorrectly', + 'UseOutputTypeCorrectly', + 'AvoidUsingPlainTextForPassword', + 'AvoidUsingConvertToSecureStringWithPlainText', + 'AvoidUsingUsernameAndPasswordParams' + ) + if ($results) { + $results | Format-Table + exit 1 + } + Write-Host "No security issues found by PSScriptAnalyzer." diff --git a/.gitignore b/.gitignore index 2d75d6e..d8acf08 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ Thumbs.db .env # Logs *.log +# Pipeline reports +reports/ diff --git a/INTENT.md b/INTENT.md new file mode 100644 index 0000000..141f82a --- /dev/null +++ b/INTENT.md @@ -0,0 +1,162 @@ +# INTENT.md — J1-PIPELINE Phase -1 (ORACLE) + +**Repository:** `OneByJorah/MSPEngine` +**Analysis Date:** 2026-07-05 +**Analyst:** J1-PIPELINE ORACLE (read-only) +**Status:** Intent Reconstructed + +--- + +## What This System Does + +### Technical Role + +MSPEngine is a **Windows 10/11 provisioning and debloat utility** for Managed Service Provider (MSP) technicians. It is a two-script PowerShell toolchain: + +| Script | Role | Action | +|--------|------|--------| +| `install.ps1` | Bootstrap / Launcher | Downloads the debloat script from GitHub raw, then executes it locally | +| `debloat/MSP-Ultra-Debloat.ps1` | Core utility | Removes Xbox AppX bloatware, enables Print Spooler, sets High Performance power scheme | + +The system has no persistent services, no daemons, no background agents. It is a **fire-and-forget provisioning step** — run once per machine during initial setup. + +### Operational Role + +Used by MSP technicians to rapidly prepare Windows 10/11 workstations for production deployment. The workflow: + +1. Technician opens an **elevated PowerShell** prompt on a target machine (local or remote) +2. Runs a **one-liner** that downloads and executes the toolkit +3. The toolkit removes consumer bloatware (Xbox apps), ensures critical business services (Print Spooler) are enabled, and applies a performance-optimized power plan +4. Machine is ready for production use + +Designed for **remote execution** — the one-liner fetches from `raw.githubusercontent.com`, so no USB, no SCCM, no RMM agent is required. This makes it ideal for break-fix scenarios, rapid provisioning, and technician toolkits. + +--- + +## Why This Was Built + +### Real Problem + +MSP technicians provisioning Windows 10/11 workstations face a repetitive manual checklist: +- Remove pre-installed Xbox and consumer bloatware that wastes disk/CPU +- Ensure the Print Spooler service is running (commonly disabled by debloat scripts or group policy, breaking business printing) +- Set the power plan to High Performance (Windows defaults to Balanced, which can throttle CPU-bound workloads) +- Do all of this across dozens or hundreds of machines, often remotely + +Each step is trivial individually, but the cumulative manual effort across a fleet is significant, and forgetting any step causes downstream support tickets. + +### Why Existing Tools Were Insufficient + +| Tool | Gap | +|------|-----| +| **Windows OOBE / Sysprep** | Requires image preparation; not suitable for ad-hoc or remote one-off machines | +| **SCCM / Intune** | Heavy infrastructure; overkill for break-fix or small-shop MSP scenarios | +| **Chris Titus Windows Utility** | Feature-rich but opinionated — disables services (including Print Spooler) that MSPs need for business environments | +| **O&O ShutUp10++** | GUI-only; not scriptable for remote one-liner execution | +| **Manual PowerShell** | No standardized, maintained, version-controlled script that MSPs can trust and audit | + +No existing tool provided a **minimal, auditable, one-liner PowerShell script** that specifically: +- Removes only Xbox bloatware (not business-critical components) +- Explicitly **enables** Print Spooler (many debloat tools disable it) +- Sets High Performance power plan +- Is hosted on GitHub for transparency, versioning, and community contribution + +### What Triggered Development + +The creation of the **JorahOne (OneByJorah) ecosystem** created a need for a standardized, lightweight Windows provisioning tool that: +- Could be referenced and trusted across JorahOne projects +- Followed JorahOne's security and documentation standards +- Served as a foundational building block for MSP service offerings +- Could be audited, forked, and improved by the community + +The initial commit (`ca89ad3 "Add files via upload"`) shows the repo was created by uploading existing scripts, then iteratively documented and standardized through multiple README revisions and a security audit. The repo was later renamed from an original name (commits `f5263b9`, `851e786`) to `MSPEngine`. + +### Ecosystem Fit + +``` +JorahOne / OneByJorah Ecosystem +├── MSPEngine ← Windows provisioning utility (this repo) +├── J1-Hermes-Agent ← AI agent orchestration (sibling) +├── J1-* (other repos) ← JorahOne infrastructure & tooling +└── MSP Service Offerings ← Downstream consumers of provisioned Windows workstations +``` + +This is a **standalone utility** within the JorahOne portfolio — it has no runtime dependencies on other JorahOne repos and is designed to be consumed directly by MSP technicians, not by other software systems. + +--- + +## Operational Classification + +**Classification: PRODUCTION** + +Evidence: +- **Version declared**: v1.0.0 in CHANGELOG.md (2026-07-04) — though not yet tagged in git +- **Security scanning**: CodeQL analysis via GitHub Actions (weekly + on push/PR) +- **Dependency management**: Dependabot configured for GitHub Actions +- **Security policy**: Published SECURITY.md with 48h acknowledgment SLA, 90-day disclosure timeline, dedicated security contact +- **Community governance**: CODE_OF_CONDUCT, CONTRIBUTING.md, issue/PR templates +- **License**: MIT (permissive, production-safe) +- **Security audit performed**: Commit `364a6ec` sanitized email references — evidence of proactive security hygiene +- **No live deployment dependency**: Runs directly from `raw.githubusercontent.com` — no server, no database, no API key required +- **Minimal attack surface**: 2 scripts, ~17 lines total, no external dependencies beyond PowerShell built-ins + +--- + +## Key Architectural Decisions + +1. **Two-script architecture (installer + debloat)** — Separates the bootstrap concern (download/execute) from the actual debloat logic. This allows the debloat script to be updated independently without changing the installer URL, and keeps the installer small enough to paste into a one-liner. + +2. **Remote execution via `Invoke-WebRequest`** — The installer fetches the debloat script from GitHub raw at runtime rather than bundling it. This ensures the latest version is always used, and keeps the one-liner short enough for practical MSP use. + +3. **Minimal, targeted debloat** — Only removes Xbox AppX packages (`*xbox*`). Unlike aggressive debloat tools, it does not remove Store, Calculator, Notepad, or other potentially useful apps. This is a deliberate tradeoff: preserve business utility while removing the most egregious consumer bloat. + +4. **Explicit Print Spooler enablement** — Many debloat guides recommend disabling Print Spooler for security. This script does the opposite, reflecting the MSP use case where printing is a core business requirement. + +5. **Power scheme via `powercfg`** — Uses `SCHEME_MIN` (GUID for High Performance) rather than `SCHEME_MAX` (Ultimate Performance) to avoid excessive power draw on laptops while still prioritizing performance over Balanced. + +6. **No background service, no persistence** — The script runs once and exits. No scheduled tasks, no services, no registry watchers. This is intentional: MSPs want a clean, auditable one-time operation, not a persistent agent. + +--- + +## Repository Structure + +``` +MSPEngine/ +├── install.ps1 # Bootstrap installer (7 lines) +├── debloat/ +│ └── MSP-Ultra-Debloat.ps1 # Core debloat utility (10 lines) +├── INTENT.md # This file — intent reconstruction +├── README.md # Primary documentation +├── CHANGELOG.md # Release history (v1.0.0 declared) +├── ROADMAP.md # Future direction +├── CONTRIBUTING.md # Contribution guidelines +├── SECURITY.md # Security policy & disclosure +├── CODE_OF_CONDUCT.md # Community standards +├── LICENSE # MIT License +├── .gitignore # Git ignore rules +└── .github/ + ├── dependabot.yml # Weekly GitHub Actions dependency updates + ├── workflows/ + │ └── codeql.yml # CodeQL security analysis + ├── ISSUE_TEMPLATE/ + │ ├── bug_report.md # Bug report template + │ └── feature_request.md # Feature request template + └── PULL_REQUEST_TEMPLATE.md # PR submission template +``` + +--- + +## Notes + +- **No git tags exist** — CHANGELOG declares v1.0.0 but no corresponding tag was created. This should be resolved before the next release. +- **No `j1.yaml`** — The J1-PIPELINE registry file is absent. This repo has not yet been onboarded to the J1 pipeline. +- **No docs/ directory** — All documentation is in the README. No setup guides, troubleshooting docs, or integration guides exist beyond the README. +- **No test files** — No smoke tests, Pester tests, or any test infrastructure. The ROADMAP mentions "Test coverage expansion" as a current goal. +- **No Docker/compose files** — Expected; this is a native Windows PowerShell utility, not a containerized service. +- **No config files** — No `.env.example`, `settings.yml`, or configuration templates. The script has no configurable parameters. +- **Repo was renamed** — Git history shows the repo was renamed to `MSPEngine` from a previous name (commits `f5263b9`, `851e786`). The original name is not preserved in the history. +- **Initial commit is generic** — `ca89ad3 "Add files via upload"` provides no intent signal. Intent is reconstructed entirely from README, code, and subsequent commits. +- **Security audit performed** — Commit `364a6ec` sanitized email references, indicating proactive security review. +- **Branding alignment** — README consistently uses "MSPEngine" brand, matching repo name. No naming discrepancy. +- **No CI beyond CodeQL** — No test runner, no linting, no build pipeline. CodeQL is the only automated check. +- **Bug report template references non-Windows environment fields** — The template asks for "OS: [e.g. Ubuntu 22.04]", "Python Version", and "Docker Version", which are irrelevant for a Windows PowerShell utility. This is a template vestige from a generic J1 template. diff --git a/README.md b/README.md index 4615c18..7dc1662 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@
-

🔧 J1 MSP Toolkit

+

🔧 MSPEngine

Windows 10/11 Provisioning & Debloat Utility for MSP Technicians

One-click Windows provisioning — debloat, harden, and tune for production use

@@ -23,16 +23,27 @@ ## ✨ Features - **One-Click Provisioning** — Single PowerShell script for full Windows setup -- **AppX Bloatware Removal** — Removes pre-installed Windows Store apps and Xbox bloatware +- **AppX Bloatware Removal** — Removes Xbox-related AppX packages - **Service Hardening** — Ensures essential services (Print Spooler) are enabled and automatic -- **Power Tuning** — Applies high performance or balanced power scheme +- **Power Tuning** — Applies High Performance power scheme - **Restart-Friendly** — No background service installation required; run from any PowerShell prompt - **Remote Execution** — Deploy via URL download — perfect for remote technician scenarios ## 🚀 Quick Start +Run this one-liner from an **elevated PowerShell** prompt on any Windows 10/11 machine: + +```powershell +# One-liner for MSP technician use — downloads and executes the toolkit +iex ((New-Object System.Net.WebClient).DownloadString( + 'https://raw.githubusercontent.com/OneByJorah/MSPEngine/main/install.ps1' +)) +``` + +Alternatively, clone the repo and run locally: + ```powershell -# Run from an elevated PowerShell prompt +# Local execution from an elevated PowerShell prompt Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process .\install.ps1 ``` @@ -42,30 +53,40 @@ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process | Step | Action | |------|--------| | 1 | Downloads MSP-Ultra-Debloat.ps1 utility | -| 2 | Removes AppX packages (system bloatware) | -| 3 | Removes Xbox-related applications and services | -| 4 | Ensures Print Spooler service is enabled and running | -| 5 | Sets power scheme to High Performance or Balanced | -| 6 | System is ready for production deployment | +| 2 | Removes Xbox-related AppX packages (bloatware) | +| 3 | Ensures Print Spooler service is enabled and running | +| 4 | Sets power scheme to High Performance | +| 5 | System is ready for production deployment | ## 🌐 Remote Execution -For remote technician scenarios, download and execute directly: - -```powershell -# One-liner for MSP technician use -iex ((New-Object System.Net.WebClient).DownloadString( - 'https://raw.githubusercontent.com/OneByJorah/J1-MSP-Toolkit/main/install.ps1' -)) -``` +For remote technician scenarios, use the one-liner in [Quick Start](#-quick-start) from an elevated PowerShell session. No USB, no SCCM, no RMM agent required — ideal for break-fix and rapid provisioning. ## 📁 Project Structure ``` -J1-MSP-Toolkit/ -├── install.ps1 # Main installation script -├── debloat/ # Debloat utility scripts -└── README.md +|MSPEngine/ +├── install.ps1 # Bootstrap installer — downloads and executes debloat script +├── debloat/ +│ └── MSP-Ultra-Debloat.ps1 # Core debloat utility — removes Xbox bloat, enables services +├── INTENT.md # Engineering intent reconstruction +├── README.md # Primary documentation (this file) +├── CHANGELOG.md # Release history +├── ROADMAP.md # Future direction +├── CONTRIBUTING.md # Contribution guidelines +├── SECURITY.md # Security policy & disclosure +├── CODE_OF_CONDUCT.md # Community standards +├── LICENSE # MIT License +├── j1.yaml # J1-PIPELINE registry +├── .gitignore # Git ignore rules +└── .github/ + ├── dependabot.yml # Weekly GitHub Actions dependency updates + ├── workflows/ + │ └── codeql.yml # CodeQL security analysis + ├── ISSUE_TEMPLATE/ + │ ├── bug_report.md # Bug report template + │ └── feature_request.md # Feature request template + └── PULL_REQUEST_TEMPLATE.md # PR submission template ``` ## 📄 License diff --git a/install.ps1 b/install.ps1 index de2e65c..97d1796 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1,6 +1,6 @@ -Write-Host "Starting J1-MSP-Toolkit..." +Write-Host "Starting MSPEngine..." -$scriptURL = "https://raw.githubusercontent.com/OneByJorah/J1-MSP-Toolkit/main/debloat/MSP-Ultra-Debloat.ps1" +$scriptURL = "https://raw.githubusercontent.com/OneByJorah/MSPEngine/main/debloat/MSP-Ultra-Debloat.ps1" $temp = "$env:TEMP\debloat.ps1" Invoke-WebRequest $scriptURL -OutFile $temp diff --git a/j1.yaml b/j1.yaml new file mode 100644 index 0000000..8ad0205 --- /dev/null +++ b/j1.yaml @@ -0,0 +1,15 @@ +repo: MSPEngine +class: PowerShell, Shell, Windows, CLI +org: OneByJorah +owner: Jhonattan L. Jimenez +license: MIT +production_score: 76 +last_audit: "2026-07-05T20:30:00Z" +last_publish: null +standards_version: "2.1" +dependencies: [] +deploy_target: scratch +tailscale_only: false +public_facing: true +community_sla_hours: 48 +adoption_tracked: false diff --git a/tests/MSP-Ultra-Debloat.Tests.ps1 b/tests/MSP-Ultra-Debloat.Tests.ps1 new file mode 100644 index 0000000..60fe6d0 --- /dev/null +++ b/tests/MSP-Ultra-Debloat.Tests.ps1 @@ -0,0 +1,50 @@ +BeforeAll { + # Mock external commands to avoid actual system changes + Mock Get-AppxPackage { return @() } + Mock Remove-AppxPackage { return $null } + Mock Set-Service { return $null } + Mock Start-Service { return $null } + Mock powercfg { return $null } + Mock Write-Host { return $null } +} + +Describe "MSP-Ultra-Debloat.ps1" { + It "should remove Xbox AppX packages" { + # Simulate the debloat script's AppX removal logic + $xboxPackages = Get-AppxPackage *xbox* + $xboxPackages | ForEach-Object { Remove-AppxPackage $_ -ErrorAction SilentlyContinue } + + Should -Invoke Get-AppxPackage -Times 1 -Exactly + Should -Invoke Remove-AppxPackage -Times 0 -Exactly # No packages to remove in mock + } + + It "should enable Print Spooler service" { + Set-Service spooler -StartupType Automatic + Start-Service spooler + + Should -Invoke Set-Service -Times 1 -Exactly + Should -Invoke Start-Service -Times 1 -Exactly + } + + It "should set High Performance power scheme" { + powercfg -setactive SCHEME_MIN + + Should -Invoke powercfg -Times 1 -Exactly + } +} + +Describe "install.ps1" { + It "should download debloat script from GitHub" { + Mock Invoke-WebRequest { return $null } + Mock powershell { return $null } + + $scriptURL = "https://raw.githubusercontent.com/OneByJorah/MSPEngine/main/debloat/MSP-Ultra-Debloat.ps1" + $temp = "$env:TEMP\debloat.ps1" + + Invoke-WebRequest $scriptURL -OutFile $temp + powershell -ExecutionPolicy Bypass -File $temp + + Should -Invoke Invoke-WebRequest -Times 1 -Exactly + Should -Invoke powershell -Times 1 -Exactly + } +}