Security Solution by Umer Malik

Getting Started & Instructions

This page contains 6 specialized scripts designed for incident response, forensic collection, and endpoint hardening.

1. Accessing PowerShell as Administrator

2. Saving the Scripts (Required Folder)

IMPORTANT: All scripts MUST be saved in C:\Scripts. The commands provided rely on this specific folder path.

3. How to Run Scripts

āš™ļø Step 0 – Automatic Environment Setup

Run this script first to automatically create the C:\Scripts folder.

Run Command:

Set-ExecutionPolicy Bypass -Scope Process; C:\Scripts\Setup_Environment.ps1

Save Script As: C:\Scripts\Setup_Environment.ps1

# Environment Setup Script
# Created by Umer Malik
$Path = "C:\Scripts"
if (!(Test-Path $Path)) {
    New-Item -ItemType Directory -Path $Path | Out-Null
    Write-Host "[+] Folder C:\Scripts created successfully." -ForegroundColor Green
} else {
    Write-Host "[!] Folder C:\Scripts already exists." -ForegroundColor Yellow
}
    

šŸ”“ Phase 1 – Enterprise M365 Mailbox Security Audit

Run on CLEAN Admin PC only.

Requirements:

Step 1: Install Required Modules

Install-Module Microsoft.Graph -Scope CurrentUser -AllowClobber
Install-Module ExchangeOnlineManagement -Scope CurrentUser -AllowClobber

Step 2: Connect and Run Mailbox Audit Script

Set-ExecutionPolicy RemoteSigned -Scope Process
C:\Scripts\M365_Mailbox_Audit.ps1

Save Script As: C:\Scripts\M365_Mailbox_Audit.ps1

<#
Microsoft 365 Enterprise Mailbox Security Audit
Author: Umer Malik (Enterprise Version)
#>

# =========================
# CONFIGURATION
# =========================

$TeamsWebhookUrl = "https://YOUR-TEAMS-WEBHOOK-URL"
$SendEmailAlert = $false
$AlertEmailTo = "security@yourdomain.com"
$AlertEmailFrom = "audit@yourdomain.com"
$SMTPServer = "smtp.yourdomain.com"

# =========================
# INITIALIZATION
# =========================

$TimeStamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$OutputDir = "$env:USERPROFILE\Desktop\M365_Security_Audit_$TimeStamp"
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null

Start-Transcript "$OutputDir\AuditLog.txt"

Write-Host "Connecting to Microsoft Graph..."
Connect-MgGraph -Scopes "User.Read.All","MailboxSettings.Read","Mail.Read","AuditLog.Read.All"

Write-Host "Connecting to Exchange Online..."
Connect-ExchangeOnline

# =========================
# VARIABLES
# =========================

$HighRiskFindings = @()
$AllFindings = @()

$Users = Get-MgUser -All -Filter "userType eq 'Member'" -Property Id,UserPrincipalName,DisplayName

# =========================
# MAILBOX RULE AUDIT
# =========================

foreach ($User in $Users) {

    Write-Progress -Activity "Auditing Mailboxes" -Status $User.UserPrincipalName

    try {
        $Rules = Get-MgUserMailFolderMessageRule -UserId $User.Id -MailFolderId "Inbox"

        foreach ($Rule in $Rules) {

            $Risk = "Normal"

            # Detect Forwarding
            if ($Rule.Actions.ForwardTo -or $Rule.Actions.RedirectTo) {
                $Risk = "HIGH - External Forwarding"
            }

            # Detect Auto Delete
            if ($Rule.Actions.Delete -eq $true) {
                $Risk = "HIGH - Auto Delete Rule"
            }

            # Detect Move to Junk/Deleted
            if ($Rule.Actions.MoveToFolder -match "Deleted|Junk") {
                $Risk = "Medium - Suspicious Folder Move"
            }

            $Finding = [PSCustomObject]@{
                DisplayName = $User.DisplayName
                UserPrincipalName = $User.UserPrincipalName
                RuleName = $Rule.DisplayName
                RiskLevel = $Risk
            }

            $AllFindings += $Finding

            if ($Risk -like "HIGH*") {
                $HighRiskFindings += $Finding
            }
        }
    }
    catch {
        Write-Warning "Failed rule check for $($User.UserPrincipalName)"
    }

    # =========================
    # FORWARDING SETTINGS
    # =========================

    try {
        $Mailbox = Get-Mailbox $User.UserPrincipalName

        if ($Mailbox.ForwardingSmtpAddress -or $Mailbox.ForwardingAddress) {

            $Finding = [PSCustomObject]@{
                DisplayName = $User.DisplayName
                UserPrincipalName = $User.UserPrincipalName
                RuleName = "Mailbox Forwarding Enabled"
                RiskLevel = "HIGH - Mailbox Forwarding"
            }

            $HighRiskFindings += $Finding
            $AllFindings += $Finding
        }
    }
    catch {}
}

# =========================
# UNIFIED AUDIT LOG CHECK
# =========================

Write-Host "Checking Unified Audit Logs..."

$StartDate = (Get-Date).AddDays(-7)
$AuditLogs = Search-UnifiedAuditLog -StartDate $StartDate -EndDate (Get-Date) `
    -Operations "New-InboxRule","Set-Mailbox","Add-MailboxPermission","SendAs"

$AuditLogs | Export-Csv "$OutputDir\AuditLogEvents.csv" -NoTypeInformation

# =========================
# EXPORT REPORTS
# =========================

$AllFindings | Export-Csv "$OutputDir\AllFindings.csv" -NoTypeInformation
$HighRiskFindings | Export-Csv "$OutputDir\HighRiskFindings.csv" -NoTypeInformation

# =========================
# HTML REPORT
# =========================

$HtmlReport = @"
<html>
<head>
<title>M365 Security Audit</title>
<style>
body {font-family: Arial;}
table {border-collapse: collapse;}
th, td {border: 1px solid black; padding: 5px;}
th {background-color: #f2f2f2;}
.high {background-color: #ffcccc;}
</style>
</head>
<body>
<h2>Microsoft 365 Security Audit Report</h2>
<p>Date: $(Get-Date)</p>
<p>Total High Risk Findings: $($HighRiskFindings.Count)</p>
</body>
</html>
"@

$HtmlReport | Out-File "$OutputDir\AuditReport.html"

# =========================
# TEAMS ALERT
# =========================

if ($HighRiskFindings.Count -gt 0) {

    $Message = @{
        text = "🚨 M365 Security Alert: $($HighRiskFindings.Count) high-risk findings detected."
    }

    Invoke-RestMethod -Method Post -Uri $TeamsWebhookUrl -Body ($Message | ConvertTo-Json) -ContentType 'application/json'
}

# =========================
# EMAIL ALERT (OPTIONAL)
# =========================

if ($SendEmailAlert -and $HighRiskFindings.Count -gt 0) {
    Send-MailMessage -To $AlertEmailTo -From $AlertEmailFrom `
        -Subject "M365 Security Alert" `
        -Body "High-risk findings detected. See attached report." `
        -SmtpServer $SMTPServer `
        -Attachments "$OutputDir\HighRiskFindings.csv"
}

Stop-Transcript

Write-Host "Enterprise Security Audit Complete."

🟠 Phase 2 – Forensic Collection

Run Command:

Set-ExecutionPolicy RemoteSigned -Scope Process
C:\Scripts\IR_Deep_Collector.ps1

Save Script As: C:\Scripts\IR_Deep_Collector.ps1

# Incident Response Deep Collector
# Created by Umer Malik

$TimeStamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$OutputDir = "$env:USERPROFILE\Desktop\IR_Collection_$TimeStamp"
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null

Get-Process | Out-File "$OutputDir\Running_Processes.txt"
netstat -ano | Out-File "$OutputDir\Active_Network_Connections.txt"
schtasks /query /fo LIST /v | Out-File "$OutputDir\Scheduled_Tasks.txt"

reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run |
Out-File "$OutputDir\RunKeys.txt"

reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run |
Out-File "$OutputDir\RunKeys.txt" -Append

Write-Host "Collection Complete."

🟔 Phase 3 – Domain-Wide Scan

Run Command:

Set-ExecutionPolicy RemoteSigned -Scope Process
C:\Scripts\Domain_Triage.ps1

Save Script As: C:\Scripts\Domain_Triage.ps1

# Domain Wide Triage Scanner
# Created by Umer Malik

Import-Module ActiveDirectory
$Computers = Get-ADComputer -Filter * | Select -ExpandProperty Name
$Output = "$env:USERPROFILE\Desktop\Domain_Triage_Report.txt"

foreach ($Computer in $Computers) {
    Invoke-Command -ComputerName $Computer -ScriptBlock {
        Get-Process wscript,cscript,mshta,regsvr32 -ErrorAction SilentlyContinue
    } -ErrorAction SilentlyContinue |
    Out-File $Output -Append
}
Write-Host "Domain Scan Complete."

šŸ”“ Phase 4 – Malware Cleanup (Infected Machines)

Run Command:

C:\Scripts\IR_Cleanup_Tool.cmd

Save Script As: C:\Scripts\IR_Cleanup_Tool.cmd

:: IR_Cleanup_Tool.cmd
:: Created by Umer Malik
@echo off
title IR Cleanup Tool
setlocal

echo Requesting Administrator Authorization...
powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process PowerShell -ArgumentList '-NoExit -NoProfile -ExecutionPolicy Bypass -File ""%~f0""' -Verb RunAs" && exit /b

echo --- Stopping malware processes ---
powershell -Command ^
$MaliciousProcs = @("wscript", "cscript", "mshta", "regsvr32"); ^
foreach ($proc in $MaliciousProcs) { ^
    if (Get-Process $proc -ErrorAction SilentlyContinue) { ^
        Write-Host "[!] Stopping active threat engine: $proc" -ForegroundColor Red; ^
        Stop-Process -Name $proc -Force ^
    } ^
}

echo --- Purging temp files and Outlook cache ---
powershell -Command ^
$TempPaths = @("$env:TEMP\*","$env:LOCALAPPDATA\Temp\*","$env:APPDATA\Microsoft\Templates\*.one","$env:USERPROFILE\Downloads\*.one","$env:LOCALAPPDATA\Microsoft\Outlook\RoamCache\*"); ^
foreach ($path in $TempPaths) { ^
    Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue ^
}
echo [+] Temp folders and Outlook cache cleared.

echo --- Hunting recent OneNote payloads ---
powershell -Command ^
$Drives = Get-PSDrive -PSProvider FileSystem; ^
foreach ($Drive in $Drives) { ^
    Get-ChildItem -Path "$($Drive.Root)*" -Include *.one -Recurse -ErrorAction SilentlyContinue | ^
    Where-Object { $_.CreationTime -gt (Get-Date).AddDays(-14) } | ^
    ForEach-Object { ^
        Write-Host "[!] Found Suspicious OneNote: $($_.FullName)" -ForegroundColor Red; ^
        Rename-Item -Path $_.FullName -NewName "$($_.Name).infected_bak" -ErrorAction SilentlyContinue ^
    } ^
}

echo --- Registry persistence audit ---
powershell -Command ^
$RegPaths = @("HKCU:\Software\Microsoft\Windows\CurrentVersion\Run","HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"); ^
foreach ($path in $RegPaths) { ^
    Get-ItemProperty -Path $path | Select-Object -Property * -Exclude PSPath, PSParentPath, PSChildName, PSDrive, PSProvider | ^
    ForEach-Object { ^
        $props = $_.psobject.properties; ^
        foreach ($prop in $props) { ^
            if ($prop.Value -match "AppData" -or $prop.Value -match "Temp") { ^
                Write-Host "[!] WARNING: Suspicious Registry Key Found in $path" -ForegroundColor Yellow; ^
                Write-Host "    $($prop.Name) -> $($prop.Value)" -ForegroundColor Yellow; ^
            } ^
        } ^
    } ^
}

ipconfig /flushdns
powershell -Command "Start-MpScan -ScanType QuickScan"
echo --- CLEANUP COMPLETE ---
pause

šŸ”µ Phase 5 – Endpoint Hardening

Run Command:

PowerShell -ExecutionPolicy Bypass -File "C:\Scripts\EndpointHardening.ps1"

Save Script As: C:\Scripts\EndpointHardening.ps1

<#
.SYNOPSIS
Endpoint Hardening with True Rollback and Compliance Reporting
Author: Umer Malik
#>

# -------------------------------
# Check for Administrator
# -------------------------------
If (-NOT ([Security.Principal.WindowsPrincipal] `
    [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
    [Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Host "Run this script as Administrator." -ForegroundColor Red
    Exit 1
}

$BackupFile = "C:\Scripts\EndpointHardening_Backup.json"
$Results = @()

function Add-Result {
    param ($Control, $Status)
    $Results += [PSCustomObject]@{
        Control = $Control
        Status  = $Status
    }
}

# -------------------------------
# Function to Save Current State
# -------------------------------
function Backup-CurrentState {
    $State = @{}

    # Windows Script Host
    $wsh = Get-ItemProperty "HKLM:\Software\Microsoft\Windows Script Host\Settings" -Name Enabled -ErrorAction SilentlyContinue
    $State.WSH_Enabled = if ($wsh) { $wsh.Enabled } else { 1 }

    # PowerShell ScriptBlock Logging
    $pslog = Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging -ErrorAction SilentlyContinue
    $State.PS_ScriptBlockLogging = if ($pslog) { $pslog.EnableScriptBlockLogging } else { 0 }

    # Defender
    try { $def = Get-MpPreference } catch { $def = $null }
    $State.Defender = @{
        DisableRealtimeMonitoring = if ($def) { $def.DisableRealtimeMonitoring } else { $null }
        EnableNetworkProtection = if ($def) { $def.EnableNetworkProtection } else { $null }
        EnableControlledFolderAccess = if ($def) { $def.EnableControlledFolderAccess } else { $null }
    }

    # Firewall
    $fw = Get-NetFirewallProfile
    $State.Firewall = @{}
    foreach ($p in $fw) { $State.Firewall[$p.Name] = $p.Enabled }

    # SMBv1
    $State.SMBv1 = (Get-SmbServerConfiguration).EnableSMB1Protocol

    # NTLMv2
    $ntlm = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LmCompatibilityLevel -ErrorAction SilentlyContinue
    $State.NTLMv2 = if ($ntlm) { $ntlm.LmCompatibilityLevel } else { 0 }

    # LLMNR
    $llmnr = Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" -Name EnableMulticast -ErrorAction SilentlyContinue
    $State.LLMNR = if ($llmnr) { $llmnr.EnableMulticast } else { 1 }

    # Guest
    $guest = Get-LocalUser -Name Guest -ErrorAction SilentlyContinue
    $State.GuestEnabled = if ($guest) { $guest.Enabled } else { $null }

    # Remote Registry
    $rr = Get-Service RemoteRegistry -ErrorAction SilentlyContinue
    $State.RemoteRegistry = if ($rr) { $rr.Status } else { "Stopped" }

    # Save JSON
    $State | ConvertTo-Json -Depth 5 | Set-Content $BackupFile
    Write-Host "Backup of current state saved to $BackupFile" -ForegroundColor Cyan
}

# -------------------------------
# Function to Apply Hardening
# -------------------------------
function Apply-Hardening {

    Write-Host "`nApplying Endpoint Hardening..." -ForegroundColor Cyan

    # Backup current state first
    Backup-CurrentState

    # 1. Disable Windows Script Host
    New-Item -Path "HKLM:\Software\Microsoft\Windows Script Host\Settings" -Force | Out-Null
    Set-ItemProperty "HKLM:\Software\Microsoft\Windows Script Host\Settings" -Name Enabled -Value 0 -Type DWord
    Add-Result "Windows Script Host Disabled" ((Get-ItemProperty "HKLM:\Software\Microsoft\Windows Script Host\Settings").Enabled -eq 0)

    # 2. PowerShell Script Logging
    New-Item -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force | Out-Null
    Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging -Value 1 -Type DWord
    Add-Result "PowerShell ScriptBlock Logging Enabled" ((Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging").EnableScriptBlockLogging -eq 1)

    # 3. Defender Hardening
    try { Set-MpPreference -DisableRealtimeMonitoring $false -ErrorAction Stop } catch {}
    try { Set-MpPreference -EnableNetworkProtection Enabled -ErrorAction Stop } catch {}
    try { Set-MpPreference -EnableControlledFolderAccess Enabled -ErrorAction Stop } catch {}
    try { $def = Get-MpPreference } catch { $def = $null }
    Add-Result "Defender RealTime Protection" ($def -and $def.DisableRealtimeMonitoring -eq $false)
    Add-Result "Defender Network Protection" ($def -and $def.EnableNetworkProtection -eq 1)
    Add-Result "Controlled Folder Access" ($def -and $def.EnableControlledFolderAccess -eq 1)

    # 4. Firewall
    Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
    $fw = (Get-NetFirewallProfile | Where {$_.Enabled -eq "True"}).Count
    Add-Result "Firewall Enabled (All Profiles)" ($fw -eq 3)

    # 5. SMBv1 Disabled
    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
    Add-Result "SMBv1 Disabled" ((Get-SmbServerConfiguration).EnableSMB1Protocol -eq $false)

    # 6. NTLMv2 Only
    New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Force | Out-Null
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LmCompatibilityLevel -Value 5 -Type DWord
    Add-Result "NTLMv2 Enforced" ((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LmCompatibilityLevel -eq 5)

    # 7. LLMNR Disabled
    New-Item -Path "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" -Force | Out-Null
    Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" -Name EnableMulticast -Value 0 -Type DWord
    Add-Result "LLMNR Disabled" ((Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient").EnableMulticast -eq 0)

    # 8. Guest Disabled
    if (Get-LocalUser -Name "Guest" -ErrorAction SilentlyContinue) {
        Disable-LocalUser -Name "Guest"
    }
    Add-Result "Guest Account Disabled" ((Get-LocalUser Guest).Enabled -eq $false)

    # 9. Remote Registry Disabled
    if (Get-Service -Name "RemoteRegistry" -ErrorAction SilentlyContinue) {
        Stop-Service -Name "RemoteRegistry" -Force
        Set-Service -Name "RemoteRegistry" -StartupType Disabled
    }
    Add-Result "Remote Registry Disabled" ((Get-Service RemoteRegistry).Status -eq "Stopped")

    # -------------------------------
    # Report
    # -------------------------------
    Write-Host "`n====== Hardening Results ======" -ForegroundColor Yellow
    $Results | Format-Table -AutoSize
    $Failed = $Results | Where { $_.Status -eq $false }
    if ($Failed.Count -eq 0) {
        Write-Host "`nāœ… All controls successfully applied." -ForegroundColor Green
    } else {
        Write-Host "`n⚠ Some controls failed:" -ForegroundColor Red
        $Failed | Format-Table -AutoSize
    }
}

# -------------------------------
# Function to Rollback
# -------------------------------
function Rollback-Hardening {
    if (-Not (Test-Path $BackupFile)) {
        Write-Host "Backup file not found. Cannot rollback." -ForegroundColor Red
        return
    }

    Write-Host "`nRolling back Endpoint Hardening..." -ForegroundColor Cyan
    $State = Get-Content $BackupFile | ConvertFrom-Json

    # 1. Windows Script Host
    Set-ItemProperty "HKLM:\Software\Microsoft\Windows Script Host\Settings" -Name Enabled -Value $State.WSH_Enabled -Type DWord
    Add-Result "Windows Script Host Restored" ((Get-ItemProperty "HKLM:\Software\Microsoft\Windows Script Host\Settings").Enabled -eq $State.WSH_Enabled)

    # 2. PowerShell ScriptBlock Logging
    Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name EnableScriptBlockLogging -Value $State.PS_ScriptBlockLogging -Type DWord
    Add-Result "PowerShell ScriptBlock Logging Restored" ((Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging").EnableScriptBlockLogging -eq $State.PS_ScriptBlockLogging)

    # 3. Defender
    try { Set-MpPreference -DisableRealtimeMonitoring $State.Defender.DisableRealtimeMonitoring -ErrorAction SilentlyContinue } catch {}
    try { Set-MpPreference -EnableNetworkProtection $State.Defender.EnableNetworkProtection -ErrorAction SilentlyContinue } catch {}
    try { Set-MpPreference -EnableControlledFolderAccess $State.Defender.EnableControlledFolderAccess -ErrorAction SilentlyContinue } catch {}

    $def = Get-MpPreference
    Add-Result "Defender RealTime Restored" ($def.DisableRealtimeMonitoring -eq $State.Defender.DisableRealtimeMonitoring)
    Add-Result "Defender Network Protection Restored" ($def.EnableNetworkProtection -eq $State.Defender.EnableNetworkProtection)
    Add-Result "Controlled Folder Access Restored" ($def.EnableControlledFolderAccess -eq $State.Defender.EnableControlledFolderAccess)

    # 4. Firewall
    foreach ($name in $State.Firewall.Keys) {
        Set-NetFirewallProfile -Profile $name -Enabled $State.Firewall[$name]
    }
    $fw = (Get-NetFirewallProfile | Where {$_.Enabled -eq $true}).Count
    Add-Result "Firewall Restored" ($fw -eq ($State.Firewall.Keys | Measure-Object).Count)

    # 5. SMBv1
    Set-SmbServerConfiguration -EnableSMB1Protocol $State.SMBv1 -Force
    Add-Result "SMBv1 Restored" ((Get-SmbServerConfiguration).EnableSMB1Protocol -eq $State.SMBv1)

    # 6. NTLMv2
    Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name LmCompatibilityLevel -Value $State.NTLMv2 -Type DWord
    Add-Result "NTLMv2 Restored" ((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa").LmCompatibilityLevel -eq $State.NTLMv2)

    # 7. LLMNR
    Set-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" -Name EnableMulticast -Value $State.LLMNR -Type DWord
    Add-Result "LLMNR Restored" ((Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient").EnableMulticast -eq $State.LLMNR)

    # 8. Guest
    if ($State.GuestEnabled -eq $true) {
        Enable-LocalUser -Name Guest
    } else {
        Disable-LocalUser -Name Guest
    }
    Add-Result "Guest Account Restored" ((Get-LocalUser Guest).Enabled -eq $State.GuestEnabled)

    # 9. Remote Registry
    if ($State.RemoteRegistry -eq "Running") {
        Set-Service -Name RemoteRegistry -StartupType Automatic
        Start-Service RemoteRegistry
    } else {
        Stop-Service RemoteRegistry -Force
        Set-Service -Name RemoteRegistry -StartupType Disabled
    }
    $rr = (Get-Service RemoteRegistry).Status
    Add-Result "Remote Registry Restored" ($rr -eq $State.RemoteRegistry)

    # -------------------------------
    # Report
    # -------------------------------
    Write-Host "`n====== Rollback Results ======" -ForegroundColor Yellow
    $Results | Format-Table -AutoSize
    $Failed = $Results | Where { $_.Status -eq $false }
    if ($Failed.Count -eq 0) {
        Write-Host "`nāœ… Rollback completed successfully." -ForegroundColor Green
    } else {
        Write-Host "`n⚠ Some controls failed to restore:" -ForegroundColor Red
        $Failed | Format-Table -AutoSize
    }
}

# -------------------------------
# Menu
# -------------------------------
Write-Host "`nEndpoint Hardening Script"
Write-Host "1) Apply Hardening"
Write-Host "2) Rollback Hardening"
$choice = Read-Host "Enter your choice (1 or 2)"

switch ($choice) {
    "1" { Apply-Hardening }
    "2" { Rollback-Hardening }
    default { Write-Host "Invalid choice. Exiting." -ForegroundColor Red }
}

āš ļø Troubleshooting & Common Errors