Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ powershell -ExecutionPolicy Bypass -File Tests\pssa-check.ps1

## Pull Request Checklist

- [ ] All 5,032 tests pass (`Run-Tests.ps1` exits with code 0)
- [ ] All 5,040 tests pass (`Run-Tests.ps1` exits with code 0)
- [ ] PSScriptAnalyzer reports 0 errors (`pssa-check.ps1`)
- [ ] Monolithic synced (`sync-to-monolithic.ps1` shows 0 parse errors)
- [ ] New functions follow PowerShell verb-noun naming (`Get-`, `Set-`, `Test-`, `Show-`)
Expand Down
8 changes: 8 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v1.110.0

Enable AD Recycle Bin — added to **AD DS Domain Controller Promotion** (`[6] Enable AD Recycle Bin`) and via the `ADRecycleBin` CLI action. Turns on Active Directory object recovery so deleted users/groups/OUs can be restored with their attributes intact.

It checks the forest, warns that enabling is **permanent** (the AD Recycle Bin cannot be disabled once on) and requires a forest functional level of 2008 R2 or higher, confirms, then runs `Enable-ADOptionalFeature`. The action is Dry-Run-aware and queued as **one-way** (no undo, matching the irreversibility). `-Action ADRecycleBin -OutputFormat JSON` reports the current enabled state without changing anything.

Addition to 61-ActiveDirectory (no new module). CLI actions: 192 → 193.

## v1.109.0

VHDX encryption-at-rest verification — added to **BitLocker Management** (`[7] VHDX Encryption-at-Rest Audit`) and via the `VHDXEncryptionAudit` CLI action. A **read-only** check that reports whether each Hyper-V VM's virtual disk (VHD/VHDX) sits on a BitLocker-protected volume — so you can confirm VM storage is encrypted at rest.
Expand Down
4 changes: 2 additions & 2 deletions Header.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
7h3 4b1d3r

.VERSION
1.109.0
1.110.0

.LAST UPDATED
05/23/2026
Expand Down Expand Up @@ -1391,7 +1391,7 @@
param(
# CLI headless mode: run a specific action without interactive menus
# Usage: RackStack.exe -Action Cleanup [-Tier Standard] [-Silent] [-OutputFormat JSON]
[ValidateSet('Cleanup', 'Debloat', 'HealthCheck', 'Batch', 'QuickScan', 'Inventory', 'DriftCheck', 'Snapshot', 'Compliance', 'Harden', 'Remediate', 'Aggregate', 'Compare', 'Export', 'Trend', 'CertCheck', 'ReportHTML', 'ListeningPorts', 'SoftwareList', 'Uptime', 'ServiceAudit', 'EventAudit', 'NetInfo', 'ScheduledExport', 'ValidateConfig', 'Watch', 'Query', 'Diff', 'Baseline', 'Alert', 'FleetScan', 'PatchStatus', 'UserAudit', 'FirewallAudit', 'TaskAudit', 'DiskAudit', 'TLSAudit', 'SMBAudit', 'DriverAudit', 'TimeAudit', 'BootAudit', 'GPOAudit', 'MemoryAudit', 'ProcessAudit', 'BackupAudit', 'ShareAudit', 'DNSAudit', 'PowerAudit', 'RegistryAudit', 'ProfileAudit', 'HyperVAudit', 'NetworkAudit', 'StorageAudit', 'FeatureAudit', 'AutoStartAudit', 'BIOSAudit', 'ClusterAudit', 'AuditPolicyAudit', 'EnvAudit', 'CrashAudit', 'LocalGroupAudit', 'WMIAudit', 'TempAudit', 'UpdatePolicyAudit', 'IISAudit', 'SSHAudit', 'BitLockerAudit', 'PrintAudit', 'CredGuardAudit', 'PortAudit', 'AntivirusAudit', 'DotNetAudit', 'RDPAudit', 'VPNAudit', 'HostsFileAudit', 'NetStatAudit', 'LicenseAudit', 'USBDeviceAudit', 'AppLockerAudit', 'EventSubAudit', 'HotfixAudit', 'SysInfoAudit', 'LogonAudit', 'ACLAudit', 'RecoveryAudit', 'ServiceAccountAudit', 'ProxyAudit', 'PendingRebootAudit', 'PageFileAudit', 'CPUAudit', 'DefenderExclusionAudit', 'KerberosAudit', 'DHCPAudit', 'NUMAAudit', 'SymlinkAudit', 'StartupScriptAudit', 'SecureChannelAudit', 'ComObjectAudit', 'FirewallLogAudit', 'ScheduledRebootAudit', 'PowerShellAudit', 'RouteTableAudit', 'TokenPrivilegeAudit', 'WindowsCapabilityAudit', 'ARPTableAudit', 'LocaleAudit', 'TaskHistoryAudit', 'NTFSAudit', 'Win11Cleanup', 'DarkMode', 'LightMode', 'iSCSIAudit', 'NICTeamAudit', 'SMBSessionAudit', 'WindowsUpdateAudit', 'ClusterQuorumAudit', 'S2DAudit', 'VirtualSwitchAudit', 'MPIOPathAudit', 'ServiceRecoveryAudit', 'VMOvercommitAudit', 'DedupAudit', 'ClusterNetworkAudit', 'ReplicaLagAudit', 'HandleLeakAudit', 'ShadowCopyAudit', 'QoSPolicyAudit', 'LiveMigrationAudit', 'DomainTrustAudit', 'DiskLatencyAudit', 'NICOffloadAudit', 'StorageTimeoutAudit', 'EventLogCapacityAudit', 'TcpSettingsAudit', 'WinRMAudit', 'ClusterHealthScore', 'VMInventoryExport', 'VMSnapshotAudit', 'StorageHealthScore', 'CSVSpaceAudit', 'SMBConnectionAudit', 'VolumeLabelAudit', 'NICErrorAudit', 'VMResourceWaste', 'HealthDashboard', 'SCCMClientAudit', 'SCOMAgentAudit', 'WACConnectivityAudit', 'AzureADAudit', 'ServerScore', 'FleetReport', 'PasswordPolicy', 'FirewallRuleAudit', 'GPResultAudit', 'DNSCacheAudit', 'TPMAudit', 'SecureBootAudit', 'TimeSkewAudit', 'NetworkProfileAudit', 'InsecureServiceAudit', 'SelfTest', 'CheckForUpdate', 'ExportLogs', 'UpdateSelf', 'Rollback', 'ScheduleUpdateCheck', 'Dashboard', 'History', 'Replay', 'AzureArcEnroll', 'DefenderEndpointOnboard', 'WSUSSetup', 'ADCSSetup', 'StorageMigrationSetup', 'GPOBackup', 'GPODrift', 'JEAList', 'NPSSetup', 'AlwaysOnVPNSetup', 'CISScan', 'SIEMSetup', 'SIEMStatus', 'WACSetup', 'WACStatus', 'VHDXEncryptionAudit')]
[ValidateSet('Cleanup', 'Debloat', 'HealthCheck', 'Batch', 'QuickScan', 'Inventory', 'DriftCheck', 'Snapshot', 'Compliance', 'Harden', 'Remediate', 'Aggregate', 'Compare', 'Export', 'Trend', 'CertCheck', 'ReportHTML', 'ListeningPorts', 'SoftwareList', 'Uptime', 'ServiceAudit', 'EventAudit', 'NetInfo', 'ScheduledExport', 'ValidateConfig', 'Watch', 'Query', 'Diff', 'Baseline', 'Alert', 'FleetScan', 'PatchStatus', 'UserAudit', 'FirewallAudit', 'TaskAudit', 'DiskAudit', 'TLSAudit', 'SMBAudit', 'DriverAudit', 'TimeAudit', 'BootAudit', 'GPOAudit', 'MemoryAudit', 'ProcessAudit', 'BackupAudit', 'ShareAudit', 'DNSAudit', 'PowerAudit', 'RegistryAudit', 'ProfileAudit', 'HyperVAudit', 'NetworkAudit', 'StorageAudit', 'FeatureAudit', 'AutoStartAudit', 'BIOSAudit', 'ClusterAudit', 'AuditPolicyAudit', 'EnvAudit', 'CrashAudit', 'LocalGroupAudit', 'WMIAudit', 'TempAudit', 'UpdatePolicyAudit', 'IISAudit', 'SSHAudit', 'BitLockerAudit', 'PrintAudit', 'CredGuardAudit', 'PortAudit', 'AntivirusAudit', 'DotNetAudit', 'RDPAudit', 'VPNAudit', 'HostsFileAudit', 'NetStatAudit', 'LicenseAudit', 'USBDeviceAudit', 'AppLockerAudit', 'EventSubAudit', 'HotfixAudit', 'SysInfoAudit', 'LogonAudit', 'ACLAudit', 'RecoveryAudit', 'ServiceAccountAudit', 'ProxyAudit', 'PendingRebootAudit', 'PageFileAudit', 'CPUAudit', 'DefenderExclusionAudit', 'KerberosAudit', 'DHCPAudit', 'NUMAAudit', 'SymlinkAudit', 'StartupScriptAudit', 'SecureChannelAudit', 'ComObjectAudit', 'FirewallLogAudit', 'ScheduledRebootAudit', 'PowerShellAudit', 'RouteTableAudit', 'TokenPrivilegeAudit', 'WindowsCapabilityAudit', 'ARPTableAudit', 'LocaleAudit', 'TaskHistoryAudit', 'NTFSAudit', 'Win11Cleanup', 'DarkMode', 'LightMode', 'iSCSIAudit', 'NICTeamAudit', 'SMBSessionAudit', 'WindowsUpdateAudit', 'ClusterQuorumAudit', 'S2DAudit', 'VirtualSwitchAudit', 'MPIOPathAudit', 'ServiceRecoveryAudit', 'VMOvercommitAudit', 'DedupAudit', 'ClusterNetworkAudit', 'ReplicaLagAudit', 'HandleLeakAudit', 'ShadowCopyAudit', 'QoSPolicyAudit', 'LiveMigrationAudit', 'DomainTrustAudit', 'DiskLatencyAudit', 'NICOffloadAudit', 'StorageTimeoutAudit', 'EventLogCapacityAudit', 'TcpSettingsAudit', 'WinRMAudit', 'ClusterHealthScore', 'VMInventoryExport', 'VMSnapshotAudit', 'StorageHealthScore', 'CSVSpaceAudit', 'SMBConnectionAudit', 'VolumeLabelAudit', 'NICErrorAudit', 'VMResourceWaste', 'HealthDashboard', 'SCCMClientAudit', 'SCOMAgentAudit', 'WACConnectivityAudit', 'AzureADAudit', 'ServerScore', 'FleetReport', 'PasswordPolicy', 'FirewallRuleAudit', 'GPResultAudit', 'DNSCacheAudit', 'TPMAudit', 'SecureBootAudit', 'TimeSkewAudit', 'NetworkProfileAudit', 'InsecureServiceAudit', 'SelfTest', 'CheckForUpdate', 'ExportLogs', 'UpdateSelf', 'Rollback', 'ScheduleUpdateCheck', 'Dashboard', 'History', 'Replay', 'AzureArcEnroll', 'DefenderEndpointOnboard', 'WSUSSetup', 'ADCSSetup', 'StorageMigrationSetup', 'GPOBackup', 'GPODrift', 'JEAList', 'NPSSetup', 'AlwaysOnVPNSetup', 'CISScan', 'SIEMSetup', 'SIEMStatus', 'WACSetup', 'WACStatus', 'VHDXEncryptionAudit', 'ADRecycleBin')]
[string]$Action,

[ValidateSet('Light', 'Standard', 'Aggressive')]
Expand Down
2 changes: 1 addition & 1 deletion Modules/00-Initialization.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ if (-not $PSCommandPath -and $script:ScriptPath) {
if (-not $script:ModuleRoot -and $script:ScriptPath) {
$script:ModuleRoot = [System.IO.Path]::GetDirectoryName($script:ScriptPath)
}
$script:ScriptVersion = "1.109.0"
$script:ScriptVersion = "1.110.0"
$script:ScriptStartTime = Get-Date

# Post-update cleanup: UpdateSelf / Rollback leave a `.pending-delete` sibling next to RackStack.exe.
Expand Down
2 changes: 1 addition & 1 deletion Modules/34-Help.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ function Search-HelpTopics {
@{ Title = "Performance"; Keywords = @("performance", "cpu", "memory", "disk", "io", "bandwidth", "dashboard", "process"); Description = "Live performance dashboard with CPU, memory, disk I/O, and network bandwidth monitoring" }
@{ Title = "Licensing & NTP"; Keywords = @("license", "activation", "kms", "avma", "ntp", "time", "timezone", "clock"); Description = "Windows licensing status (KMS/AVMA/Retail), NTP configuration, time sync, and timezone setup" }
@{ Title = "VM Management"; Keywords = @("checkpoint", "snapshot", "export", "import", "migration", "vhd", "iso"); Description = "VM checkpoints, export/import, migration readiness, VHD health, and ISO inventory" }
@{ Title = "CLI Actions"; Keywords = @("cli", "action", "headless", "automation", "fleet", "json", "audit", "scan", "score", "dashboard", "monitor", "policy", "sla", "netmap", "validate"); Description = "192 CLI actions for headless automation. Run -ListActions to see all. JSON output via -OutputFormat JSON. Key: ServerScore, HealthDashboard, FleetReport, CISScan, NPSSetup, AlwaysOnVPNSetup, SIEMStatus." }
@{ Title = "CLI Actions"; Keywords = @("cli", "action", "headless", "automation", "fleet", "json", "audit", "scan", "score", "dashboard", "monitor", "policy", "sla", "netmap", "validate"); Description = "193 CLI actions for headless automation. Run -ListActions to see all. JSON output via -OutputFormat JSON. Key: ServerScore, HealthDashboard, FleetReport, CISScan, NPSSetup, AlwaysOnVPNSetup, SIEMStatus." }
@{ Title = "SelfTest Action"; Keywords = @("selftest", "self-test", "diagnose", "diagnostic", "verify", "healthcheck", "sanity"); Description = "Internal diagnostic. -Action SelfTest checks PS version, elevation, module count, version consistency, defaults.json validity, temp path writability, FileServer reachability, and agent installer config. Exit 1 on any failure. Use -OutputFormat JSON for structured output." }
@{ Title = "Security Audits"; Keywords = @("security", "audit", "hardening", "compliance", "tls", "smb", "kerberos", "credguard", "applocker", "bitlockeraudit", "defenderexclusionaudit", "audit-policy", "secureboot", "tpm"); Description = "Security-focused CLI audits: TLSAudit, SMBAudit, KerberosAudit, CredGuardAudit, AppLockerAudit, BitLockerAudit, DefenderExclusionAudit, AuditPolicyAudit, SecureBootAudit, TPMAudit, UserAudit, LogonAudit, InsecureServiceAudit, RegistryAudit. All support -OutputFormat JSON." }
@{ Title = "Network Audits"; Keywords = @("netaudit", "dns", "firewall-audit", "firewalllog", "arp", "route", "tcp", "netstat", "dhcp", "netprofile", "winrm", "qos", "nicoffload"); Description = "Network audits: DNSAudit, DNSCacheAudit, FirewallAudit, FirewallRuleAudit, FirewallLogAudit, ARPTableAudit, RouteTableAudit, TcpSettingsAudit, NetStatAudit, DHCPAudit, NetworkProfileAudit, WinRMAudit, QoSPolicyAudit, NICOffloadAudit, NICErrorAudit, HostsFileAudit, VPNAudit, ProxyAudit." }
Expand Down
6 changes: 6 additions & 0 deletions Modules/50-EntryPoint.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ function Assert-Elevation {
@{ Action = 'WACSetup'; Description = 'Install + configure the Windows Admin Center gateway (verified MSI, port, certificate)' }
@{ Action = 'WACStatus'; Description = 'Show Windows Admin Center gateway status (service, port, listening)' }
@{ Action = 'VHDXEncryptionAudit'; Description = 'Read-only: report whether each VM virtual disk sits on a BitLocker-protected volume' }
@{ Action = 'ADRecycleBin'; Description = 'Show AD Recycle Bin status (JSON) or enable it interactively (irreversible)' }
@{ Action = 'Batch'; Description = 'JSON-driven full configuration' }
)
if ($script:CLIOutputFormat -eq 'JSON') {
Expand Down Expand Up @@ -2047,6 +2048,11 @@ footer{text-align:center;color:#999;font-size:12px;padding:16px}
$vhdxOk = Start-VHDXEncryptionAudit
[Environment]::Exit([int](-not $vhdxOk))
}
'ADRecycleBin' {
# AD Recycle Bin status (JSON) / interactive enable (console).
$adrbOk = Start-ADRecycleBin
[Environment]::Exit([int](-not $adrbOk))
}
'Batch' {
if (-not $script:CLIConfig) {
Write-OutputColor " ERROR: -Action Batch requires -Config <path>" -color "Error"
Expand Down
78 changes: 77 additions & 1 deletion Modules/61-ActiveDirectory.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ function Show-ADDSPromotionMenu {
Write-MenuItem -Text "[3] Read-Only Domain Controller (RODC)"
Write-MenuItem -Text "[4] Check AD DS Status"
Write-MenuItem -Text "[5] Replication Health Monitor"
Write-MenuItem -Text "[6] Enable AD Recycle Bin"
Write-OutputColor " └────────────────────────────────────────────────────────────────────────┘" -color "Info"
Write-OutputColor "" -color "Info"
Write-OutputColor " [B] ◄ Back" -color "Info"
Expand All @@ -732,8 +733,9 @@ function Show-ADDSPromotionMenu {
"3" { Install-ReadOnlyDC }
"4" { Show-ADDSStatus }
"5" { Show-ReplicationMonitor }
"6" { Enable-ADRecycleBinFeature }
default {
Write-OutputColor " Invalid choice. Enter 1-5 or B." -color "Error"
Write-OutputColor " Invalid choice. Enter 1-6 or B." -color "Error"
Start-Sleep -Seconds 1
}
}
Expand Down Expand Up @@ -1472,4 +1474,78 @@ function Show-ADDSStatus {
Write-OutputColor "" -color "Info"
Write-PressEnter
}

# Read-only: is the AD Recycle Bin optional feature enabled in this forest?
function Test-ADRecycleBinStatus {
try {
if ($null -eq (Get-Command -Name Get-ADOptionalFeature -ErrorAction SilentlyContinue)) {
return [PSCustomObject]@{ Available = $false; Enabled = $false; Forest = ''; ForestMode = '' }
}
$forest = Get-ADForest -ErrorAction Stop
$feat = Get-ADOptionalFeature -Filter "Name -eq 'Recycle Bin Feature'" -ErrorAction Stop
$enabled = ($null -ne $feat -and @($feat.EnabledScopes).Count -gt 0)
return [PSCustomObject]@{ Available = $true; Enabled = $enabled; Forest = "$($forest.Name)"; ForestMode = "$($forest.ForestMode)" }
}
catch {
return [PSCustomObject]@{ Available = $false; Enabled = $false; Forest = ''; ForestMode = '' }
}
}

# Interactive: enable the AD Recycle Bin. IRREVERSIBLE once enabled.
function Enable-ADRecycleBinFeature {
Clear-Host
Write-CenteredOutput "Enable AD Recycle Bin" -color "Info"
$s = Test-ADRecycleBinStatus
if (-not $s.Available) {
Write-OutputColor " Active Directory module unavailable (not a DC, or RSAT-AD-PowerShell missing)." -color "Error"; return
}
if ($s.Enabled) {
Write-OutputColor " AD Recycle Bin is already enabled for forest '$($s.Forest)'." -color "Info"; return
}
Write-OutputColor " Forest: $($s.Forest) (functional level: $($s.ForestMode))" -color "Info"
Write-OutputColor " WARNING: Enabling the AD Recycle Bin is PERMANENT — it cannot be disabled" -color "Warning"
Write-OutputColor " afterward, and requires a forest functional level of 2008 R2 or higher." -color "Warning"
if (-not (Confirm-UserAction -Message "Enable the AD Recycle Bin for '$($s.Forest)' (irreversible)?")) {
Write-OutputColor " Cancelled." -color "Info"; return
}

if ($script:DryRunMode -and -not $script:ApplyingDryRunQueue) {
$capForest = $s.Forest
Push-DryRunStep -Label "Enable AD Recycle Bin ($capForest)" -Category "ActiveDirectory" -OneWay $true `
-Params @{ Forest = $capForest } `
-Preflight { if ((Test-ADRecycleBinStatus).Enabled) { "AD Recycle Bin already enabled" } else { $true } }.GetNewClosure() `
-Apply {
Enable-ADOptionalFeature -Identity 'Recycle Bin Feature' -Scope ForestOrConfigurationSet -Target $capForest -Confirm:$false -ErrorAction Stop | Out-Null
}.GetNewClosure() `
-Undo { Write-OutputColor " AD Recycle Bin cannot be disabled once enabled — no undo." -color "Info" }.GetNewClosure()
Write-OutputColor " Queued (Dry-Run, ONE-WAY): enable AD Recycle Bin." -color "Warning"
Add-SessionChange -Category "DryRun" -Description "Queued AD Recycle Bin enable ($capForest)"
return
}

try {
Enable-ADOptionalFeature -Identity 'Recycle Bin Feature' -Scope ForestOrConfigurationSet -Target $s.Forest -Confirm:$false -ErrorAction Stop | Out-Null
Write-OutputColor " AD Recycle Bin enabled for forest '$($s.Forest)'." -color "Success"
Add-SessionChange -Category "ActiveDirectory" -Description "Enabled AD Recycle Bin ($($s.Forest))"
Clear-MenuCache
}
catch {
Write-OutputColor " Failed to enable AD Recycle Bin: $($_.Exception.Message)" -color "Error"
}
}

# CLI: ADRecycleBin — JSON status (read-only); interactive enable on console.
function Start-ADRecycleBin {
if ($script:CLIOutputFormat -eq 'JSON') {
$s = Test-ADRecycleBinStatus
Write-Output (@{
Tool = $script:ToolFullName; Version = $script:ScriptVersion; Action = 'ADRecycleBin'
Timestamp = (Get-Date -Format "yyyy-MM-ddTHH:mm:ss"); Hostname = $env:COMPUTERNAME
Available = $s.Available; Enabled = $s.Enabled; Forest = $s.Forest; ForestMode = $s.ForestMode
} | ConvertTo-Json)
return $true
}
Enable-ADRecycleBinFeature
return $true
}
#endregion
Loading
Loading