The PowerShell toolkit that turns bare metal into production-ready Windows Servers.
Features • Quick Start • Configuration • Batch Mode • Changelog • Contributing
RackStack is a menu-driven PowerShell tool that automates everything between "Windows is installed" and "server is in production." Think of it as sconfig for the modern era -- but instead of 15 options, you get 148 CLI actions and 60+ interactive menus covering network configuration, Hyper-V deployment, SAN/iSCSI setup, domain join, licensing, VM creation, health monitoring, drift detection, and batch automation -- all through an interactive console UI with undo support, transaction rollback, and audit logging.
Built for MSPs, sysadmins, and infrastructure teams who build servers repeatedly and want it done right every time.
Networking -- Static IP with rollback, VLAN tagging, Switch Embedded Teaming (auto-detect), custom SET vNICs (Backup, Cluster, Live Migration, Storage, or custom names with VLAN), DNS presets, iSCSI/SAN with A/B side MPIO and cabling auto-detect
Storage Backends -- Pluggable storage backend (iSCSI, Fibre Channel, Storage Spaces Direct, SMB3, NVMe-oF, Local); auto-detection from system state; per-backend management menus; generalized MPIO dispatching; all batch mode steps adapt to the selected backend
Hyper-V -- Role install, configurable VM templates (override specs or add new via defaults.json), batch queue deployment, VHD management, offline registry injection, Secure Boot Gen 2, cluster CSV support
Server Roles -- Failover Clustering, MPIO, BitLocker, Deduplication, Storage Replica, 14 disk operations
Security -- RDP/NLA, firewall templates, Windows Defender exclusions, local admin with complexity enforcement, Windows licensing (GVLK 2008-2025, AVMA 2012R2-2025)
Automation -- JSON-driven batch mode (24 idempotent steps with transaction rollback), Quick Setup Wizard, configuration export/import, HTML reports, JSON audit logging with rotation
Monitoring -- 148 CLI actions with JSON output for fleet automation, ServerScore (unified 0-100 health grade), HealthDashboard (all-in-one monitoring endpoint), ClusterHealthScore, StorageHealthScore, System Center (SCCM/SCOM/WAC) + Azure AD/Intune integration
Monitoring & Diagnostics -- Health dashboard (disk I/O latency, NIC errors, memory pressure, Hyper-V guest health, top CPU processes), performance snapshots with trend reports and "days until full" estimates, event log viewer, service manager, network diagnostics (ping, traceroute, port test, subnet sweep, DNS, ARP)
Drift Detection -- Save configuration baselines, compare snapshots over time, track setting changes across baselines, auto-baseline after batch mode
VM Deployment Safety -- Pre-flight validation (disk, RAM, vCPU ratio, switches, VHDs) with OK/WARN/FAIL table, post-deploy smoke tests (heartbeat, NIC, IP, ping, RDP), batch queue with summary
Multi-Agent Support -- Configure and manage multiple RMM/MSP agent installers from a single interface, batch install via InstallAgents config array
Remote Ops -- Remote PowerShell sessions, remote health checks, remote service management
System Debloat -- Remove bloatware, disable telemetry, optimize services (Light/Standard/Aggressive profiles), Windows 11 / Server 2025 UI cleanup (classic right-click, left taskbar, no widgets/copilot), OS dark/light theme toggle
UX -- 5 color themes, session resume, favorites, command history, undo framework, 72-char box-drawing UI
Grab RackStack.exe from the latest release, drop it on your server, and run it as Administrator. That's it.
On first launch, a setup wizard walks you through configuring your environment (domain, DNS, admin account, iSCSI subnet). Your settings are saved to defaults.json next to the exe. To pre-configure, download defaults.example.json from the release, rename it to defaults.json, fill in your values, and place it alongside the exe.
The exe auto-checks for updates from GitHub releases. Your defaults.json is never overwritten by updates.
git clone https://github.com/TheAbider/RackStack.git
cd RackStack
# Run it (requires Administrator) -- first-run wizard creates defaults.json
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
.\RackStack.ps1
RackStack.ps1is the modular loader (~130 lines). It dot-sources all 65 modules fromModules/and starts the tool. Use this for development -- edit individual module files, then run.
For production use, generate a monolithic single-file script (~35K lines) that you can drop on any server:
# Build the monolithic from all modules
.\sync-to-monolithic.ps1The output is RackStack v{version}.ps1 -- a self-contained single file with all 65 modules baked in (version from 00-Initialization.ps1). This is the file used to compile the .exe.
Don't confuse the two:
RackStack.ps1= modular loader for development.RackStack v{version}.ps1= monolithic build for deployment/compilation.
- PowerShell 5.1+ (ships with Server 2016+; for older servers run
Install-Prerequisites.ps1to auto-install WMF 5.1) - Windows Server 2008 R2 SP1, 2012, 2012 R2, 2016, 2019, 2022, or 2025 (also runs on Windows 10/11 for development/testing)
- Administrator privileges (auto-elevates if needed)
- Optional: PSScriptAnalyzer (for linting), a file server for ISO/VHD downloads (see File Server Setup)
Copy defaults.example.json to defaults.json and customize. The example file has every configurable field with comments — here's a quick-start subset:
{
"Domain": "corp.acme.com",
"LocalAdminName": "localadmin",
"LocalAdminFullName": "Local Administrator",
"SwitchName": "LAN-SET",
"ManagementName": "Management",
"BackupName": "Backup",
"AutoUpdate": false,
"TempPath": "C:\\Temp",
"DNSPresets": {
"Corp DC Primary": ["10.0.1.10", "10.0.1.11"],
"Corp DC Secondary": ["10.0.2.10", "10.0.2.11"]
},
"StorageBackendType": "iSCSI",
"iSCSISubnet": "172.16.1",
"SANTargetMappings": [
{ "Suffix": 10, "Label": "A0" },
{ "Suffix": 11, "Label": "B1" }
],
"SANTargetPairings": {
"Pairs": [
{ "Name": "Pair0", "A": 10, "B": 11 },
{ "Name": "Pair1", "A": 12, "B": 13 }
],
"HostAssignments": [
{ "HostMod": 1, "PrimaryPair": "Pair0", "RetryOrder": ["Pair1"] },
{ "HostMod": 2, "PrimaryPair": "Pair1", "RetryOrder": ["Pair0"] }
],
"CycleSize": 2
},
"CustomVNICs": [
{ "Name": "Cluster", "VLAN": 100 },
{ "Name": "Live Migration", "VLAN": 200 }
],
"StoragePaths": {
"HostVMStoragePath": "D:\\Virtual Machines",
"HostISOPath": "D:\\ISOs",
"ClusterISOPath": "C:\\ClusterStorage\\Volume1\\ISOs",
"VHDCachePath": "D:\\Virtual Machines\\_BaseImages",
"ClusterVHDCachePath": "C:\\ClusterStorage\\Volume1\\_BaseImages"
},
"VMNaming": {
"SiteId": "",
"Pattern": "{Site}-{Prefix}{Seq}",
"SiteIdSource": "hostname",
"SiteIdRegex": "^(\\d{3,6})-"
},
"AgentInstaller": {
"ToolName": "MyRMM",
"FolderName": "Agents",
"FilePattern": "Agent_.*\\.exe$",
"ServiceName": "MyRMM Agent*",
"InstallArgs": "/s /norestart",
"InstallPaths": ["%ProgramFiles%\\MyRMM", "%ProgramFiles(x86)%\\MyRMM"],
"SuccessExitCodes": [0, 1641, 3010],
"TimeoutSeconds": 300
},
"FileServer": {
"StorageType": "nginx",
"BaseURL": "https://files.acme.com/server-tools",
"ClientId": "your-cloudflare-access-client-id.access",
"ClientSecret": "your-cloudflare-access-client-secret",
"ISOsFolder": "ISOs",
"VHDsFolder": "VirtualHardDrives",
"AgentFolder": "Agents"
},
"DefenderExclusionPaths": [
"C:\\ProgramData\\Microsoft\\Windows\\Hyper-V",
"C:\\ClusterStorage"
],
"DefenderCommonVMPaths": [
"D:\\Virtual Machines",
"E:\\Virtual Machines"
],
"CustomKMSKeys": {
"Windows Server 2022": { "Standard": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" }
},
"CustomAVMAKeys": {
"Windows Server 2022": { "Standard": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX" }
},
"CustomVMTemplates": {
"FS": { "MemoryGB": 16 },
"SQL": {
"FullName": "SQL Server", "Prefix": "SQL", "OSType": "Windows",
"vCPU": 8, "MemoryGB": 32, "MemoryType": "Static",
"Disks": [{"Name": "OS", "SizeGB": 150, "Type": "Fixed"},
{"Name": "Data", "SizeGB": 500, "Type": "Fixed"}],
"NICs": 1
}
},
"CustomVMDefaults": {
"vCPU": 4, "MemoryGB": 8, "DiskSizeGB": 100
},
"CustomRoleTemplates": {
"MYAPP": {
"FullName": "Custom App Server",
"Description": "Features for a custom application stack",
"Features": ["Web-Server", "NET-Framework-45-Core"],
"RequiresReboot": false,
"ServerOnly": true
}
}
}| Field | What it does |
|---|---|
Domain |
Default Active Directory domain for domain join |
LocalAdminName / LocalAdminFullName |
Local administrator account name and display name |
SwitchName / ManagementName / BackupName |
Hyper-V virtual switch and vNIC names |
AutoUpdate |
Auto-download and install updates on startup without prompting (default: false) |
TempPath |
Directory for transcripts, reports, and exports (default: C:\Temp) |
DNSPresets |
Custom DNS server presets, merged with built-in (Google, Cloudflare, Quad9, OpenDNS) |
StorageBackendType |
Shared storage backend: iSCSI, FC, S2D, SMB3, NVMeoF, or Local (default: iSCSI) |
iSCSISubnet |
First 3 octets of your iSCSI network |
SANTargetMappings |
SAN target IP suffix-to-label mappings for iSCSI auto-detect |
SANTargetPairings |
Advanced: custom A/B pair definitions, host-to-pair assignments, and retry order for multi-controller SANs |
CustomVNICs |
Virtual NICs to create on the virtual switch during batch mode (Name + optional VLAN) |
StoragePaths |
Default Hyper-V storage paths (VM storage, ISOs, VHD cache, cluster paths) |
VMNaming |
VM naming pattern with tokens ({Site}, {Prefix}, {Seq}), site ID source and regex |
AgentInstaller |
Primary MSP agent installer config: tool name, service name, file pattern, install args, paths, exit codes |
AdditionalAgents |
Array of additional agent installer configs (same schema as AgentInstaller) for multi-agent environments |
FileServer |
File server / cloud storage for ISO/VHD downloads: nginx, Azure Blob, or static JSON (see File Server Setup) |
DefenderExclusionPaths / DefenderCommonVMPaths |
Windows Defender exclusion paths for Hyper-V hosts and VM storage |
CustomKMSKeys / CustomAVMAKeys |
Org-specific license keys, merged with built-in Microsoft GVLK/AVMA tables |
CustomVMTemplates |
Override built-in VM template specs or add new templates (partial overrides supported) |
CustomVMDefaults |
Default vCPU, RAM, disk size/type for non-template (custom) VMs |
CustomRoleTemplates |
Add custom server role templates with Windows features, merged with 10 built-in templates |
defaults.jsonis gitignored -- your secrets never leave your machine.
Automate full server builds with a JSON config file:
{
"ConfigType": "VM",
"Hostname": "WEB-01",
"IPAddress": "10.0.1.100",
"SubnetCIDR": 24,
"Gateway": "10.0.1.1",
"DNS1": "10.0.1.10",
"DomainName": "corp.example.com",
"EnableRDP": true,
"SetPowerPlan": "High Performance",
"CreateLocalAdmin": true,
"InstallAgents": ["MyRMM", "ExampleRMM"],
"ValidateCluster": false,
"AutoReboot": true
}Place batch_config.json next to the script and it runs automatically on launch. Set fields to null to skip steps. All steps are idempotent -- re-running the same config safely skips already-completed items. Use ConfigType: "HOST" for Hyper-V hosts -- adds extra steps (SET switch, custom vNICs, iSCSI, MPIO, host storage, Defender exclusions, agent install, cluster validation) for a total of 24 automated steps with transaction rollback on failure.
New in v1.8.0: InstallAgents array for multi-agent installs, ValidateCluster for cluster readiness checks.
Run RackStack non-interactively for automation (Ansible, RMM tools, PDQ, remote scripts):
# Quick health + disk + debloat assessment
RackStack.exe -Action QuickScan -Silent
# Disk cleanup (Standard profile)
RackStack.exe -Action Cleanup -Tier Standard -Silent
# System debloat (Aggressive, auto-detects Server vs Workstation)
RackStack.exe -Action Debloat -Tier Aggressive -Silent
# Run a batch config JSON file
RackStack.exe -Action Batch -Config "C:\path\to\config.json" -Silent
# Server inventory for CMDB/asset management
RackStack.exe -Action Inventory -OutputFormat JSON -SilentDownload and run the latest release in one command:
# Download + QuickScan (default)
irm https://raw.githubusercontent.com/TheAbider/RackStack/master/Install-RackStack.ps1 | iex
# Download + specific action
powershell -NoProfile -ExecutionPolicy Bypass -Command "& { $s = irm https://raw.githubusercontent.com/TheAbider/RackStack/master/Install-RackStack.ps1; $s | Set-Content rs.ps1; .\rs.ps1 -Action Cleanup -Tier Standard -Silent }"- name: Run RackStack cleanup on Windows hosts
win_shell: |
$url = 'https://github.com/TheAbider/RackStack/releases/latest/download/RackStack.exe'
Invoke-WebRequest -Uri $url -OutFile C:\Temp\RackStack.exe -UseBasicParsing
C:\Temp\RackStack.exe -Action Cleanup -Tier Standard -SilentAdd -OutputFormat JSON to get structured, machine-readable output from HealthCheck and QuickScan actions. Useful for feeding results into monitoring dashboards, alerting pipelines, or Ansible register:
# JSON health check
RackStack.exe -Action HealthCheck -OutputFormat JSON -Silent
# Parse JSON in PowerShell
$report = (.\RackStack.exe -Action HealthCheck -OutputFormat JSON -Silent | ConvertFrom-Json).Report
$report.Sections.CPU
$report.Issues
# Ansible: capture JSON output
# - name: Health check
# win_shell: C:\Temp\RackStack.exe -Action HealthCheck -OutputFormat JSON -Silent
# register: health_result
# - set_fact:
# health: "{{ health_result.stdout | from_json }}"Exit codes: 0 = success, 1 = error. All CLI actions return proper exit codes for CI/CD integration.
Tiers: Light (minimal, safe for prod), Standard (recommended), Aggressive (maximum cleanup/debloat).
| Category | Actions |
|---|---|
| System Ops | Cleanup Debloat HealthCheck QuickScan Batch Remediate Win11Cleanup DarkMode LightMode |
| Inventory | Inventory Export SysInfoAudit BIOSAudit SoftwareList HotfixAudit FeatureAudit DotNetAudit WindowsCapabilityAudit |
| Monitoring | Snapshot Trend Watch Alert Uptime CPUAudit MemoryAudit DiskAudit TempAudit EventLogCapacityAudit |
| Compliance | Compliance DriftCheck Diff Baseline Compare Aggregate ReportHTML |
| Security | Harden RegistryAudit TLSAudit CredGuardAudit AuditPolicyAudit AppLockerAudit DefenderExclusionAudit TokenPrivilegeAudit |
| Identity | UserAudit LocalGroupAudit LogonAudit ServiceAccountAudit KerberosAudit ACLAudit |
| Network | NetInfo DNSAudit NetworkAudit ListeningPorts NetStatAudit PortAudit ProxyAudit DHCPAudit VPNAudit ARPTableAudit NICTeamAudit TcpSettingsAudit SMBConnectionAudit |
| Firewall | FirewallAudit FirewallLogAudit |
| Storage | StorageAudit ShareAudit SMBAudit SMBSessionAudit BitLockerAudit NTFSAudit PageFileAudit ProfileAudit iSCSIAudit |
| Services | ServiceAudit TaskAudit TaskHistoryAudit EventAudit PrintAudit IISAudit SSHAudit WinRMAudit |
| Drivers/HW | DriverAudit USBDeviceAudit PowerAudit NUMAAudit NICOffloadAudit NICErrorAudit |
| Time/Boot | TimeAudit BootAudit PendingRebootAudit ScheduledRebootAudit RecoveryAudit LocaleAudit |
| Patching | PatchStatus WindowsUpdateAudit CertCheck UpdatePolicyAudit LicenseAudit AntivirusAudit |
| Infra | HyperVAudit ClusterAudit ClusterQuorumAudit ClusterNetworkAudit ClusterHealthScore BackupAudit GPOAudit WMIAudit PowerShellAudit RouteTableAudit HealthDashboard ServerScore |
| System Center | SCCMClientAudit SCOMAgentAudit WACConnectivityAudit AzureADAudit |
| Hyper-V | VMOvercommitAudit ReplicaLagAudit LiveMigrationAudit VirtualSwitchAudit VMInventoryExport VMSnapshotAudit VMResourceWaste |
| Storage (ext) | S2DAudit DedupAudit MPIOPathAudit ShadowCopyAudit QoSPolicyAudit DiskLatencyAudit StorageTimeoutAudit StorageHealthScore VolumeLabelAudit |
| Services (ext) | ServiceRecoveryAudit HandleLeakAudit |
| Persistence | AutoStartAudit EventSubAudit ComObjectAudit SymlinkAudit StartupScriptAudit HostsFileAudit |
| Domain | SecureChannelAudit DomainTrustAudit ScheduledExport ValidateConfig EnvAudit CrashAudit ProcessAudit |
| Fleet | FleetScan FleetReport Query RDPAudit |
Run RackStack.exe -ListActions or RackStack.exe -ListActions -OutputFormat JSON for the full list with descriptions.
RackStack/
├── RackStack.ps1 # Modular loader -- dot-sources 65 modules (dev use)
├── RackStack v{version}.ps1 # Monolithic build -- all modules in one file (deploy/compile)
├── RackStack.exe # Compiled from the monolithic .ps1 via ps2exe
├── defaults.json # Your environment config (gitignored)
├── defaults.example.json # Config template with examples
├── sync-to-monolithic.ps1 # Builds monolithic from Header.ps1 + Modules/
├── Modules/
│ ├── 00-Initialization.ps1 # Constants, variables, config loading
│ ├── 01-Console.ps1 # Console window management
│ ├── ... # 61 more modules
│ └── 64-SystemDebloat.ps1
├── Tests/
│ ├── Run-Tests.ps1 # 4080+ automated tests
│ ├── Validate-Release.ps1 # Pre-release validation suite
│ └── ...
└── docs/
└── FileServer-Setup.md # Set up your own ISO/VHD file server
65 modules numbered for load order. Dependencies flow downward.
| Range | Category | Highlights |
|---|---|---|
| 00-05 | Core | Variables, console, logging, input validation, navigation, OS detection |
| 06-14 | Networking | Adapters, IP config, VLANs, SET, iSCSI, hostname, domain, DNS, NTP |
| 15-24 | System | RDP, firewall, Defender, NTP, updates, licensing, passwords, local admin |
| 25-33 | Roles | Hyper-V, MPIO, clustering, performance, events, services, BitLocker |
| 34-39 | Tools | Help, utilities, batch config, health check, storage manager, cloud |
| 40-44 | VM Pipeline | Host storage, VHD management, ISO downloads, offline VHD, VM deployment |
| 45-50 | Session | Config export, session summary, cleanup, menus, entry point |
| 51-59 | Extended | Cluster dashboard, checkpoints, export/import, HTML reports, QoL, operations, remote, diagnostics, storage backends |
| 60-64 | Server Roles | Role templates, AD DS promotion, Hyper-V Replica, scheduled tasks, system debloat |
# Full test suite (~2,500+ tests, ~4 minutes)
powershell -ExecutionPolicy Bypass -File Tests\Run-Tests.ps1
# PSScriptAnalyzer (0 errors on all 65 modules + monolithic)
powershell -ExecutionPolicy Bypass -File Tests\pssa-check.ps1
# Pre-release validation (parse + PSSA + structure + sync + version + tests)
powershell -ExecutionPolicy Bypass -File Tests\Validate-Release.ps1Tests cover parsing, module loading, function existence (629 functions), version consistency, sync verification, input validation, navigation, hostname parsing, color themes, box widths, audit logging, custom vNIC features, iSCSI cabling checks, storage backend functions, and more.
- Edit modules in
Modules/ - Test with
.\RackStack.ps1(modular loader -- fast iteration, no build step) - Sync:
.\sync-to-monolithic.ps1(buildsRackStack v{version}.ps1monolithic) - Test:
.\Tests\Run-Tests.ps1 - Compile:
Invoke-PS2EXE -InputFile 'RackStack v{ver}.ps1' -OutputFile 'RackStack.exe'
The sync script matches #region/#endregion markers between modules and the monolithic file. All 64 region pairs are flat (non-nested). Use -DryRun to preview.
File summary:
RackStack.ps1= modular loader (for dev).RackStack v{version}.ps1= monolithic build (for deployment).RackStack.exe= compiled from monolithic (for end users).
- 72-char inner width for all menu boxes
- Semantic colors:
Success,Warning,Error,Info,Debug,Critical,Verbose Write-MenuItemfor menu item rendering (theme-aware, supports status columns)$null -eq $varform for null checks (PSSA requirement)$regexMatchesinstead of$matches(reserved automatic variable)- PowerShell verb-noun naming (
Test-,Get-,Set-,Show-,Start-)
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Special thanks to Ravi -- whose existence provided the spite-fueled motivation to build this entire project from scratch. Every feature is a testament to what happens when someone says "you can't automate that."
MIT -- use it, fork it, ship it.
