One stop shop for common Windows 11 tasks
Find a file
reinitialized 5327f66da8
Enhance PowerShell scripts with improved handling and new features
- Clean-ADStaleObjects.ps1: Refine object disabling and quarantining logic to respect recommendations based on staleness thresholds. Added logging for skipped objects.
- Factory-Reset.ps1: Ensure the Admin phase is prioritized before Profiles to maintain break-glass access during resets.
- Prepare-System.ps1: Pass resume arguments through the DomainJoin phase to retain critical settings across reboots.
- Repair-Workstation.ps1: Introduced New-RepairWorkstationResumeToolArgs function to preserve user-defined parameters across reboots.
- Clear-WindowsHelloPin.ps1: Added interactive selection for clearing Windows Hello PINs, enhancing user experience and safety.
- Enable-WebSignIn.ps1: Improved Azure AD join check with optional status text parameter for testing. Streamlined confirmation prompts.
- Restore-OneDriveBackup.ps1: Implemented Invoke-RestoreSevenZip function for robust handling of 7z archive operations, ensuring proper argument quoting.
- Set-WindowsHelloPinPolicy.ps1: Enhanced confirmation prompts and ensured proper handling of transcript stops.

Updated wiki documentation to reflect new features and provide clearer navigation for users.
2026-07-17 16:56:04 -05:00
.vscode feat: Add Repair-MappedDrives script for resilient network drive management 2026-07-14 14:57:45 -05:00
config Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
modules Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
tests Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
tools Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
wiki Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
.gitignore docs: expand CLAUDE.md to full AGENTS.md and add .gitignore for client config 2026-07-02 14:23:37 -05:00
.mcp.json feat: Add Repair-MappedDrives script for resilient network drive management 2026-07-14 14:57:45 -05:00
AGENTS.md Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
CLAUDE.md Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
flake.lock extensive improvements to SolveOnedriveDuplicates 2026-02-11 21:08:34 -06:00
flake.nix docs: update target runtime from PowerShell 7 to Windows PowerShell 5.1 2026-06-22 09:54:27 -05:00
README.md Enhance PowerShell scripts with improved handling and new features 2026-07-17 16:56:04 -05:00
start.ps1 docs: document launcher UI and network asset scan 2026-07-10 11:46:34 -05:00

TechWizard

TechWizard is the Reinitialized.net TechTools launcher for Windows 11 workstation provisioning, repair, cleanup, profile migration, RMM agent maintenance, and OneDrive duplicate resolution.

The single entry point is start.ps1. It can run from a local checkout or be launched directly from Forgejo with PowerShell.

TechWizard v2 keeps start.ps1 as a thin bootstrap. Tool metadata now lives in modules/TechTools.Manifest.psm1, and launcher behavior lives in modules/TechTools.Launcher.psm1. Domain modules and tool scripts continue to own the workstation operations.

Quick Start From Forgejo

Open Windows Terminal or PowerShell as Administrator, then run:

Set-ExecutionPolicy Bypass -Scope Process -Force; $RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'; & ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) -RepoBaseUrl $RepoBaseUrl

Set-ExecutionPolicy Bypass -Scope Process -Force relaxes the policy for the current PowerShell process only, so a strict machine or user Execution Policy does not block the remote launch. It is not persisted and does not change the configured Execution Policy.

This downloads start.ps1 from Forgejo, opens the interactive tool menu, and loads the selected tool, modules, and config files from the same branch.

On a fresh interactive menu launch TechWizard offers to pivot the session into a temporary superadministrator (it creates the account, signs you out, and the menu relaunches under that account with maximum privileges). It always asks first — Proceed? [y/N], where plain Enter declines — and answering n simply continues in the current session. The pivot is never offered for -Tool or -AcceptAll launches.

The canonical raw launch examples use https://git.ds.reinitialized.net/reinitialized.net/TechWizard. If a reinitialized.studio/TechWizard URL is published for operators, treat it as an alias only when it resolves to the same repository and branch; otherwise keep -RepoBaseUrl aligned to the canonical namespace to avoid duplicate cache roots.

To launch a specific tool without the menu:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation

To run unattended and suppress confirmation prompts, use -AcceptAll with a specific tool:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Prepare-System `
    -AcceptAll

To run only a specific phase, pass -ToolArgs:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation `
    -ToolArgs @{ Phase = 'Cleanup'; Force = $true }

To validate inputs and view the manifest-backed run plan without executing the tool, add -Preview:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation `
    -ToolArgs @{ Phase = 'Cleanup' } `
    -Preview

The interactive menu is a single screen: a TechWizard masthead with host context (computer, operator, run source, client overlay, elevated-session badges), the tools grouped by category with continuous numbering and human display titles, and the recommended new-workstation sequence. You can pick a tool by number or just type its name or an alias. Interactive launch defaults to -UiMode Auto, which uses the guided wizard variant where practical: -UiMode Wizard adds each tool's when-to-use guidance and its time/data-loss/reboot tag under every entry, while -UiMode Classic keeps one compact line per tool.

Every menu-driven launch ends in a pre-flight card (what will run, estimated time, reboot/data-loss expectations, the ordered phase plan with destructive markers) followed by a gate: press Enter to start, E to change your answers, or Q to return to the menu. After a run finishes the launcher offers to return to the menu so you can chain tools without relaunching. The gate and the return-to-menu prompt only appear on a live interactive console — -Tool, -AcceptAll, force mode, resume runs, and headless sessions never see them, so automation behaves exactly as before.

Simple enable/disable utilities (for example Web Sign-In and the Windows Hello PIN policy) appear as a single menu entry; selecting one opens a small second-level menu to choose Enable or Disable before the run starts. Launching those tools directly with -Tool still takes the action from -ToolArgs (e.g. -ToolArgs @{ Mode = 'Disable' }).

Available Tools

The menu is edition-aware: it shows only the tools supported by the current Windows edition (client vs. server / domain controller). On a workstation the client tools below appear; on a domain controller or an RSAT-equipped admin workstation the Active Directory tools appear.

Tool Purpose
Repair-Workstation Deep-analyzes the OS and auto-runs only the repair phases a problem was found for — Windows image repair, OEM/Windows updates plus third-party software currency (winget), device-driver detection and repair, profile repair, cleanup, and RMM agent validation and install/repair. A deep Event Viewer analysis (with best-practice maintenance checks) runs as part of Auto only; it is not a hand-selectable phase.
Factory-Reset Resets a workstation to the MSP baseline, preserving RMM while removing non-whitelisted apps and stale profiles. Defaults to Auto: a read-only analysis (image health, updates, bloatware/UI baseline, the app removal plan, break-glass admin state, the account/profile cleanup plan, disk space, RMM health) picks only the phases whose baseline goal is not already satisfied; All forces the full reset.
Prepare-System Analyzes the OS (incl. Event Logs) and auto-runs only the provisioning phases not already satisfied — provisioning, debloat/privacy hardening, required app install, UI defaults, domain/Entra join, and RMM full-installation validation and onboarding.
SolveOnedriveDuplicates Scans and resolves OneDrive duplicate, conflict, and near-duplicate files with backups.
Restore-OneDriveBackup Reverts OneDrive duplicate-resolution operations from a timestamped backup folder.
Migrate-UserProfile Uses USMT hard-link migration to move one local Windows profile into a fresh local account. Must run as NT AUTHORITY\SYSTEM for real migrations (e.g. psexec.exe -i -s powershell.exe -ExecutionPolicy Bypass -File .\tools\Process\Migrate-UserProfile.ps1); an elevated-but-non-SYSTEM launch stops at the SYSTEM gate with that guidance.
Enable-WebSignIn Enables or disables the Web Sign-In credential provider for Entra-joined Windows 11 workstations.
Set-WindowsHelloPinPolicy Allows or prevents Windows from requesting/requiring a Windows Hello PIN (toggles Windows Hello for Business provisioning at the device scope).
Clear-WindowsHelloPin Forcefully clears a selected user profile's Windows Hello PIN (NGC container) — e.g. a leftover PIN enrolled during TAP-based white-glove setup — with backup and best-effort per-SID targeting.
Set-Microsoft365Apps Fully customizes the Microsoft 365 installation per app: add or remove individual Office applications (Word, Excel, Access, Publisher, Teams, OneNote, classic Outlook, ...) via the Office Deployment Tool, or fresh-install a custom app set on a machine without Office. Unattended runs change nothing unless apps are named explicitly; removals and classic-Outlook re-adds require dangerous confirmation. Running Office apps must be closed for the change to apply (Click-to-Run otherwise cancels the silent pass with exit 17006), so detected running apps are force-closed after an explicit dangerous confirmation.
Test-InternetHealth Traces the path to a target and live-monitors every hop's latency, loss, and jitter, PingPlotter-style, on a flicker-free console dashboard with a per-hop latency-history graph. A running point-of-failure diagnosis separates real end-to-end loss from routers that merely rate-limit their ICMP replies (the classic traceroute false positive), names the segment where a real failure enters the path (local network / ISP handoff / internet / destination), and distinguishes problems happening right now from an earlier episode. Q / Esc / Ctrl+C stop it cleanly — final statistics, the diagnosis, and the optional per-hop CSV export survive the stop even in continuous mode. Read-only.
Repair-MappedDrives Makes a user's mapped network drives survive VPN/network reconnects — the permanent fix for "an error occurred while reconnecting X: ... the local device name is already in use" and for "system error 1219" credential conflicts. Discovers the target user's mappings from their registry hive (works from an elevated run-as-different-admin session), converts them to non-persistent, and drives them from two scheduled tasks running under the user's own interactive token (no stored password, no elevation): remap at logon and on network/VPN connect (NetworkProfile event 10000, VPN-client-agnostic) with quoted UNC paths and a settle delay, release all drive letters on disconnect (event 10001). Optional per-reconnect saved-credential cleanup for the mapped file servers (the 1219 fix, confirmed separately), a GPO Drive Maps conflict warning, Status and Uninstall modes, and an uninstall rollback that restores classic persistent mappings at the user's next sign-in.
Clean-ADStaleObjects Safely retires stale on-prem AD computer/user objects: scan → report → disable → quarantine, with opt-in permanent purge and a reversible transaction log. (domain controller / RSAT only)
Find-NetworkAssets Discovers and classifies the devices on a network with nmap — printers, servers, domain controllers, hypervisors, NAS, switches/firewalls/APs, VoIP phones, cameras, and workstations — for on-site setup when the documentation is missing. Auto-detects the local subnet (or takes an explicit CIDR/range/host), fingerprints open services and guesses the OS, and exports a grouped inventory as CSV, JSON, and a shareable HTML report. Installs nmap (with the Npcap driver) on demand via winget. Read-only against scanned devices; it is an active scan, so only run it on networks you are authorized to scan.

Common Examples

Run workstation repair in automatic mode (the default). Repair-Workstation, Prepare-System, and Factory-Reset default to Phase = Auto: they first perform a read-only analysis of the operating system — including Event Logs, image health, device-driver problems, pending reboot, free disk space, profile corruption, RMM agent health, OEM, bloatware, required tools, UI defaults, domain/Entra-join state, and (for Factory-Reset) the non-whitelisted app removal plan, break-glass administrator state, and the account/profile cleanup plan — print a report, and then run only the phases whose goal is not already satisfied, in the canonical dependency order. When a probe is inconclusive the phase still runs, so analysis never silently skips needed work. Use Phase = 'All' to force every selectable phase, or name individual phases (Repair, Updates, Drivers, Profile, Cleanup, RMMAgent) to run exactly those. The deep Event Viewer analysis runs only as part of Repair-Workstation's Auto; it is not selectable by name and All does not run it.

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation

Force every repair phase regardless of analysis:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation `
    -ToolArgs @{ Phase = 'All' }

Run only updates and cleanup:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Repair-Workstation `
    -ToolArgs @{ Phase = @('Updates', 'Cleanup') }

Prepare a workstation, including debloat and UI standardization:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Prepare-System `
    -ToolArgs @{ Phase = @('Debloat', 'Apps', 'UI') }

Customize the Microsoft 365 app set on one machine — drop Publisher and Access, add OneNote — without prompts (unattended changes require naming the apps; force mode alone never removes anything):

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Set-Microsoft365Apps `
    -ToolArgs @{ RemoveApps = @('Publisher', 'Access'); AddApps = @('OneNote'); Force = $true }

Run it with no arguments for an interactive review of the current per-app state and add/remove menus; -ToolArgs @{ StatusOnly = $true } reports the state and changes nothing.

Inventory stale Active Directory objects without making any changes (run on a domain controller or RSAT-equipped admin workstation):

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Clean-ADStaleObjects `
    -ToolArgs @{ Phase = @('Scan', 'Report') }

The full pipeline disables then quarantines stale objects; permanent deletion is opt-in and only runs with AllowHardDelete:

& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Clean-ADStaleObjects `
    -ToolArgs @{ Phase = @('All'); AllowHardDelete = $true }

Discover and classify the devices on the local network (auto-detected) with a standard scan — installs nmap on demand and writes CSV/JSON/HTML inventories under C:\TechWizard\Logs\Find-NetworkAssets:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Find-NetworkAssets

Scan a specific subnet thoroughly and skip all prompts (Force authorizes the scan and accepts the on-demand nmap install):

& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Find-NetworkAssets `
    -ToolArgs @{ Target = '192.168.10.0/24'; Profile = 'Thorough'; Force = $true }

Fast host-discovery sweep of two subnets (host list + MAC/vendor, no port scan):

& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) `
    -RepoBaseUrl $RepoBaseUrl `
    -Tool Find-NetworkAssets `
    -ToolArgs @{ Target = '10.0.0.0/24 10.0.1.0/24'; Profile = 'Discovery' }

Debloat Coverage (All Accounts, Aggressive)

The Debloat phase removes detected UWP and Win32 bloat with the coverage of an aggressive "scan all Windows accounts" uninstaller pass:

  • AppX/UWP: matching packages are removed for every user account (Remove-AppxPackage -AllUsers) and deprovisioned so new users never get them; leftover per-user AppData\Local\Packages\<family> state folders for removed families are scrubbed across all profiles. An explicit target profile keeps removal scoped to that one account.
  • Win32: the Uninstall hives of the machine, every logged-on user, and — by default — every offline profile (their NTUSER.DAT is loaded for the pass and unloaded afterwards) are enumerated. Silent uninstall is attempted first (MSI /qn, QuietUninstallString, optional winget fallback); after a successful uninstall, remnants (orphaned Uninstall key, leftover install directory, dead Start Menu shortcuts) are cleaned. When no silent uninstaller exists or it fails, the program is force-removed (its services stopped, disabled, and deregistered; its processes stopped; its install directory deleted within approved roots — falling back to the uninstaller's own directory when the entry records no install location; its Uninstall key and shortcuts removed) — confirmed once per run as a dangerous action, auto-approved only in force/unattended mode. Locked or ACL-protected leftovers escalate automatically: ownership/ACL reset and retry, then per-item deletion, and finally reboot-time deletion via the Windows pending-file-rename mechanism, which runs at early boot before any service can re-lock its files. The Uninstall registry entry is never deleted while a program's files remain un-handled (unless its own uninstaller already ran), so the official uninstall path always stays available.

Every safety layer still applies: the essential AppX and Win32 allowlists, the publisher allowlist, the SystemComponent guard, product-wide sibling protection, the RMM no-touch policy, and a strict approved-deletion-root check that refuses to delete anything outside Program Files, Program Files (x86), ProgramData, or a profile's AppData (and never OS-owned subtrees such as Windows, WindowsApps, Windows Defender, or ProgramData\Microsoft). The toggles live in config/debloat-settings.psd1 (AppxRemoveAllUsers, AppxRemoveLeftoverData, Win32ScanAllUserProfiles, Win32LeftoverCleanup, Win32ForcedRemovalFallback), all enabled by default.

Local Checkout

git clone https://git.ds.reinitialized.net/reinitialized.net/TechWizard.git
cd TechWizard
powershell -ExecutionPolicy Bypass -File .\start.ps1

Launch a specific local tool:

powershell -ExecutionPolicy Bypass -File .\start.ps1 -Tool Repair-Workstation

Requirements

  • Run from an elevated PowerShell session.
  • Target runtime is Windows PowerShell 5.1, which ships in-box with every supported build of Windows. No separate PowerShell runtime is downloaded or installed; start.ps1 runs directly under the host shell.
  • TechWizard runs on every platform that supports Windows PowerShell 5.1 — Windows 7 SP1 / Server 2008 R2 (via WMF 5.1) through current Windows 11 / Server 2025. Features tied to a newer NT release (AppX removal, DISM component-store repair, winget, pnputil device rescans, Entra join, Windows Hello, Web sign-in, local-account cmdlets, Windows 11 taskbar alignment) are gated by release feature flags resolved during the read-only analysis pass: on an older release each gated step is skipped with a warning (or fails loudly up front when the work is required), and the analysis report lists which features the host lacks. Nothing hard-fails mid-phase because the OS predates a feature.
  • Target workstations must be able to reach https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/indev.
  • If the Forgejo repository is private, use a local checkout or expose a read-only raw URL reachable by the workstation before launching remotely.

Branches And Overrides

The examples above use the indev branch. To launch another branch, change the branch segment in RepoBaseUrl:

Set-ExecutionPolicy Bypass -Scope Process -Force
$RepoBaseUrl = 'https://git.ds.reinitialized.net/reinitialized.net/TechWizard/raw/branch/main'
& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) -RepoBaseUrl $RepoBaseUrl

-RepoBaseUrl is intentionally included in the remote commands so every downloaded script, module, and config file comes from the same Forgejo branch.

Version Banner

Every launch prints a banner naming the product version, branch, and running commit, then compares the running commit to the branch tip via the Forgejo commits API:

  • Local checkout: the running commit is read from .git and compared to the branch tip. A warning is printed when the checkout is behind.
  • Remote irm/iex launch: there is no .git directory. When every bootstrap module was freshly downloaded, the running code is the branch tip by construction; the tip SHA is adopted, reported, and stamped into the module cache (commit.json in the cache root). When a later launch cannot reach the repository and falls back to cached modules, that stamp names the running commit and the banner warns that the cache is behind or unverifiable.

The check is best-effort and never blocks a launch: with no network and no stamp, the banner says the version could not be verified.

Client Configuration Overlays

Org- and client-specific values — real RMM SERVERADDRESS/SERVERPASS, the managed ScreenConnect ExpectedInstanceHost/ExpectedInstanceId, location ids — are secrets and must never be committed to this repository. They live in an external config root (a mapped work Google Drive letter, a UNC share, or the local drop C:\TechWizard\client-config) with this layout:

<root>\generic\rmm-agent.psd1                  org-wide overrides
<root>\clients\AcmeCorp\rmm-agent.psd1         per-client overrides

Overlay files mirror the repo's config/*.psd1 names and contain only the keys being overridden; they are deep-merged over the repo defaults (generic first, then the selected client) every time a config file is loaded, so all tools pick them up automatically. Scalars and arrays in an overlay replace the base value; nested hashtables merge.

Select the root and client at launch:

& ([scriptblock]::Create((irm "$RepoBaseUrl/start.ps1"))) -RepoBaseUrl $RepoBaseUrl `
    -ClientConfigPath 'G:\TechWizard' -Client 'AcmeCorp'

Example G:\TechWizard\generic\rmm-agent.psd1 overlay that fills in the real Automate install values and pins the managed ScreenConnect instance without touching the repo:

@{
    Agents = @{
        Automate = @{
            InstallArgs = @{
                SERVERADDRESS = 'https://automate.example.com'
                SERVERPASS    = 'RealEncryptedServerPassword'
                LOCATION      = '42'
            }
            RequiredComponents = @(
                @{
                    DisplayName          = 'Managed ScreenConnect Access Agent'
                    Type                 = 'ScreenConnect'
                    ServiceNamePattern   = 'ScreenConnect Client*'
                    RequiredRole         = 'Access'
                    ExpectedInstanceHost = 'instance-abc123.screenconnect.example.com'
                    ExpectedInstanceId   = ''
                }
            )
        }
    }
}

Notes:

  • Only a pointer (root path + client name) is persisted locally in C:\TechWizard\client-context.json so reboot/resume finds the same context; secret values are read from the external root at load time and never copied under C:\TechWizard.
  • A per-user mapped drive letter may be absent in a resumed session; prefer a UNC path, or copy the overlays to C:\TechWizard\client-config for runs that reboot. RMM install values resolved before a reboot are already carried through resume by the existing runtime-value capture.
  • A configured-but-unreachable root logs a warning and the run continues on repo defaults; RMM readiness checks still fail loudly on unresolved placeholders, so a lost overlay cannot silently install with dummy values.
  • Access to the overlay store is governed by the drive/share ACLs; keep the root readable only by technicians.
  • Overlays are a convenience, not a requirement: on an attended run without an overlay (an independent run), Prepare-System keeps the RMM phase in its Auto plan, asks which supported RMM agent to install when more than one is configured, prompts for the missing install values, and carries both the choice and the values through reboot resume. Unattended runs without resolvable values still skip an optional agent (and fail loudly on a required one).

Logs And Resume

TechWizard writes logs, downloads, backups, and reboot resume state under C:\TechWizard\. Tools that require a reboot save resume state and relaunch through start.ps1 after Windows restarts.

The default unattended resume path writes C:\TechWizard\resume-state.json, writes C:\TechWizard\resume.ps1, and registers the startup scheduled task TechToolsResumeAsSystem as NT AUTHORITY\SYSTEM. This is intended for unattended/session-0 resume and can be visible in RMM Backstage when the RMM exposes session 0.

When Prepare-System must reboot after domain/Entra join and the active RMM agent cannot be verified, TechWizard requests the visible-console fallback instead: it creates a temporary local administrator, configures one AutoAdminLogon, registers TechToolsResumeOnTempAdminLogon, clears the AutoAdminLogon password as soon as the bootstrap starts, and cleans up the temporary account after the resumed run.

Manual resume validation checklist:

  1. Trigger a controlled reboot-required condition or mock the resume handoff.
  2. Before reboot, verify Get-ScheduledTask -TaskName TechToolsResumeAsSystem, Test-Path C:\TechWizard\resume-state.json, and Test-Path C:\TechWizard\resume.ps1.
  3. Reboot and do not log in.
  4. From RMM Backstage/session 0, verify a powershell process starts and the new log contains Resuming previous TechTools session.
  5. Verify the remaining phases run and cleanup removes resume-state.json, resume.ps1, and the scheduled task after success.

Visible-console fallback validation:

  1. Trigger a domain/Entra reboot handoff without a healthy active RMM agent.
  2. Before reboot, verify C:\TechWizard\temp-admin.json, C:\TechWizard\resume-state.json, C:\TechWizard\resume.ps1, TechToolsResumeOnTempAdminLogon, and the one-time Winlogon AutoAdminLogon values.
  3. After reboot, verify the temporary administrator signs in, a visible PowerShell console resumes TechWizard, and the new log contains Resuming previous TechTools session.
  4. Verify cleanup removes the resume files, scheduled tasks, Winlogon password, and temporary administrator.