Compare commits

..

15 commits
v2.2.2 ... main

Author SHA1 Message Date
NexusOne23
815a7e39d0 chore: complete version alignment 2.2.2 → 2.2.3 across all module files
Some checks failed
CI - PowerShell Quality Checks / PSScriptAnalyzer (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 5.1 (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 7.4 (push) Has been cancelled
CI - PowerShell Quality Checks / Validate Project Structure (push) Has been cancelled
Pester Tests / test (push) Has been cancelled
Bumps remaining 13 files that still referenced v2.2.2:
- 3 AdvancedSecurity config JSONs (AdminShares, Credentials, RDP)
- 4 AdvancedSecurity PS1 headers (Block-FingerProtocol, Set-SRPRules,
  Set-WindowsUpdate, Invoke-AdvancedSecurity)
- 2 AntiAI PS1 headers (Disable-CopilotAdvanced, Test-AntiAICompliance)
- 1 Privacy runtime output (Invoke-PrivacyHardening)
- CONTRIBUTING.md templates + FEATURES.md docs
- bug_report.md issue template

Historical annotations in Backup-PrivacySettings.ps1 ("added in v2.2.2")
intentionally preserved as they document feature introduction dates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:37:07 +01:00
NexusOne23
3bae0057ea fix: SetMaximumStorageSpaceForRecallSnapshots value 10 → 10240 (MB)
Some checks failed
CI - PowerShell Quality Checks / PSScriptAnalyzer (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 5.1 (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 7.4 (push) Has been cancelled
CI - PowerShell Quality Checks / Validate Project Structure (push) Has been cancelled
Pester Tests / test (push) Has been cancelled
Microsoft CSP stores Recall snapshot storage in MB, not GB.
10 GB = 10240 MB. Fixes apply, verify, and compliance check.

Closes #14

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:29:42 +01:00
NexusOne23
86d76cedc9 docs: add Android app description to ecosystem table
Some checks failed
CI - PowerShell Quality Checks / PSScriptAnalyzer (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 5.1 (push) Has been cancelled
CI - PowerShell Quality Checks / Test on PowerShell 7.4 (push) Has been cancelled
CI - PowerShell Quality Checks / Validate Project Structure (push) Has been cancelled
Pester Tests / test (push) Has been cancelled
2026-02-13 17:13:18 +01:00
NexusOne23
902d63f837 docs: add NoID Privacy ecosystem table with Android app 2026-02-13 17:09:18 +01:00
NexusOne23
e1320c4340 📝 Fix broken Troubleshooting anchor link in README.md
#troubleshooting → #-troubleshooting (GitHub strips emoji to dash prefix)
2026-02-13 17:03:35 +01:00
NexusOne23
34e270b47c docs: add sister project link to NoID Privacy for Linux 2026-02-13 16:59:37 +01:00
NexusOne23
1d90ff59fc chore: Update framework architecture asset for v2.2.3 2026-01-07 18:54:57 +01:00
NexusOne23
da9f937ee8 release: v2.2.3 - Fix Restore Mode module selection crash
CHANGELOG:
- Fixed: Restore Mode manual module selection crash (Critical)
- Root cause: .Split(',', ';', ' ') triggered wrong .NET overload
- Fix: Replaced with native PowerShell -split '[,; ]' operator
- Reported by: KatCat2

VERSION BUMP: 2.2.2 -> 2.2.3
- Updated 48 files with new version number
- CHANGELOG.md: Added v2.2.3 release notes
- README.md: Updated badge, module table, project status
2026-01-07 18:46:14 +01:00
NexusOne23
8435dbe97b fix: Replace broken .Split() with -split operator in Restore module selection
The previous implementation used .Split(',', ';', ' ') which
causes PowerShell to match the wrong .NET overload Split(string, Int32),
interpreting ';' as a count parameter and throwing a System.Int32
conversion error.

Replaced with native PowerShell -split operator using regex character
class [,; ] which correctly splits on comma, semicolon, or space.

Fixes: Restore Mode -> Manual Selection crash on any input
Reported-by: KatCat2
2026-01-07 18:27:32 +01:00
NexusOne23
74b73eda81 fix: cleanup loader lists, update New-DefaultConfig, fix CHANGELOG numbers
- Remove non-existent Backup/Restore-AntiAISettings from AntiAI.psm1 loader

- Remove non-existent Restore-PrivacySettings from Privacy.psm1 loader

- Update New-DefaultConfig: EdgeHardening 20->24, AdvancedSecurity 36->50

- Add missing options: nonInteractive, autoConfirm, module-specific settings

- Fix CHANGELOG.md: AntiAI 24->32, EdgeHardening 20->24, AdvancedSecurity 44->50
2025-12-24 21:15:09 +01:00
NexusOne23
c4d6d9c995 Add -NoReboot and -ForceReboot parameters to Restore-Session for GUI automation 2025-12-24 03:33:33 +01:00
NexusOne23
4c1af02ad9 Security hardening: PATH hijack fix, SHA256 checksums, connectivity endpoint
- Start-NoIDPrivacy.bat: Use absolute System32 path for powershell.exe
- Core/Validator.ps1: Replace 8.8.8.8 with www.msftconnecttest.com
- Tools/Generate-ReleaseChecksums.ps1: New script for release checksums
- SECURITY.md: Updated verification instructions
2025-12-22 23:17:22 +01:00
NexusOne23
79eb810096 fix: HTML report shows all 633 settings + improved print layout 2025-12-22 22:38:14 +01:00
NexusOne23
044cabf6c4 chore: update bug_report template to v2.2.2 2025-12-22 15:51:11 +01:00
NexusOne23
46d45c45c0 Add v2.2.2 release notes 2025-12-22 06:50:37 +01:00
65 changed files with 898 additions and 644 deletions

View file

@ -32,7 +32,7 @@ A clear description of what actually happened.
- **CPU**: [e.g., AMD Ryzen 7 9800X3D] - **CPU**: [e.g., AMD Ryzen 7 9800X3D]
- **TPM**: [e.g., 2.0 Present] - **TPM**: [e.g., 2.0 Present]
- **Third-Party AV**: [e.g., None, Windows Defender only] - **Third-Party AV**: [e.g., None, Windows Defender only]
- **Script Version**: [e.g., v2.2.1] - **Script Version**: [e.g., v2.2.3]
- **Execution Mode**: [Interactive / Direct / DryRun] - **Execution Mode**: [Interactive / Direct / DryRun]
**Get System Info:** **Get System Info:**

View file

@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
--- ---
## [2.2.3] - 2025-01-07
### 🔨 Bugfix Release
**Critical bugfix for Restore Mode manual module selection.**
### 🔨 Fixed
**Restore Mode Module Selection Crash (Critical)**
- Fixed: Selecting `[M] Restore only SELECTED modules` and entering any module number caused a fatal PowerShell error
- Root cause: `.Split(',', ';', ' ')` triggered wrong .NET overload `Split(string, Int32)`, interpreting `;` as count parameter
- Fix: Replaced with native PowerShell `-split '[,; ]'` operator
- Impact: Manual module selection in Restore workflow now works correctly
- Reported by: KatCat2
---
## [2.2.2] - 2025-12-22 ## [2.2.2] - 2025-12-22
### 🚀 Performance Release ### 🚀 Performance Release
@ -63,11 +80,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- All 7 registry policies confirmed correct per MS Policy CSP docs - All 7 registry policies confirmed correct per MS Policy CSP docs
- Version numbers aligned across all 50+ files - Version numbers aligned across all 50+ files
### 🔐 Verify Download
```
SHA256: fdb364d48e67a6889b44a519ba061cd570411158b8bdeb9b91ec845b7e270d96
```
--- ---
## [2.2.0] - 2025-12-08 ## [2.2.0] - 2025-12-08
@ -232,19 +244,19 @@ SHA256: fdb364d48e67a6889b44a519ba061cd570411158b8bdeb9b91ec845b7e270d96
- OneDrive telemetry off (sync functional) - OneDrive telemetry off (sync functional)
- App permissions default-deny - App permissions default-deny
**AntiAI** (24 policies) - AI Lockdown **AntiAI** (32 policies) - AI Lockdown
- Generative AI Master Switch (blocks ALL AI models system-wide) - Generative AI Master Switch (blocks ALL AI models system-wide)
- Windows Recall (complete deactivation + component protection) - Windows Recall (complete deactivation + component protection)
- Windows Copilot (system-wide disabled + hardware key remapped) - Windows Copilot (system-wide disabled + hardware key remapped)
- Click to Do, Paint AI, Notepad AI, Settings Agent - all disabled - Click to Do, Paint AI, Notepad AI, Settings Agent - all disabled
**EdgeHardening** (20 policies) - Microsoft Edge Security Baseline **EdgeHardening** (24 policies) - Microsoft Edge Security Baseline
- SmartScreen enforced, Tracking Prevention strict - SmartScreen enforced, Tracking Prevention strict
- SSL/TLS hardening, Extension security - SSL/TLS hardening, Extension security
- IE Mode restrictions - IE Mode restrictions
- Native PowerShell implementation (no LGPO.exe) - Native PowerShell implementation (no LGPO.exe)
**AdvancedSecurity** (44 settings) - Beyond Microsoft Baseline **AdvancedSecurity** (50 settings) - Beyond Microsoft Baseline
- **SRP .lnk Protection (CVE-2025-9491)** - Zero-day mitigation for ClickFix malware - **SRP .lnk Protection (CVE-2025-9491)** - Zero-day mitigation for ClickFix malware
- **RDP Hardening** - Disabled by default, TLS + NLA enforced - **RDP Hardening** - Disabled by default, TLS + NLA enforced
- **Legacy Protocol Blocking** - SMBv1, NetBIOS, LLMNR, WPAD, PowerShell v2 - **Legacy Protocol Blocking** - SMBv1, NetBIOS, LLMNR, WPAD, PowerShell v2

View file

@ -68,7 +68,7 @@ Modules/
``` ```
Modules/AdvancedSecurity/ Modules/AdvancedSecurity/
├── AdvancedSecurity.psd1 # Manifest with version 2.2.2 ├── AdvancedSecurity.psd1 # Manifest with version 2.2.3
├── AdvancedSecurity.psm1 # Loads Private/*.ps1 and Public/*.ps1 ├── AdvancedSecurity.psm1 # Loads Private/*.ps1 and Public/*.ps1
├── Config/ ├── Config/
│ ├── RDP.json # RDP hardening config │ ├── RDP.json # RDP hardening config
@ -105,7 +105,7 @@ Modules/AdvancedSecurity/
```powershell ```powershell
@{ @{
RootModule = 'YourModule.psm1' RootModule = 'YourModule.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'YOUR-GUID-HERE' # Generate with [guid]::NewGuid() GUID = 'YOUR-GUID-HERE' # Generate with [guid]::NewGuid()
Author = 'Your Name' Author = 'Your Name'
CompanyName = 'NoID Privacy' CompanyName = 'NoID Privacy'
@ -128,7 +128,7 @@ Modules/AdvancedSecurity/
Tags = @('Security', 'Hardening', 'Windows11') Tags = @('Security', 'Hardening', 'Windows11')
ProjectUri = 'https://github.com/yourusername/noid-privacy' ProjectUri = 'https://github.com/yourusername/noid-privacy'
ReleaseNotes = @" ReleaseNotes = @"
v2.2.2 - Initial Release v2.2.3 - Initial Release
- Feature 1 - Feature 1
- Feature 2 - Feature 2
"@ "@
@ -141,7 +141,7 @@ v2.2.2 - Initial Release
```powershell ```powershell
@{ @{
RootModule = 'AdvancedSecurity.psm1' RootModule = 'AdvancedSecurity.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
Author = 'NexusOne23' Author = 'NexusOne23'
Description = 'Advanced Security hardening beyond Microsoft Security Baseline' Description = 'Advanced Security hardening beyond Microsoft Security Baseline'
@ -155,7 +155,7 @@ v2.2.2 - Initial Release
PSData = @{ PSData = @{
Tags = @('Security', 'Hardening', 'RDP', 'TLS', 'Windows11') Tags = @('Security', 'Hardening', 'RDP', 'TLS', 'Windows11')
ReleaseNotes = @" ReleaseNotes = @"
v2.2.2 - Production Release v2.2.3 - Production Release
- RDP NLA enforcement + optional complete disable - RDP NLA enforcement + optional complete disable
- WDigest credential protection - WDigest credential protection
- Administrative shares disable (domain-aware) - Administrative shares disable (domain-aware)
@ -781,4 +781,4 @@ mkdir "Modules\YourModule\Config"
--- ---
**Questions? Study AdvancedSecurity v2.2.2 - it's the reference implementation!** 🎯 **Questions? Study AdvancedSecurity v2.2.3 - it's the reference implementation!** 🎯

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -79,83 +79,104 @@ function New-DefaultConfig {
) )
$defaultConfig = @{ $defaultConfig = @{
version = "2.2.2" version = "2.2.3"
modules = @{ modules = @{
SecurityBaseline = @{ SecurityBaseline = @{
enabled = $true enabled = $true
priority = 1 priority = 1
status = "IMPLEMENTED" status = "IMPLEMENTED"
bitLockerUSBEnforcement = $false
} }
ASR = @{ ASR = @{
enabled = $true enabled = $true
priority = 2 priority = 2
status = "IMPLEMENTED" status = "IMPLEMENTED"
usesManagementTools = $false
allowNewSoftware = $false
continueWithoutCloud = $true
} }
DNS = @{ DNS = @{
enabled = $true enabled = $true
priority = 3 priority = 3
provider = "" status = "IMPLEMENTED"
status = "IMPLEMENTED" provider = "Quad9"
dohMode = "REQUIRE"
} }
Privacy = @{ Privacy = @{
enabled = $true enabled = $true
priority = 4 priority = 4
mode = "" status = "IMPLEMENTED"
status = "IMPLEMENTED" mode = "MSRecommended"
disableCloudClipboard = $true
removeBloatware = $true
} }
AntiAI = @{ AntiAI = @{
enabled = $true enabled = $true
priority = 5 priority = 5
status = "IMPLEMENTED" status = "IMPLEMENTED"
description = "Disable all Windows 11 AI features (Recall, Copilot, Paint AI, etc.)" description = "Disable all Windows 11 AI features (Recall, Copilot, Paint AI, etc.)"
} }
EdgeHardening = @{ EdgeHardening = @{
enabled = $true enabled = $true
priority = 6 priority = 6
status = "IMPLEMENTED" status = "IMPLEMENTED"
description = "Microsoft Edge v139 Security Baseline: 20 security policies including SmartScreen enforcement, site isolation, SSL/TLS hardening, extension blocklist, IE Mode restrictions, and Spectre mitigations. No LGPO.exe dependency." description = "Microsoft Edge v139 Security Baseline: 24 security policies"
version = "2.2.2" allowExtensions = $true
baseline = "Edge v139" version = "2.2.3"
policies = 20 baseline = "Edge v139"
features = @{ policies = 24
smartscreen_enforcement = $true features = @{
site_isolation = $true smartscreen_enforcement = $true
ssl_error_blocking = $true site_isolation = $true
extension_blocklist = $true ssl_error_blocking = $true
ie_mode_restrictions = $true extension_blocklist = $true
spectre_mitigations = $true ie_mode_restrictions = $true
application_encryption = $true spectre_mitigations = $true
application_encryption = $true
auth_scheme_restrictions = $true auth_scheme_restrictions = $true
} }
} }
AdvancedSecurity = @{ AdvancedSecurity = @{
enabled = $true enabled = $true
priority = 7 priority = 7
status = "IMPLEMENTED" status = "IMPLEMENTED"
description = "Advanced Security hardening beyond MS Baseline: RDP NLA/Disable, WDigest protection, Admin Shares disable, Risky ports/services, Legacy TLS disable, WPAD disable, PowerShell v2 removal, SRP .lnk protection, Windows Update (3 GUI settings), Finger Protocol block. Opt-in by design (use -SecurityProfile Balanced/Enterprise/Maximum)" description = "Advanced Security hardening beyond MS Baseline"
version = "2.2.2" securityProfile = "Balanced"
policies = 36 disableRDP = $true
features = @{ forceAdminShares = $false
rdp_hardening = $true disableUPnP = $true
wdigest_protection = $true disableWirelessDisplay = $false
admin_shares_disable = $true disableDiscoveryProtocols = $true
risky_ports_closure = $true disableIPv6 = $false
risky_services_stop = $true version = "2.2.3"
legacy_tls_disable = $true policies = 50
wpad_disable = $true features = @{
powershell_v2_removal = $true rdp_hardening = $true
srp_lnk_protection = $true wdigest_protection = $true
windows_update_config = $true admin_shares_disable = $true
finger_protocol_block = $true risky_ports_closure = $true
risky_services_stop = $true
legacy_tls_disable = $true
wpad_disable = $true
powershell_v2_removal = $true
srp_lnk_protection = $true
windows_update_config = $true
finger_protocol_block = $true
wireless_display_security = $true
discovery_protocols_security = $true
firewall_shields_up = $true
ipv6_disable = $true
} }
profiles = @("Balanced", "Enterprise", "Maximum") profiles = @("Balanced", "Enterprise", "Maximum")
} }
} }
options = @{ options = @{
dryRun = $false dryRun = $false
createBackup = $true createBackup = $true
verboseLogging = $true verboseLogging = $true
autoReboot = $false autoReboot = $false
nonInteractive = $false
autoConfirm = $false
} }
} }
@ -413,7 +434,7 @@ function Get-EnabledModules {
# Check if module is actually implemented # Check if module is actually implemented
if (Test-ModuleAvailability -ModuleName $moduleName) { if (Test-ModuleAvailability -ModuleName $moduleName) {
$enabledModules += [PSCustomObject]@{ $enabledModules += [PSCustomObject]@{
Name = $moduleName Name = $moduleName
Priority = $moduleConfig.priority Priority = $moduleConfig.priority
} }
} }

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
.EXAMPLE .EXAMPLE
@ -24,7 +24,7 @@
# All configuration comes from config.json via Initialize-Config. # All configuration comes from config.json via Initialize-Config.
# Script-level variables # Script-level variables
$script:FrameworkVersion = "2.2.2" $script:FrameworkVersion = "2.2.3"
$script:FrameworkRoot = Split-Path -Parent $PSScriptRoot $script:FrameworkRoot = Split-Path -Parent $PSScriptRoot
$script:ExecutionStartTime = Get-Date $script:ExecutionStartTime = Get-Date
@ -409,8 +409,8 @@ function Invoke-Hardening {
else { else {
# CLI mode: Auto-detect session type based on module count # CLI mode: Auto-detect session type based on module count
$autoSessionType = if ($modulesToExecute.Count -ge 7) { "wizard" } $autoSessionType = if ($modulesToExecute.Count -ge 7) { "wizard" }
elseif ($modulesToExecute.Count -eq 1) { "advanced" } elseif ($modulesToExecute.Count -eq 1) { "advanced" }
else { "manual" } else { "manual" }
Set-SessionType -SessionType $autoSessionType Set-SessionType -SessionType $autoSessionType
Write-Log -Level DEBUG -Message "Session type auto-detected: $autoSessionType (based on $($modulesToExecute.Count) modules)" -Module "Framework" Write-Log -Level DEBUG -Message "Session type auto-detected: $autoSessionType (based on $($modulesToExecute.Count) modules)" -Module "Framework"
} }
@ -451,7 +451,7 @@ function Invoke-Hardening {
$ruleCount = $ruleIds.Count $ruleCount = $ruleIds.Count
$preFrameworkSnapshot = @{ $preFrameworkSnapshot = @{
ASR = @{ ASR = @{
RuleIds = $ruleIds RuleIds = $ruleIds
RuleActions = $ruleActions RuleActions = $ruleActions
SnapshotDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" SnapshotDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -26,10 +26,10 @@ enum LogLevel {
# NOTE: Must use Get-Variable to check existence (direct access fails in Strict Mode) # NOTE: Must use Get-Variable to check existence (direct access fails in Strict Mode)
if (-not (Get-Variable -Name 'LoggerConfig' -Scope Global -ErrorAction SilentlyContinue)) { if (-not (Get-Variable -Name 'LoggerConfig' -Scope Global -ErrorAction SilentlyContinue)) {
$global:LoggerConfig = @{ $global:LoggerConfig = @{
LogFilePath = "" LogFilePath = ""
MinimumLevel = [LogLevel]::INFO MinimumLevel = [LogLevel]::INFO
EnableConsole = $true EnableConsole = $true
EnableFile = $true EnableFile = $true
TimestampFormat = "yyyy-MM-dd HH:mm:ss" TimestampFormat = "yyyy-MM-dd HH:mm:ss"
} }
} }
@ -193,10 +193,10 @@ function Write-Log {
# Write to console with color coding (suppress DEBUG-level on console) # Write to console with color coding (suppress DEBUG-level on console)
if ($global:LoggerConfig.EnableConsole -and $Level -ge [LogLevel]::INFO) { if ($global:LoggerConfig.EnableConsole -and $Level -ge [LogLevel]::INFO) {
$consoleColor = switch ($Level) { $consoleColor = switch ($Level) {
([LogLevel]::DEBUG) { "Gray" } ([LogLevel]::DEBUG) { "Gray" }
([LogLevel]::INFO) { "White" } ([LogLevel]::INFO) { "White" }
([LogLevel]::WARNING) { "Yellow" } ([LogLevel]::WARNING) { "Yellow" }
([LogLevel]::ERROR) { "Red" } ([LogLevel]::ERROR) { "Red" }
([LogLevel]::SUCCESS) { "Green" } ([LogLevel]::SUCCESS) { "Green" }
default { "White" } default { "White" }
} }
@ -245,15 +245,15 @@ function Get-ErrorContext {
) )
$context = @{ $context = @{
Message = "" Message = ""
Exception = "" Exception = ""
Category = "" Category = ""
TargetObject = "" TargetObject = ""
ScriptName = "" ScriptName = ""
LineNumber = 0 LineNumber = 0
Command = "" Command = ""
StackTrace = "" StackTrace = ""
Summary = "" Summary = ""
} }
if ($null -eq $ErrorRecord) { if ($null -eq $ErrorRecord) {
@ -271,13 +271,15 @@ function Get-ErrorContext {
if ($ErrorRecord.InvocationInfo) { if ($ErrorRecord.InvocationInfo) {
$context.ScriptName = if ($ErrorRecord.InvocationInfo.ScriptName) { $context.ScriptName = if ($ErrorRecord.InvocationInfo.ScriptName) {
Split-Path -Leaf $ErrorRecord.InvocationInfo.ScriptName Split-Path -Leaf $ErrorRecord.InvocationInfo.ScriptName
} else { }
else {
"N/A" "N/A"
} }
$context.LineNumber = $ErrorRecord.InvocationInfo.ScriptLineNumber $context.LineNumber = $ErrorRecord.InvocationInfo.ScriptLineNumber
$context.Command = if ($ErrorRecord.InvocationInfo.MyCommand) { $context.Command = if ($ErrorRecord.InvocationInfo.MyCommand) {
$ErrorRecord.InvocationInfo.MyCommand.Name $ErrorRecord.InvocationInfo.MyCommand.Name
} else { }
else {
"N/A" "N/A"
} }
} }

View file

@ -12,7 +12,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Usage in modules: Usage in modules:
1. Call Test-NonInteractiveMode to check if prompts should be skipped 1. Call Test-NonInteractiveMode to check if prompts should be skipped
@ -194,7 +194,8 @@ function Write-NonInteractiveDecision {
$message = if ($null -ne $Value) { $message = if ($null -ne $Value) {
"[GUI] $Decision : $Value" "[GUI] $Decision : $Value"
} else { }
else {
"[GUI] $Decision" "[GUI] $Decision"
} }

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -64,7 +64,7 @@ function Initialize-BackupSystem {
displayName = "" # Auto-generated based on modules displayName = "" # Auto-generated based on modules
sessionType = "unknown" # wizard | advanced | manual sessionType = "unknown" # wizard | advanced | manual
timestamp = Get-Date -Format "o" timestamp = Get-Date -Format "o"
frameworkVersion = "2.2.2" frameworkVersion = "2.2.3"
modules = @() modules = @()
totalItems = 0 totalItems = 0
restorable = $true restorable = $true
@ -116,13 +116,13 @@ function Update-SessionDisplayName {
# Calculate ACTUAL settings count (not backup items!) # Calculate ACTUAL settings count (not backup items!)
# Each module applies a specific number of settings (Paranoid mode = max): # Each module applies a specific number of settings (Paranoid mode = max):
$settingsPerModule = @{ $settingsPerModule = @{
"SecurityBaseline" = 425 # 335 Registry + 67 Security Template + 23 Audit "SecurityBaseline" = 425 # 335 Registry + 67 Security Template + 23 Audit
"ASR" = 19 # 19 ASR Rules "ASR" = 19 # 19 ASR Rules
"DNS" = 5 # 5 DNS Settings "DNS" = 5 # 5 DNS Settings
"Privacy" = 78 # 54 Registry (MSRecommended) + 24 Bloatware "Privacy" = 78 # 54 Registry (MSRecommended) + 24 Bloatware
"AntiAI" = 32 # 32 Registry Policies (15 features) "AntiAI" = 32 # 32 Registry Policies (15 features)
"EdgeHardening" = 24 # 24 Edge Policies (22-23 applied depending on extensions) "EdgeHardening" = 24 # 24 Edge Policies (22-23 applied depending on extensions)
"AdvancedSecurity" = 50 # 50 Advanced Settings (15 features incl. Discovery Protocols + IPv6) "AdvancedSecurity" = 50 # 50 Advanced Settings (15 features incl. Discovery Protocols + IPv6)
} }
$totalSettings = 0 $totalSettings = 0
@ -382,10 +382,10 @@ function Backup-RegistryKey {
try { try {
$emptyMarker = @{ $emptyMarker = @{
KeyPath = $KeyPath KeyPath = $KeyPath
BackupDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" BackupDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
State = "NotExisted" State = "NotExisted"
Message = "Registry key did not exist before hardening - must be deleted during restore" Message = "Registry key did not exist before hardening - must be deleted during restore"
} | ConvertTo-Json } | ConvertTo-Json
$markerFile = Join-Path $backupFolder "$safeBackupName`_EMPTY.json" $markerFile = Join-Path $backupFolder "$safeBackupName`_EMPTY.json"
@ -935,10 +935,10 @@ function Restore-FromBackup {
try { try {
# Convert reg.exe path to PowerShell path # Convert reg.exe path to PowerShell path
$psKeyPath = $keyPathToRestore -replace 'HKEY_LOCAL_MACHINE', 'HKLM:' ` $psKeyPath = $keyPathToRestore -replace 'HKEY_LOCAL_MACHINE', 'HKLM:' `
-replace 'HKEY_CURRENT_USER', 'HKCU:' ` -replace 'HKEY_CURRENT_USER', 'HKCU:' `
-replace 'HKEY_CLASSES_ROOT', 'HKCR:' ` -replace 'HKEY_CLASSES_ROOT', 'HKCR:' `
-replace 'HKEY_USERS', 'HKU:' ` -replace 'HKEY_USERS', 'HKU:' `
-replace 'HKEY_CURRENT_CONFIG', 'HKCC:' -replace 'HKEY_CURRENT_CONFIG', 'HKCC:'
if (Test-Path $psKeyPath) { if (Test-Path $psKeyPath) {
Write-Log -Level INFO -Message "Deleting existing protected key: $psKeyPath before re-import." -Module "Rollback" Write-Log -Level INFO -Message "Deleting existing protected key: $psKeyPath before re-import." -Module "Rollback"
@ -1033,11 +1033,23 @@ function Invoke-RestoreRebootPrompt {
Offers immediate or deferred reboot with countdown. Offers immediate or deferred reboot with countdown.
Uses validation loop for consistent behavior. Uses validation loop for consistent behavior.
.PARAMETER NoReboot
Skip the reboot prompt entirely (for automation/GUI usage)
.PARAMETER ForceReboot
Automatically reboot without prompting (for automation)
.OUTPUTS .OUTPUTS
None None
#> #>
[CmdletBinding()] [CmdletBinding()]
param() param(
[Parameter(Mandatory = $false)]
[switch]$NoReboot,
[Parameter(Mandatory = $false)]
[switch]$ForceReboot
)
Write-Host "" Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
@ -1077,7 +1089,33 @@ function Invoke-RestoreRebootPrompt {
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host "" Write-Host ""
# Prompt user with validation loop # Check if running in NonInteractive mode (e.g., from GUI)
$isNonInteractive = [Environment]::GetCommandLineArgs() -contains '-NonInteractive'
# Handle -ForceReboot: immediately reboot without prompt
if ($ForceReboot) {
Write-Host ""
Write-Host "[>] ForceReboot specified - rebooting system now..." -ForegroundColor Yellow
Write-Host ""
Restart-Computer -Force
return
}
# Handle -NoReboot or NonInteractive mode: skip the prompt
if ($NoReboot -or $isNonInteractive) {
Write-Host ""
if ($NoReboot) {
Write-Host "[!] NoReboot specified - reboot prompt skipped" -ForegroundColor Yellow
}
else {
Write-Host "[!] Running in NonInteractive mode - reboot prompt skipped" -ForegroundColor Yellow
}
Write-Host " Please reboot manually to complete the restore." -ForegroundColor Gray
Write-Host ""
return
}
# Interactive mode: prompt user
do { do {
Write-Host "Reboot now? [Y/N] (default: Y): " -NoNewline -ForegroundColor White Write-Host "Reboot now? [Y/N] (default: Y): " -NoNewline -ForegroundColor White
$choice = Read-Host $choice = Read-Host
@ -1175,8 +1213,8 @@ function Restore-AllBackups {
Write-Log -Level WARNING -Message "Full rollback completed with some failures" -Module "Rollback" Write-Log -Level WARNING -Message "Full rollback completed with some failures" -Module "Rollback"
} }
# Prompt for reboot after restore # Prompt for reboot after restore (pass through reboot parameters)
Invoke-RestoreRebootPrompt Invoke-RestoreRebootPrompt -NoReboot:$NoReboot -ForceReboot:$ForceReboot
return $allSucceeded return $allSucceeded
} }
@ -1344,6 +1382,12 @@ function Restore-Session {
.PARAMETER ModuleNames .PARAMETER ModuleNames
Optional array of specific module names to restore (restores all if not specified) Optional array of specific module names to restore (restores all if not specified)
.PARAMETER NoReboot
Skip the reboot prompt entirely (for automation/GUI usage)
.PARAMETER ForceReboot
Automatically reboot without prompting (for automation)
.OUTPUTS .OUTPUTS
Boolean indicating overall success Boolean indicating overall success
#> #>
@ -1354,7 +1398,13 @@ function Restore-Session {
[string]$SessionPath, [string]$SessionPath,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[string[]]$ModuleNames [string[]]$ModuleNames,
[Parameter(Mandatory = $false)]
[switch]$NoReboot,
[Parameter(Mandatory = $false)]
[switch]$ForceReboot
) )
if (-not (Test-Path $SessionPath)) { if (-not (Test-Path $SessionPath)) {
@ -1372,7 +1422,8 @@ function Restore-Session {
Write-RestoreLog -Level INFO -Message "Session Path: $SessionPath" Write-RestoreLog -Level INFO -Message "Session Path: $SessionPath"
if ($ModuleNames) { if ($ModuleNames) {
Write-RestoreLog -Level INFO -Message "Specific Modules: $($ModuleNames -join ', ')" Write-RestoreLog -Level INFO -Message "Specific Modules: $($ModuleNames -join ', ')"
} else { }
else {
Write-RestoreLog -Level INFO -Message "Restoring: ALL modules" Write-RestoreLog -Level INFO -Message "Restoring: ALL modules"
} }
Write-RestoreLog -Level INFO -Message "========================================" Write-RestoreLog -Level INFO -Message "========================================"
@ -1800,7 +1851,7 @@ function Restore-Session {
for ($i = 0; $i -lt $preFramework.ASR.RuleIds.Count; $i++) { for ($i = 0; $i -lt $preFramework.ASR.RuleIds.Count; $i++) {
if ($preFramework.ASR.RuleActions[$i] -ne 0) { if ($preFramework.ASR.RuleActions[$i] -ne 0) {
$asrRulesToRestore += @{ $asrRulesToRestore += @{
GUID = $preFramework.ASR.RuleIds[$i] GUID = $preFramework.ASR.RuleIds[$i]
Action = $preFramework.ASR.RuleActions[$i] Action = $preFramework.ASR.RuleActions[$i]
} }
} }
@ -1843,8 +1894,8 @@ function Restore-Session {
$ruleActions = $asrRulesToRestore | ForEach-Object { $_.Action } $ruleActions = $asrRulesToRestore | ForEach-Object { $_.Action }
Set-MpPreference -AttackSurfaceReductionRules_Ids $ruleIds ` Set-MpPreference -AttackSurfaceReductionRules_Ids $ruleIds `
-AttackSurfaceReductionRules_Actions $ruleActions ` -AttackSurfaceReductionRules_Actions $ruleActions `
-ErrorAction Stop -ErrorAction Stop
$sourceDesc = if ($usePreFramework) { "PreFramework snapshot (TRUE pre-hardening)" } else { "ASR_ActiveConfiguration.json" } $sourceDesc = if ($usePreFramework) { "PreFramework snapshot (TRUE pre-hardening)" } else { "ASR_ActiveConfiguration.json" }
Write-Log -Level SUCCESS -Message "ASR rules restored via Set-MpPreference ($($asrRulesToRestore.Count) active rules from $sourceDesc)" -Module "Rollback" Write-Log -Level SUCCESS -Message "ASR rules restored via Set-MpPreference ($($asrRulesToRestore.Count) active rules from $sourceDesc)" -Module "Rollback"
@ -1912,7 +1963,8 @@ function Restore-Session {
Write-Log -Level SUCCESS -Message "Explorer Advanced settings restored via PowerShell" -Module "Rollback" Write-Log -Level SUCCESS -Message "Explorer Advanced settings restored via PowerShell" -Module "Rollback"
} }
} }
} catch { }
catch {
Write-Log -Level WARNING -Message "PowerShell-based Explorer restore failed: $($_.Exception.Message)" -Module "Rollback" Write-Log -Level WARNING -Message "PowerShell-based Explorer restore failed: $($_.Exception.Message)" -Module "Rollback"
} }
} }
@ -1936,10 +1988,10 @@ function Restore-Session {
} }
$regType = switch ($entry.Type) { $regType = switch ($entry.Type) {
"DWord" { "DWord" } "DWord" { "DWord" }
"String" { "String" } "String" { "String" }
"MultiString" { "MultiString" } "MultiString" { "MultiString" }
default { "String" } default { "String" }
} }
$existing = Get-ItemProperty -Path $keyPath -Name $entry.Name -ErrorAction SilentlyContinue $existing = Get-ItemProperty -Path $keyPath -Name $entry.Name -ErrorAction SilentlyContinue
@ -2178,13 +2230,13 @@ function Restore-Session {
} }
$regType = switch ($entry.Type) { $regType = switch ($entry.Type) {
"DWord" { "DWord" } "DWord" { "DWord" }
"String" { "String" } "String" { "String" }
"MultiString" { "MultiString" } "MultiString" { "MultiString" }
"ExpandString" { "ExpandString" } "ExpandString" { "ExpandString" }
"Binary" { "Binary" } "Binary" { "Binary" }
"QWord" { "QWord" } "QWord" { "QWord" }
default { "String" } default { "String" }
} }
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
@ -2246,7 +2298,7 @@ function Restore-Session {
"HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications", "HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement", "HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement",
"HKCU:\SOFTWARE\Microsoft\Personalization\Settings", "HKCU:\SOFTWARE\Microsoft\Personalization\Settings",
# NEW: Input Personalization Settings (v2.2.2 - FIX missing HKCU restore) # NEW: Input Personalization Settings (v2.2.3 - FIX missing HKCU restore)
"HKCU:\SOFTWARE\Microsoft\InputPersonalization", "HKCU:\SOFTWARE\Microsoft\InputPersonalization",
"HKCU:\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore", "HKCU:\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore",
"HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\appDiagnostics" "HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\appDiagnostics"
@ -2263,7 +2315,8 @@ function Restore-Session {
Remove-ItemProperty -Path $keyPath -Name $prop -ErrorAction SilentlyContinue Remove-ItemProperty -Path $keyPath -Name $prop -ErrorAction SilentlyContinue
} }
} }
} catch { }
catch {
Write-Log -Level DEBUG -Message "Could not clear $keyPath : $_" -Module "Rollback" Write-Log -Level DEBUG -Message "Could not clear $keyPath : $_" -Module "Rollback"
} }
} }
@ -2280,12 +2333,12 @@ function Restore-Session {
} }
$regType = switch ($entry.Type) { $regType = switch ($entry.Type) {
"DWord" { "DWord" } "DWord" { "DWord" }
"String" { "String" } "String" { "String" }
"MultiString" { "MultiString" } "MultiString" { "MultiString" }
"ExpandString" { "ExpandString" } "ExpandString" { "ExpandString" }
"Binary" { "Binary" } "Binary" { "Binary" }
default { "String" } default { "String" }
} }
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
@ -2463,13 +2516,13 @@ function Restore-Session {
} }
$regType = switch ($entry.Type) { $regType = switch ($entry.Type) {
"DWord" { "DWord" } "DWord" { "DWord" }
"String" { "String" } "String" { "String" }
"MultiString" { "MultiString" } "MultiString" { "MultiString" }
"ExpandString" { "ExpandString" } "ExpandString" { "ExpandString" }
"Binary" { "Binary" } "Binary" { "Binary" }
"QWord" { "QWord" } "QWord" { "QWord" }
default { "String" } default { "String" }
} }
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
@ -2677,7 +2730,8 @@ function Restore-Session {
Write-Host " All security settings have been reverted to backup state" -ForegroundColor White Write-Host " All security settings have been reverted to backup state" -ForegroundColor White
Write-Host " Modules restored: $($reversedModules.Count) | Total items: $($manifest.totalItems)" -ForegroundColor Gray Write-Host " Modules restored: $($reversedModules.Count) | Total items: $($manifest.totalItems)" -ForegroundColor Gray
Write-Host "" Write-Host ""
} else { }
else {
Write-Host "" Write-Host ""
Write-Host " RESTORE COMPLETED WITH ISSUES " -ForegroundColor Yellow Write-Host " RESTORE COMPLETED WITH ISSUES " -ForegroundColor Yellow
Write-Host "" Write-Host ""
@ -2690,8 +2744,8 @@ function Restore-Session {
Write-Host "" Write-Host ""
Write-Host "" Write-Host ""
# Prompt for reboot after restore # Prompt for reboot after restore (pass through reboot parameters)
Invoke-RestoreRebootPrompt Invoke-RestoreRebootPrompt -NoReboot:$NoReboot -ForceReboot:$ForceReboot
# Final restore log entry # Final restore log entry
$endTime = Get-Date $endTime = Get-Date

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -27,9 +27,9 @@ function Test-Prerequisites {
Write-Log -Level INFO -Message "Starting prerequisite validation" -Module "Validator" Write-Log -Level INFO -Message "Starting prerequisite validation" -Module "Validator"
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
Success = $true Success = $true
Errors = @() Errors = @()
Warnings = @() Warnings = @()
SystemInfo = $null SystemInfo = $null
} }
@ -133,11 +133,11 @@ function Get-WindowsVersion {
} }
return [PSCustomObject]@{ return [PSCustomObject]@{
Version = $versionName Version = $versionName
BuildNumber = $buildNumber BuildNumber = $buildNumber
IsWindows11 = $isWindows11 IsWindows11 = $isWindows11
IsSupported = $isSupported IsSupported = $isSupported
Edition = $os.Caption Edition = $os.Caption
Architecture = $os.OSArchitecture Architecture = $os.OSArchitecture
} }
} }
@ -174,8 +174,8 @@ function Test-InternetConnectivity {
param() param()
try { try {
# Using Google DNS (8.8.8.8) - intentional for internet connectivity check # Using Microsoft NCSI endpoint - same as Windows uses for connectivity detection
$response = Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet -ErrorAction Stop $response = Test-Connection -ComputerName "www.msftconnecttest.com" -Count 1 -Quiet -ErrorAction Stop
return $response return $response
} }
catch { catch {
@ -200,26 +200,26 @@ function Test-TPMAvailable {
if ($null -eq $tpm) { if ($null -eq $tpm) {
return [PSCustomObject]@{ return [PSCustomObject]@{
Present = $false Present = $false
Version = "N/A" Version = "N/A"
Enabled = $false Enabled = $false
Activated = $false Activated = $false
} }
} }
return [PSCustomObject]@{ return [PSCustomObject]@{
Present = $tpm.TpmPresent Present = $tpm.TpmPresent
Version = if ($tpm.ManufacturerVersion) { $tpm.ManufacturerVersion } else { "2.0" } Version = if ($tpm.ManufacturerVersion) { $tpm.ManufacturerVersion } else { "2.0" }
Enabled = $tpm.TpmEnabled Enabled = $tpm.TpmEnabled
Activated = $tpm.TpmActivated Activated = $tpm.TpmActivated
} }
} }
catch { catch {
Write-Log -Level WARNING -Message "Unable to check TPM status: $_" -Module "Validator" Write-Log -Level WARNING -Message "Unable to check TPM status: $_" -Module "Validator"
return [PSCustomObject]@{ return [PSCustomObject]@{
Present = $false Present = $false
Version = "Unknown" Version = "Unknown"
Enabled = $false Enabled = $false
Activated = $false Activated = $false
} }
} }
@ -294,14 +294,14 @@ function Get-SystemInfo {
$internet = Test-InternetConnectivity $internet = Test-InternetConnectivity
return [PSCustomObject]@{ return [PSCustomObject]@{
OS = $osInfo OS = $osInfo
TPM = $tpmInfo TPM = $tpmInfo
SecureBoot = $secureBoot SecureBoot = $secureBoot
Virtualization = $virtualization Virtualization = $virtualization
IsAdministrator = $isAdmin IsAdministrator = $isAdmin
DiskSpaceAvailable = $diskSpace DiskSpaceAvailable = $diskSpace
InternetConnected = $internet InternetConnected = $internet
PowerShellVersion = $PSVersionTable.PSVersion.ToString() PowerShellVersion = $PSVersionTable.PSVersion.ToString()
} }
} }
@ -332,9 +332,9 @@ function Test-DomainJoined {
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
IsDomainJoined = $isDomainJoined IsDomainJoined = $isDomainJoined
DomainName = if ($isDomainJoined) { $computerSystem.Domain } else { "N/A" } DomainName = if ($isDomainJoined) { $computerSystem.Domain } else { "N/A" }
Workgroup = if (-not $isDomainJoined) { $computerSystem.Workgroup } else { "N/A" } Workgroup = if (-not $isDomainJoined) { $computerSystem.Workgroup } else { "N/A" }
UserConfirmed = $false UserConfirmed = $false
} }
if ($isDomainJoined) { if ($isDomainJoined) {
@ -384,9 +384,9 @@ function Test-DomainJoined {
Write-Log -Level ERROR -Message "Failed to check domain status: $_" -Module "Validator" -Exception $_.Exception Write-Log -Level ERROR -Message "Failed to check domain status: $_" -Module "Validator" -Exception $_.Exception
return [PSCustomObject]@{ return [PSCustomObject]@{
IsDomainJoined = $false IsDomainJoined = $false
DomainName = "Error" DomainName = "Error"
Workgroup = "Error" Workgroup = "Error"
UserConfirmed = $false UserConfirmed = $false
} }
} }
} }
@ -416,7 +416,7 @@ function Confirm-SystemBackup {
Write-Log -Level INFO -Message "Backup recommendation: non-interactive confirmation (no prompt shown)" -Module "Validator" Write-Log -Level INFO -Message "Backup recommendation: non-interactive confirmation (no prompt shown)" -Module "Validator"
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
UserConfirmed = $true UserConfirmed = $true
BackupRecommended = $true BackupRecommended = $true
} }

View file

@ -1,6 +1,6 @@
# NoID Privacy - Complete Feature List # NoID Privacy - Complete Feature List
**Framework Version:** v2.2.2 **Framework Version:** v2.2.3
**Total Security Settings:** 633 (Paranoid mode) **Total Security Settings:** 633 (Paranoid mode)
**Modules:** 7 (All Production-Ready) **Modules:** 7 (All Production-Ready)
**Last Updated:** December 22, 2025 **Last Updated:** December 22, 2025
@ -11,13 +11,13 @@
| Module | Settings | Status | Description | | Module | Settings | Status | Description |
|--------|----------|--------|-------------| |--------|----------|--------|-------------|
| **SecurityBaseline** | 425 | ✅ v2.2.2 | Microsoft Security Baseline for Windows 11 v25H2 | | **SecurityBaseline** | 425 | ✅ v2.2.3 | Microsoft Security Baseline for Windows 11 v25H2 |
| **ASR** | 19 | ✅ v2.2.2 | Attack Surface Reduction rules | | **ASR** | 19 | ✅ v2.2.3 | Attack Surface Reduction rules |
| **DNS** | 5 | ✅ v2.2.2 | Secure DNS with DoH encryption | | **DNS** | 5 | ✅ v2.2.3 | Secure DNS with DoH encryption |
| **Privacy** | 78 | ✅ v2.2.2 | Telemetry control, OneDrive hardening (Strict: 70 Registry + 2 Services + 6 OneDrive) | | **Privacy** | 78 | ✅ v2.2.3 | Telemetry control, OneDrive hardening (Strict: 70 Registry + 2 Services + 6 OneDrive) |
| **AntiAI** | 32 | ✅ v2.2.2 | AI lockdown (15 features, 32 compliance checks) | | **AntiAI** | 32 | ✅ v2.2.3 | AI lockdown (15 features, 32 compliance checks) |
| **EdgeHardening** | 24 | ✅ v2.2.2 | Microsoft Edge browser security (24 policies) | | **EdgeHardening** | 24 | ✅ v2.2.3 | Microsoft Edge browser security (24 policies) |
| **AdvancedSecurity** | 50 | ✅ v2.2.2 | Advanced hardening beyond MS Baseline (incl. Wireless Display, Discovery Protocols, IPv6) | | **AdvancedSecurity** | 50 | ✅ v2.2.3 | Advanced hardening beyond MS Baseline (incl. Wireless Display, Discovery Protocols, IPv6) |
| **TOTAL** | **633** | ✅ **100%** | **Complete Framework (Paranoid mode)** | | **TOTAL** | **633** | ✅ **100%** | **Complete Framework (Paranoid mode)** |
--- ---
@ -238,7 +238,7 @@ Clipchamp.Clipchamp, SpotifyAB.SpotifyMusic
## 🤖 Module 5: AntiAI (32 Policies) ## 🤖 Module 5: AntiAI (32 Policies)
**Description:** Disable 15 Windows AI features via 32 registry policies (v2.2.2) **Description:** Disable 15 Windows AI features via 32 registry policies (v2.2.3)
### 15 AI Features Disabled: ### 15 AI Features Disabled:
@ -283,7 +283,7 @@ HKCU:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\DisableRecallDataProviders =
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetDenyAppListForRecall = [...] HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetDenyAppListForRecall = [...]
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetDenyUriListForRecall = [...] HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetDenyUriListForRecall = [...]
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageDurationForRecallSnapshots = 30 HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageDurationForRecallSnapshots = 30
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageSpaceForRecallSnapshots = 10 HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageSpaceForRecallSnapshots = 10240
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\TurnOffWindowsCopilot = 1 HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\TurnOffWindowsCopilot = 1
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot\TurnOffWindowsCopilot = 1 HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot\TurnOffWindowsCopilot = 1
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot\ShowCopilotButton = 0 HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot\ShowCopilotButton = 0
@ -724,7 +724,7 @@ Some UI elements in Paint and Photos apps may **still be visible** but non-funct
``` ```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NoID Privacy v2.2.2 NoID Privacy v2.2.3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Total Settings: 633 ✅ Total Settings: 633 ✅
@ -745,4 +745,4 @@ Framework Completion: 🎉 100% COMPLETE
--- ---
**Last Updated:** December 22, 2025 **Last Updated:** December 22, 2025
**Framework Version:** v2.2.2 **Framework Version:** v2.2.3

View file

@ -1,31 +1,31 @@
@{ @{
RootModule = 'ASR.psm1' RootModule = 'ASR.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'b2c3d4e5-f6a7-8901-bcde-f23456789012' GUID = 'b2c3d4e5-f6a7-8901-bcde-f23456789012'
Author = 'NexusOne23' Author = 'NexusOne23'
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'
Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.' Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.'
Description = 'Attack Surface Reduction (ASR) - All 19 Microsoft Defender ASR rules in Block mode for maximum protection against modern threats' Description = 'Attack Surface Reduction (ASR) - All 19 Microsoft Defender ASR rules in Block mode for maximum protection against modern threats'
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
RequiredModules = @() RequiredModules = @()
FunctionsToExport = @( FunctionsToExport = @(
'Invoke-ASRRules' 'Invoke-ASRRules'
) )
CmdletsToExport = @() CmdletsToExport = @()
VariablesToExport = @() VariablesToExport = @()
AliasesToExport = @() AliasesToExport = @()
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Tags = @('Security', 'ASR', 'AttackSurfaceReduction', 'Defender', 'Windows11', 'Ransomware') Tags = @('Security', 'ASR', 'AttackSurfaceReduction', 'Defender', 'Windows11', 'Ransomware')
LicenseUri = '' LicenseUri = ''
ProjectUri = '' ProjectUri = ''
ReleaseNotes = @" ReleaseNotes = @"
v2.2.2 - Production Release v2.2.3 - Production Release
- All 19 ASR rules implementation - All 19 ASR rules implementation
- Hybrid approach: Registry backup + Set-MpPreference application - Hybrid approach: Registry backup + Set-MpPreference application
- SCCM/Configuration Manager detection - SCCM/Configuration Manager detection

View file

@ -11,7 +11,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges, Windows Defender Requires: PowerShell 5.1+, Administrator privileges, Windows Defender
#> #>

View file

@ -2,7 +2,7 @@
# Module manifest for AdvancedSecurity # Module manifest for AdvancedSecurity
# Version # Version
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
# Unique ID # Unique ID
GUID = 'e7f5a3d2-8c9b-4f1e-a6d3-9b2c8f4e5a1d' GUID = 'e7f5a3d2-8c9b-4f1e-a6d3-9b2c8f4e5a1d'
@ -48,7 +48,7 @@
LicenseUri = '' LicenseUri = ''
ProjectUri = '' ProjectUri = ''
ReleaseNotes = @' ReleaseNotes = @'
v2.2.2 (2025-12-08) v2.2.3 (2025-12-08)
- Production release of AdvancedSecurity module - Production release of AdvancedSecurity module
- 49 advanced hardening settings implemented (was 36) - 49 advanced hardening settings implemented (was 36)
- NEW: Wireless Display (Miracast) security hardening - NEW: Wireless Display (Miracast) security hardening

View file

@ -1,5 +1,5 @@
# AdvancedSecurity Module Loader # AdvancedSecurity Module Loader
# Version: 2.2.2 # Version: 2.2.3
# Description: Advanced Security Hardening - Beyond Microsoft Security Baseline # Description: Advanced Security Hardening - Beyond Microsoft Security Baseline
# Get module path # Get module path

View file

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "Administrative Shares Configuration", "title": "Administrative Shares Configuration",
"description": "Configuration for disabling administrative shares (C$, ADMIN$, etc.) to prevent lateral movement", "description": "Configuration for disabling administrative shares (C$, ADMIN$, etc.) to prevent lateral movement",
"version": "2.2.2", "version": "2.2.3",
"Administrative_Shares": { "Administrative_Shares": {
"description": "Disable automatic creation and remove existing administrative shares", "description": "Disable automatic creation and remove existing administrative shares",

View file

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "Credential Protection Configuration", "title": "Credential Protection Configuration",
"description": "Configuration for credential hardening including WDigest protection", "description": "Configuration for credential hardening including WDigest protection",
"version": "2.2.2", "version": "2.2.3",
"WDigest_Protection": { "WDigest_Protection": {
"description": "Prevent WDigest from storing plaintext passwords in LSASS memory", "description": "Prevent WDigest from storing plaintext passwords in LSASS memory",

View file

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#", "$schema": "http://json-schema.org/draft-07/schema#",
"title": "RDP Hardening Configuration", "title": "RDP Hardening Configuration",
"description": "Configuration for RDP (Remote Desktop Protocol) hardening including NLA enforcement and optional complete disable", "description": "Configuration for RDP (Remote Desktop Protocol) hardening including NLA enforcement and optional complete disable",
"version": "2.2.2", "version": "2.2.3",
"NLA_Enforcement": { "NLA_Enforcement": {
"description": "Network Level Authentication (NLA) enforcement settings", "description": "Network Level Authentication (NLA) enforcement settings",

View file

@ -21,7 +21,7 @@ function Block-FingerProtocol {
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Administrator privileges Requires: Administrator privileges
REFERENCES: REFERENCES:

View file

@ -27,7 +27,7 @@ function Set-SRPRules {
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Administrator privileges Requires: Administrator privileges
REFERENCES: REFERENCES:

View file

@ -22,7 +22,7 @@ function Set-WindowsUpdate {
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Administrator privileges Requires: Administrator privileges
Based on: Windows Settings > Windows Update > Advanced options Based on: Windows Settings > Windows Update > Advanced options
#> #>

View file

@ -11,7 +11,7 @@ function Invoke-AdvancedSecurity {
- Enterprise: Conservative approach with domain-safety checks - Enterprise: Conservative approach with domain-safety checks
- Maximum: Maximum hardening for air-gapped/high-security environments - Maximum: Maximum hardening for air-gapped/high-security environments
Features implemented (v2.2.2): Features implemented (v2.2.3):
- RDP NLA enforcement + optional complete disable - RDP NLA enforcement + optional complete disable
- WDigest credential protection - WDigest credential protection
- Administrative shares disable (domain-aware) - Administrative shares disable (domain-aware)

View file

@ -1,21 +1,21 @@
@{ @{
RootModule = 'AntiAI.psm1' RootModule = 'AntiAI.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'f8e9d7c6-5b4a-3c2d-1e0f-9a8b7c6d5e4f' GUID = 'f8e9d7c6-5b4a-3c2d-1e0f-9a8b7c6d5e4f'
Author = 'NexusOne23' Author = 'NexusOne23'
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'
Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.' Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.'
Description = 'Comprehensive Windows 11 AI deactivation - Disables all 15 AI features using official Microsoft policies (Recall, Copilot, Paint AI, Notepad AI, Click to Do, Settings Agent, etc.). Maximum compliance mode with enterprise-grade Recall protection.' Description = 'Comprehensive Windows 11 AI deactivation - Disables all 15 AI features using official Microsoft policies (Recall, Copilot, Paint AI, Notepad AI, Click to Do, Settings Agent, etc.). Maximum compliance mode with enterprise-grade Recall protection.'
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
FunctionsToExport = @( FunctionsToExport = @(
'Invoke-AntiAI' 'Invoke-AntiAI'
) )
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Tags = @('Windows11', 'AI', 'Privacy', 'Security', 'Recall', 'Copilot', 'AntiAI') Tags = @('Windows11', 'AI', 'Privacy', 'Security', 'Recall', 'Copilot', 'AntiAI')
ProjectUri = 'https://github.com/yourusername/NoIDPrivacy' ProjectUri = 'https://github.com/yourusername/NoIDPrivacy'
ReleaseNotes = @' ReleaseNotes = @'
v1.0.0 - Initial Release v1.0.0 - Initial Release
- Disables 8+ Windows 11 AI features using official Microsoft policies - Disables 8+ Windows 11 AI features using official Microsoft policies

View file

@ -11,7 +11,7 @@
.NOTES .NOTES
Module: AntiAI Module: AntiAI
Version: 2.2.2 Version: 2.2.3
Author: NoID Privacy Author: NoID Privacy
#> #>
@ -22,14 +22,12 @@ $script:ModuleRoot = $PSScriptRoot
# Import private functions # Import private functions
$privateFunctions = @( $privateFunctions = @(
'Backup-AntiAISettings'
'Restore-AntiAISettings'
'Test-AntiAICompliance' 'Test-AntiAICompliance'
'Set-SystemAIModels' 'Set-SystemAIModels'
'Disable-Recall' 'Disable-Recall'
'Set-RecallProtection' 'Set-RecallProtection'
'Disable-Copilot' 'Disable-Copilot'
'Disable-CopilotAdvanced' # NEW v2.2.2: URI handlers, Edge sidebar, Recall export 'Disable-CopilotAdvanced' # NEW v2.2.3: URI handlers, Edge sidebar, Recall export
'Disable-ClickToDo' 'Disable-ClickToDo'
'Disable-SettingsAgent' 'Disable-SettingsAgent'
'Disable-ExplorerAI' # NEW: File Explorer AI Actions menu 'Disable-ExplorerAI' # NEW: File Explorer AI Actions menu

View file

@ -100,8 +100,8 @@
}, },
"SetMaximumStorageSpaceForRecallSnapshots": { "SetMaximumStorageSpaceForRecallSnapshots": {
"Type": "DWord", "Type": "DWord",
"Value": 10, "Value": 10240,
"Description": "Maximum snapshot storage: 10 GB (Choices: 10/25/50/75/100/150 GB, 0=OS default)" "Description": "Maximum snapshot storage: 10 GB = 10240 MB (Choices: 10240/25600/51200/76800/102400/153600 MB, 0=OS default)"
} }
} }
} }

View file

@ -40,7 +40,7 @@
.NOTES .NOTES
Requires Administrator privileges. Requires Administrator privileges.
Part of NoID Privacy AntiAI Module v2.2.2 Part of NoID Privacy AntiAI Module v2.2.3
#> #>
function Disable-CopilotAdvanced { function Disable-CopilotAdvanced {
[CmdletBinding()] [CmdletBinding()]

View file

@ -95,14 +95,14 @@ function Set-RecallProtection {
Write-Log -Level DEBUG -Message "Set max snapshot retention: 30 days" -Module "AntiAI" Write-Log -Level DEBUG -Message "Set max snapshot retention: 30 days" -Module "AntiAI"
$result.Applied++ $result.Applied++
# 4. Storage Space Limit - Max 10 GB # 4. Storage Space Limit - Max 10 GB (10240 MB per MS CSP)
$existing = Get-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -ErrorAction SilentlyContinue $existing = Get-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -ErrorAction SilentlyContinue
if ($null -ne $existing) { if ($null -ne $existing) {
Set-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10 -Force Set-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10240 -Force
} else { } else {
New-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10 -PropertyType DWord -Force | Out-Null New-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10240 -PropertyType DWord -Force | Out-Null
} }
Write-Log -Level DEBUG -Message "Set max snapshot storage: 10 GB" -Module "AntiAI" Write-Log -Level DEBUG -Message "Set max snapshot storage: 10 GB (10240 MB)" -Module "AntiAI"
$result.Applied++ $result.Applied++
# Verify # Verify
@ -111,7 +111,7 @@ function Set-RecallProtection {
$verified = ($null -ne $values.SetDenyAppListForRecall) -and $verified = ($null -ne $values.SetDenyAppListForRecall) -and
($null -ne $values.SetDenyUriListForRecall) -and ($null -ne $values.SetDenyUriListForRecall) -and
($values.SetMaximumStorageDurationForRecallSnapshots -eq 30) -and ($values.SetMaximumStorageDurationForRecallSnapshots -eq 30) -and
($values.SetMaximumStorageSpaceForRecallSnapshots -eq 10) ($values.SetMaximumStorageSpaceForRecallSnapshots -eq 10240)
if ($verified) { if ($verified) {
Write-Log -Level DEBUG -Message "Verification SUCCESS: All Recall protection policies applied" -Module "AntiAI" Write-Log -Level DEBUG -Message "Verification SUCCESS: All Recall protection policies applied" -Module "AntiAI"

View file

@ -42,7 +42,7 @@
.NOTES .NOTES
Author: NoID Privacy Author: NoID Privacy
Version: 2.2.2 (Extended validation) Version: 2.2.3 (Extended validation)
Requires: Windows 11 24H2+, Administrator privileges Requires: Windows 11 24H2+, Administrator privileges
#> #>
@ -235,7 +235,7 @@ $protectionChecks = @(
(Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetDenyAppListForRecall" -ExpectedValue $expectedDenyApps -Description "App Deny List"), (Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetDenyAppListForRecall" -ExpectedValue $expectedDenyApps -Description "App Deny List"),
(Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetDenyUriListForRecall" -ExpectedValue $expectedDenyUris -Description "URI Deny List"), (Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetDenyUriListForRecall" -ExpectedValue $expectedDenyUris -Description "URI Deny List"),
(Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetMaximumStorageDurationForRecallSnapshots" -ExpectedValue 30 -Description "Max Retention: 30 days"), (Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetMaximumStorageDurationForRecallSnapshots" -ExpectedValue 30 -Description "Max Retention: 30 days"),
(Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetMaximumStorageSpaceForRecallSnapshots" -ExpectedValue 10 -Description "Max Storage: 10 GB") (Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetMaximumStorageSpaceForRecallSnapshots" -ExpectedValue 10240 -Description "Max Storage: 10 GB (10240 MB)")
) )
foreach ($check in $protectionChecks) { foreach ($check in $protectionChecks) {
$results.Details += $check $results.Details += $check

View file

@ -52,7 +52,7 @@
.NOTES .NOTES
Author: NoID Privacy Author: NoID Privacy
Version: 2.2.2 Version: 2.2.3
Requires: Windows 11 24H2 or later, Administrator privileges Requires: Windows 11 24H2 or later, Administrator privileges
Impact: All AI features completely disabled, reboot required Impact: All AI features completely disabled, reboot required
#> #>
@ -70,7 +70,7 @@ function Invoke-AntiAI {
Write-Host "" -ForegroundColor Cyan Write-Host "" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host " ANTI-AI MODULE v2.2.2" -ForegroundColor Cyan Write-Host " ANTI-AI MODULE v2.2.3" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host "" Write-Host ""
Write-Host "Disables 15 AI features (32 policies):" -ForegroundColor White Write-Host "Disables 15 AI features (32 policies):" -ForegroundColor White
@ -171,7 +171,7 @@ function Invoke-AntiAI {
@{ Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Paint"; Name = "DisableImageCreator"; Type = "DWord" }, @{ Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Paint"; Name = "DisableImageCreator"; Type = "DWord" },
@{ Path = "HKLM:\SOFTWARE\Policies\WindowsNotepad"; Name = "DisableAIFeatures"; Type = "DWord" }, @{ Path = "HKLM:\SOFTWARE\Policies\WindowsNotepad"; Name = "DisableAIFeatures"; Type = "DWord" },
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI"; Name = "DisableSettingsAgent"; Type = "DWord" }, @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI"; Name = "DisableSettingsAgent"; Type = "DWord" },
# NEW v2.2.2: Advanced Copilot Blocking # NEW v2.2.3: Advanced Copilot Blocking
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI"; Name = "AllowRecallExport"; Type = "DWord" }, @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI"; Name = "AllowRecallExport"; Type = "DWord" },
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"; Name = "EdgeSidebarEnabled"; Type = "DWord" }, @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"; Name = "EdgeSidebarEnabled"; Type = "DWord" },
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"; Name = "ShowHubsSidebar"; Type = "DWord" }, @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Edge"; Name = "ShowHubsSidebar"; Type = "DWord" },
@ -196,7 +196,7 @@ function Invoke-AntiAI {
$prop = Get-ItemProperty -Path $t.Path -Name $t.Name -ErrorAction SilentlyContinue $prop = Get-ItemProperty -Path $t.Path -Name $t.Name -ErrorAction SilentlyContinue
if ($null -ne $prop -and $prop.PSObject.Properties.Name -contains $t.Name) { if ($null -ne $prop -and $prop.PSObject.Properties.Name -contains $t.Name) {
$entry.Exists = $true $entry.Exists = $true
$entry.Value = $prop.$($t.Name) $entry.Value = $prop.$($t.Name)
} }
} }
} }
@ -272,7 +272,8 @@ function Invoke-AntiAI {
Register-Backup -Type "AntiAI" -Data $expJson -Name "Explorer_Advanced_Device_JSON" | Out-Null Register-Backup -Type "AntiAI" -Data $expJson -Name "Explorer_Advanced_Device_JSON" | Out-Null
} }
} }
} catch { }
catch {
Write-Host " WARNING: Failed to create JSON backup for Explorer Advanced: $_" -ForegroundColor Yellow Write-Host " WARNING: Failed to create JSON backup for Explorer Advanced: $_" -ForegroundColor Yellow
} }
} }
@ -355,7 +356,7 @@ function Invoke-AntiAI {
} }
# ============================================================================ # ============================================================================
# ADVANCED COPILOT BLOCKING (NEW v2.2.2) # ADVANCED COPILOT BLOCKING (NEW v2.2.3)
# ============================================================================ # ============================================================================
Write-Host "" Write-Host ""
Write-Host " [Advanced Copilot Blocks]" -ForegroundColor Cyan Write-Host " [Advanced Copilot Blocks]" -ForegroundColor Cyan

View file

@ -2,7 +2,7 @@
# Module manifest for DNS module # Module manifest for DNS module
RootModule = 'DNS.psm1' RootModule = 'DNS.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'a8f7b3c9-4e5d-4a2b-9c1d-8f3e5a7b9c2d' GUID = 'a8f7b3c9-4e5d-4a2b-9c1d-8f3e5a7b9c2d'
Author = 'NexusOne23' Author = 'NexusOne23'
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'

View file

@ -12,7 +12,7 @@
.NOTES .NOTES
Author: NoID Privacy Author: NoID Privacy
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges Requires: PowerShell 5.1+, Administrator privileges
#> #>

View file

@ -1,30 +1,30 @@
@{ @{
# Script module or binary module file associated with this manifest # Script module or binary module file associated with this manifest
RootModule = 'EdgeHardening.psm1' RootModule = 'EdgeHardening.psm1'
# Version number of this module # Version number of this module
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
# ID used to uniquely identify this module # ID used to uniquely identify this module
GUID = '8e3f4c2a-9b1d-4e7a-a2c5-6f8b3d9e1a4c' GUID = '8e3f4c2a-9b1d-4e7a-a2c5-6f8b3d9e1a4c'
# Author of this module # Author of this module
Author = 'NexusOne23' Author = 'NexusOne23'
# Company or vendor of this module # Company or vendor of this module
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'
# Copyright statement for this module # Copyright statement for this module
Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.' Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.'
# Description of the functionality provided by this module # Description of the functionality provided by this module
Description = 'Microsoft Edge Security Hardening based on MS Edge v139 Security Baseline. Applies 24 security policies to harden Microsoft Edge browser using native PowerShell (no LGPO.exe dependency). Includes SmartScreen enforcement, site isolation, SSL/TLS hardening, extension blocking, and IE mode restrictions.' Description = 'Microsoft Edge Security Hardening based on MS Edge v139 Security Baseline. Applies 24 security policies to harden Microsoft Edge browser using native PowerShell (no LGPO.exe dependency). Includes SmartScreen enforcement, site isolation, SSL/TLS hardening, extension blocking, and IE mode restrictions.'
# Minimum version of the PowerShell engine required by this module # Minimum version of the PowerShell engine required by this module
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
# Modules that must be imported into the global environment prior to importing this module # Modules that must be imported into the global environment prior to importing this module
RequiredModules = @() RequiredModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = @( FunctionsToExport = @(
@ -33,22 +33,22 @@
) )
# Cmdlets to export from this module # Cmdlets to export from this module
CmdletsToExport = @() CmdletsToExport = @()
# Variables to export from this module # Variables to export from this module
VariablesToExport = @() VariablesToExport = @()
# Aliases to export from this module # Aliases to export from this module
AliasesToExport = @() AliasesToExport = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess # Private data to pass to the module specified in RootModule/ModuleToProcess
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Tags = @('Security', 'Edge', 'Browser', 'Hardening', 'Baseline', 'Windows11', 'Privacy') Tags = @('Security', 'Edge', 'Browser', 'Hardening', 'Baseline', 'Windows11', 'Privacy')
LicenseUri = '' LicenseUri = ''
ProjectUri = '' ProjectUri = ''
ReleaseNotes = @" ReleaseNotes = @"
v2.2.2 - Production Release v2.2.3 - Production Release
- Microsoft Edge v139 Security Baseline implementation - Microsoft Edge v139 Security Baseline implementation
- 20 security policies (native PowerShell, no LGPO.exe) - 20 security policies (native PowerShell, no LGPO.exe)
- SmartScreen enforcement with override prevention - SmartScreen enforcement with override prevention

View file

@ -16,7 +16,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges Requires: PowerShell 5.1+, Administrator privileges
#> #>

View file

@ -48,7 +48,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges Requires: PowerShell 5.1+, Administrator privileges
IMPORTANT: This applies Microsoft's recommended security baseline. IMPORTANT: This applies Microsoft's recommended security baseline.

View file

@ -23,7 +23,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Can be run without Administrator privileges Can be run without Administrator privileges
#> #>
@ -103,8 +103,8 @@ function Test-EdgeHardening {
return [PSCustomObject]@{ return [PSCustomObject]@{
Compliant = $false Compliant = $false
Message = "Test failed: $($_.Exception.Message)" Message = "Test failed: $($_.Exception.Message)"
Details = @() Details = @()
} }
} }
} }

View file

@ -1,11 +1,11 @@
@{ @{
RootModule = 'Privacy.psm1' RootModule = 'Privacy.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'a9f7c8d3-2e5b-4a1f-9c3d-7e8f5a6b2c4d' GUID = 'a9f7c8d3-2e5b-4a1f-9c3d-7e8f5a6b2c4d'
Author = 'NexusOne23' Author = 'NexusOne23'
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'
Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.' Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.'
Description = 'Privacy & Telemetry hardening module with Bloatware removal and OneDrive configuration. Supports 3 modes: MSRecommended (default), Strict (maximum privacy, apps still work), and Paranoid (hardcore).' Description = 'Privacy & Telemetry hardening module with Bloatware removal and OneDrive configuration. Supports 3 modes: MSRecommended (default), Strict (maximum privacy, apps still work), and Paranoid (hardcore).'
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
@ -15,15 +15,15 @@
'Test-PrivacyCompliance' 'Test-PrivacyCompliance'
) )
CmdletsToExport = @() CmdletsToExport = @()
VariablesToExport = @() VariablesToExport = @()
AliasesToExport = @() AliasesToExport = @()
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Tags = @('Privacy', 'Telemetry', 'Bloatware', 'OneDrive', 'Windows11', 'Security') Tags = @('Privacy', 'Telemetry', 'Bloatware', 'OneDrive', 'Windows11', 'Security')
LicenseUri = 'https://github.com/yourusername/NoIDPrivacyPro/blob/main/LICENSE' LicenseUri = 'https://github.com/yourusername/NoIDPrivacyPro/blob/main/LICENSE'
ProjectUri = 'https://github.com/yourusername/NoIDPrivacyPro' ProjectUri = 'https://github.com/yourusername/NoIDPrivacyPro'
ReleaseNotes = 'Initial release - Privacy module with 3-mode support' ReleaseNotes = 'Initial release - Privacy module with 3-mode support'
} }
} }

View file

@ -16,7 +16,7 @@
.NOTES .NOTES
Module: Privacy Module: Privacy
Version: 2.2.2 Version: 2.2.3
Author: NoID Privacy Author: NoID Privacy
#> #>
@ -26,7 +26,6 @@ $script:ModuleRoot = $PSScriptRoot
# Import private functions # Import private functions
$privateFunctions = @( $privateFunctions = @(
'Backup-PrivacySettings', 'Backup-PrivacySettings',
'Restore-PrivacySettings',
'Set-TelemetrySettings', 'Set-TelemetrySettings',
'Set-PersonalizationSettings', 'Set-PersonalizationSettings',
'Set-AppPrivacySettings', 'Set-AppPrivacySettings',

View file

@ -354,7 +354,7 @@ function Invoke-PrivacyHardening {
$bloatwareListPath = Join-Path $moduleBackupPath "REMOVED_APPS_LIST.txt" $bloatwareListPath = Join-Path $moduleBackupPath "REMOVED_APPS_LIST.txt"
$listContent = @() $listContent = @()
$listContent += "================================================================" $listContent += "================================================================"
$listContent += " REMOVED APPS - NoID Privacy v2.2.2" $listContent += " REMOVED APPS - NoID Privacy v2.2.3"
$listContent += " Session: $(Split-Path $moduleBackupPath -Leaf)" $listContent += " Session: $(Split-Path $moduleBackupPath -Leaf)"
$listContent += " Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" $listContent += " Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$listContent += "================================================================" $listContent += "================================================================"

View file

@ -44,7 +44,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 - Self-Contained Edition Version: 2.2.3 - Self-Contained Edition
Requires: PowerShell 5.1+, Administrator privileges Requires: PowerShell 5.1+, Administrator privileges
BREAKING CHANGE from v1.0: BREAKING CHANGE from v1.0:

View file

@ -1,32 +1,32 @@
@{ @{
RootModule = 'SecurityBaseline.psm1' RootModule = 'SecurityBaseline.psm1'
ModuleVersion = '2.2.2' ModuleVersion = '2.2.3'
GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
Author = 'NexusOne23' Author = 'NexusOne23'
CompanyName = 'Open Source Project' CompanyName = 'Open Source Project'
Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.' Copyright = '(c) 2025 NexusOne23. Licensed under GPL-3.0.'
Description = 'Microsoft Security Baseline for Windows 11 25H2 - 425 hardening settings implementing enterprise-grade security standards. Self-contained, no LGPO.exe required. (437 entries parsed, 12 are INF metadata)' Description = 'Microsoft Security Baseline for Windows 11 25H2 - 425 hardening settings implementing enterprise-grade security standards. Self-contained, no LGPO.exe required. (437 entries parsed, 12 are INF metadata)'
PowerShellVersion = '5.1' PowerShellVersion = '5.1'
RequiredModules = @() RequiredModules = @()
FunctionsToExport = @( FunctionsToExport = @(
'Invoke-SecurityBaseline', 'Invoke-SecurityBaseline',
'Restore-SecurityBaseline' 'Restore-SecurityBaseline'
) )
CmdletsToExport = @() CmdletsToExport = @()
VariablesToExport = @() VariablesToExport = @()
AliasesToExport = @() AliasesToExport = @()
PrivateData = @{ PrivateData = @{
PSData = @{ PSData = @{
Tags = @('Security', 'Hardening', 'Windows11', 'Baseline', 'Microsoft', 'Enterprise') Tags = @('Security', 'Hardening', 'Windows11', 'Baseline', 'Microsoft', 'Enterprise')
LicenseUri = '' LicenseUri = ''
ProjectUri = '' ProjectUri = ''
ReleaseNotes = @" ReleaseNotes = @"
v2.2.2 - Self-Contained Edition v2.2.3 - Self-Contained Edition
- NO LGPO.exe REQUIRED! Fully self-contained implementation - NO LGPO.exe REQUIRED! Fully self-contained implementation
- 425 Microsoft Security Baseline settings for Windows 11 25H2 - 425 Microsoft Security Baseline settings for Windows 11 25H2
- 335 Registry policies (Computer + User) - 335 Registry policies (Computer + User)

View file

@ -13,7 +13,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges Requires: PowerShell 5.1+, Administrator privileges
#> #>

View file

@ -19,7 +19,7 @@
resulting from its use. USE AT YOUR OWN RISK. resulting from its use. USE AT YOUR OWN RISK.
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator Requires: PowerShell 5.1+, Administrator
For CLI mode use: NoIDPrivacy.ps1 -Module <name> For CLI mode use: NoIDPrivacy.ps1 -Module <name>
#> #>
@ -30,7 +30,7 @@
# No parameters - interactive mode only # No parameters - interactive mode only
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
$Host.UI.RawUI.WindowTitle = "NoID Privacy v2.2.2" $Host.UI.RawUI.WindowTitle = "NoID Privacy v2.2.3"
# Set script root path (required by modules to load configs) # Set script root path (required by modules to load configs)
$script:RootPath = $PSScriptRoot $script:RootPath = $PSScriptRoot
@ -75,11 +75,11 @@ function Write-Step {
$symbol = switch ($Status) { $symbol = switch ($Status) {
"SUCCESS" { "[+]"; $color = "Green" } "SUCCESS" { "[+]"; $color = "Green" }
"ERROR" { "[-]"; $color = "Red" } "ERROR" { "[-]"; $color = "Red" }
"WARNING" { "[!]"; $color = "Yellow" } "WARNING" { "[!]"; $color = "Yellow" }
"INFO" { "[>]"; $color = "Cyan" } "INFO" { "[>]"; $color = "Cyan" }
"WAIT" { "[.]"; $color = "Gray" } "WAIT" { "[.]"; $color = "Gray" }
default { "[ ]"; $color = "White" } default { "[ ]"; $color = "White" }
} }
Write-ColorText $symbol -Color $color -NoNewline Write-ColorText $symbol -Color $color -NoNewline
@ -90,7 +90,7 @@ function Write-Banner {
Clear-Host Clear-Host
Write-Host "" Write-Host ""
Write-Host " ========================================" -ForegroundColor Cyan Write-Host " ========================================" -ForegroundColor Cyan
Write-Host " NoID Privacy v2.2.2 " -ForegroundColor Cyan Write-Host " NoID Privacy v2.2.3 " -ForegroundColor Cyan
Write-Host " ========================================" -ForegroundColor Cyan Write-Host " ========================================" -ForegroundColor Cyan
Write-Host "" Write-Host ""
Write-Host " Professional Windows 11 Security & Privacy Hardening Framework" -ForegroundColor Gray Write-Host " Professional Windows 11 Security & Privacy Hardening Framework" -ForegroundColor Gray
@ -105,7 +105,7 @@ function Write-Banner {
$osBuild = if ($os) { $os.BuildNumber } else { $null } $osBuild = if ($os) { $os.BuildNumber } else { $null }
$psVersion = $PSVersionTable.PSVersion.ToString() $psVersion = $PSVersionTable.PSVersion.ToString()
$envLine = " Version 2.2.2" $envLine = " Version 2.2.3"
if ($osBuild) { if ($osBuild) {
$envLine += " | Windows Build $osBuild" $envLine += " | Windows Build $osBuild"
} }
@ -356,7 +356,8 @@ function Show-BackupList {
# Force result to array to handle single-session case correctly # Force result to array to handle single-session case correctly
if (Test-Path $backupPath) { if (Test-Path $backupPath) {
$sessions = @(Get-BackupSessions -BackupDirectory $backupPath) $sessions = @(Get-BackupSessions -BackupDirectory $backupPath)
} else { }
else {
$sessions = @() $sessions = @()
} }
} }
@ -382,8 +383,8 @@ function Show-BackupList {
try { try {
$age = (Get-Date) - $session.Timestamp $age = (Get-Date) - $session.Timestamp
$ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" } $ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" }
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" } elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
else { "$([math]::Round($age.TotalDays)) days ago" } else { "$([math]::Round($age.TotalDays)) days ago" }
} }
catch { catch {
$ageStr = "unknown age" $ageStr = "unknown age"
@ -795,7 +796,7 @@ function Invoke-RestoreWorkflow {
if ([string]::IsNullOrWhiteSpace($modeInput)) { $modeInput = "A" } if ([string]::IsNullOrWhiteSpace($modeInput)) { $modeInput = "A" }
$modeInput = $modeInput.Trim().ToUpper() $modeInput = $modeInput.Trim().ToUpper()
if ($modeInput -in @('A','M')) { if ($modeInput -in @('A', 'M')) {
$restoreMode = $modeInput $restoreMode = $modeInput
break break
} }
@ -818,7 +819,7 @@ function Invoke-RestoreWorkflow {
} }
$indices = @() $indices = @()
foreach ($token in $moduleInput.Split(',', ';', ' ')) { foreach ($token in ($moduleInput -split '[,; ]')) {
if (-not [string]::IsNullOrWhiteSpace($token)) { if (-not [string]::IsNullOrWhiteSpace($token)) {
$parsed = 0 $parsed = 0
if ([int]::TryParse($token.Trim(), [ref]$parsed)) { if ([int]::TryParse($token.Trim(), [ref]$parsed)) {
@ -837,7 +838,7 @@ function Invoke-RestoreWorkflow {
} }
foreach ($i in $indices) { foreach ($i in $indices) {
$selectedModuleNames += $availableModules[$i-1].name $selectedModuleNames += $availableModules[$i - 1].name
} }
} }
} }

View file

@ -50,7 +50,7 @@
resulting from its use. USE AT YOUR OWN RISK. resulting from its use. USE AT YOUR OWN RISK.
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Administrator privileges, Windows 11 Requires: PowerShell 5.1+, Administrator privileges, Windows 11
License: GPL-3.0 (Core CLI). See LICENSE for full terms. License: GPL-3.0 (Core CLI). See LICENSE for full terms.
@ -111,13 +111,13 @@ $global:CurrentModule = ""
# ============================================================================ # ============================================================================
# EXIT CODES - For CI/CD and automation integration # EXIT CODES - For CI/CD and automation integration
# ============================================================================ # ============================================================================
$script:EXIT_SUCCESS = 0 # All operations completed successfully $script:EXIT_SUCCESS = 0 # All operations completed successfully
$script:EXIT_ERROR_GENERAL = 1 # General/unspecified error $script:EXIT_ERROR_GENERAL = 1 # General/unspecified error
$script:EXIT_ERROR_PREREQUISITES = 2 # System requirements not met $script:EXIT_ERROR_PREREQUISITES = 2 # System requirements not met
$script:EXIT_ERROR_CONFIG = 3 # Configuration file error $script:EXIT_ERROR_CONFIG = 3 # Configuration file error
$script:EXIT_ERROR_MODULE = 4 # One or more modules failed $script:EXIT_ERROR_MODULE = 4 # One or more modules failed
$script:EXIT_ERROR_FATAL = 5 # Fatal/unexpected exception $script:EXIT_ERROR_FATAL = 5 # Fatal/unexpected exception
$script:EXIT_SUCCESS_REBOOT = 10 # Success, reboot required $script:EXIT_SUCCESS_REBOOT = 10 # Success, reboot required
# Script root path # Script root path
$script:RootPath = $PSScriptRoot $script:RootPath = $PSScriptRoot
@ -135,7 +135,7 @@ try {
$logDirectory = Join-Path $script:RootPath "Logs" $logDirectory = Join-Path $script:RootPath "Logs"
Initialize-Logger -LogDirectory $logDirectory -MinimumLevel $logLevel Initialize-Logger -LogDirectory $logDirectory -MinimumLevel $logLevel
Write-Log -Level INFO -Message "=== NoID Privacy Framework v2.2.2 ===" -Module "Main" Write-Log -Level INFO -Message "=== NoID Privacy Framework v2.2.3 ===" -Module "Main"
Write-Log -Level INFO -Message "Starting framework initialization..." -Module "Main" Write-Log -Level INFO -Message "Starting framework initialization..." -Module "Main"
# Load other Core modules # Load other Core modules
@ -216,7 +216,7 @@ catch {
# Display banner # Display banner
Write-Host "" Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host " NoID Privacy - v2.2.2" -ForegroundColor Cyan Write-Host " NoID Privacy - v2.2.3" -ForegroundColor Cyan
Write-Host " Windows 11 Security Hardening" -ForegroundColor Cyan Write-Host " Windows 11 Security Hardening" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host "" Write-Host ""
@ -255,23 +255,23 @@ if (-not $Module) {
if ([string]::IsNullOrWhiteSpace($selection)) { $selection = "99" } if ([string]::IsNullOrWhiteSpace($selection)) { $selection = "99" }
$selection = $selection.ToUpper() $selection = $selection.ToUpper()
if ($selection -notin @('1','2','3','4','5','6','7','99','V','R','B','I','0')) { if ($selection -notin @('1', '2', '3', '4', '5', '6', '7', '99', 'V', 'R', 'B', 'I', '0')) {
Write-Host "" Write-Host ""
Write-Host "Invalid selection. Please choose from the menu." -ForegroundColor Red Write-Host "Invalid selection. Please choose from the menu." -ForegroundColor Red
Write-Host "" Write-Host ""
} }
} while ($selection -notin @('1','2','3','4','5','6','7','99','V','R','B','I','0')) } while ($selection -notin @('1', '2', '3', '4', '5', '6', '7', '99', 'V', 'R', 'B', 'I', '0'))
switch ($selection) { switch ($selection) {
"1" { $Module = "SecurityBaseline" } "1" { $Module = "SecurityBaseline" }
"2" { $Module = "ASR" } "2" { $Module = "ASR" }
"3" { $Module = "DNS" } "3" { $Module = "DNS" }
"4" { $Module = "Privacy" } "4" { $Module = "Privacy" }
"5" { $Module = "AntiAI" } "5" { $Module = "AntiAI" }
"6" { $Module = "EdgeHardening" } "6" { $Module = "EdgeHardening" }
"7" { $Module = "AdvancedSecurity" } "7" { $Module = "AdvancedSecurity" }
"99" { $Module = "All" } "99" { $Module = "All" }
"V" { "V" {
# Verify all settings # Verify all settings
Write-Host "" Write-Host ""
Write-Host "Running complete verification..." -ForegroundColor Cyan Write-Host "Running complete verification..." -ForegroundColor Cyan
@ -291,7 +291,7 @@ if (-not $Module) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit 0 exit 0
} }
"R" { "R" {
# Restore from backup - Interactive session selection from disk # Restore from backup - Interactive session selection from disk
Write-Host "" Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
@ -365,7 +365,7 @@ if (-not $Module) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit 0 exit 0
} }
"B" { "B" {
# List backups # List backups
Write-Host "" Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
@ -387,8 +387,8 @@ if (-not $Module) {
foreach ($backup in $backups) { foreach ($backup in $backups) {
$age = (Get-Date) - $backup.CreationTime $age = (Get-Date) - $backup.CreationTime
$ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" } $ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" }
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" } elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
else { "$([math]::Round($age.TotalDays)) days ago" } else { "$([math]::Round($age.TotalDays)) days ago" }
Write-Host " - $($backup.Name)" -ForegroundColor Green -NoNewline Write-Host " - $($backup.Name)" -ForegroundColor Green -NoNewline
Write-Host " ($ageStr)" -ForegroundColor Gray Write-Host " ($ageStr)" -ForegroundColor Gray
@ -404,7 +404,7 @@ if (-not $Module) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit 0 exit 0
} }
"I" { "I" {
# System information # System information
Write-Host "" Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
@ -451,7 +451,7 @@ if (-not $Module) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
exit 0 exit 0
} }
"0" { "0" {
Write-Host "Exiting..." -ForegroundColor Yellow Write-Host "Exiting..." -ForegroundColor Yellow
exit 0 exit 0
} }

View file

@ -8,7 +8,7 @@
[![PowerShell](https://img.shields.io/badge/PowerShell-5.1%2B-blue.svg?logo=powershell)](https://github.com/PowerShell/PowerShell) [![PowerShell](https://img.shields.io/badge/PowerShell-5.1%2B-blue.svg?logo=powershell)](https://github.com/PowerShell/PowerShell)
[![Windows 11](https://img.shields.io/badge/Windows%2011-25H2-0078D4.svg?logo=windows11)](https://www.microsoft.com/windows/) [![Windows 11](https://img.shields.io/badge/Windows%2011-25H2-0078D4.svg?logo=windows11)](https://www.microsoft.com/windows/)
[![License](https://img.shields.io/badge/license-GPL--3.0-green.svg?logo=gnu)](LICENSE) [![License](https://img.shields.io/badge/license-GPL--3.0-green.svg?logo=gnu)](LICENSE)
[![Version](https://img.shields.io/badge/version-2.2.2-blue.svg)](CHANGELOG.md) [![Version](https://img.shields.io/badge/version-2.2.3-blue.svg)](CHANGELOG.md)
[![Status](https://img.shields.io/badge/status-production--ready-brightgreen.svg)]() [![Status](https://img.shields.io/badge/status-production--ready-brightgreen.svg)]()
--- ---
@ -391,13 +391,13 @@ cd noid-privacy
| Module | Settings | Description | Status | | Module | Settings | Description | Status |
|--------|----------|-------------|--------| |--------|----------|-------------|--------|
| **SecurityBaseline** | 425 | Microsoft Security Baseline 25H2 | v2.2.2 | | **SecurityBaseline** | 425 | Microsoft Security Baseline 25H2 | v2.2.3 |
| **ASR** | 19 | Attack Surface Reduction Rules | v2.2.2 | | **ASR** | 19 | Attack Surface Reduction Rules | v2.2.3 |
| **DNS** | 5 | Secure DNS with DoH encryption | v2.2.2 | | **DNS** | 5 | Secure DNS with DoH encryption | v2.2.3 |
| **Privacy** | 78 | Telemetry, Bloatware, OneDrive hardening (Strict) | v2.2.2 | | **Privacy** | 78 | Telemetry, Bloatware, OneDrive hardening (Strict) | v2.2.3 |
| **AntiAI** | 32 | AI lockdown (15 features, 32 compliance checks) | v2.2.2 | | **AntiAI** | 32 | AI lockdown (15 features, 32 compliance checks) | v2.2.3 |
| **EdgeHardening** | 24 | Microsoft Edge security (24 policies) | v2.2.2 | | **EdgeHardening** | 24 | Microsoft Edge security (24 policies) | v2.2.3 |
| **AdvancedSecurity** | 50 | Beyond MS Baseline (SRP, Legacy protocols, Wireless Display, Discovery Protocols, IPv6) | v2.2.2 | | **AdvancedSecurity** | 50 | Beyond MS Baseline (SRP, Legacy protocols, Wireless Display, Discovery Protocols, IPv6) | v2.2.3 |
| **TOTAL** | **633** | **Complete Framework (Paranoid mode)** | **Production** | | **TOTAL** | **633** | **Complete Framework (Paranoid mode)** | **Production** |
**Release Highlights:** **Release Highlights:**
@ -769,7 +769,7 @@ Logs/NoIDPrivacy_YYYYMMDD_HHMMSS.log
- **[Features](Docs/FEATURES.md)** - Complete 630+ setting reference - **[Features](Docs/FEATURES.md)** - Complete 630+ setting reference
- **[Changelog](CHANGELOG.md)** - Version history - **[Changelog](CHANGELOG.md)** - Version history
- **[Quick Start](#-quick-start)** - Installation guide (see above) - **[Quick Start](#-quick-start)** - Installation guide (see above)
- **[Troubleshooting](#troubleshooting)** - Common issues (see above) - **[Troubleshooting](#-troubleshooting)** - Common issues (see above)
### 💬 Community ### 💬 Community
@ -787,6 +787,16 @@ Logs/NoIDPrivacy_YYYYMMDD_HHMMSS.log
--- ---
## 🔗 The NoID Privacy Ecosystem
| Platform | Link |
|----------|------|
| 🪟 **Windows** | You're here! |
| 🐧 **Linux** | [NoID Privacy for Linux](https://github.com/NexusOne23/noid-privacy-linux) — 300+ checks, 42 sections, `--ai` flag for AI-powered fixes |
| 📱 **Android** | [NoID Privacy on Google Play](https://play.google.com/store/apps/details?id=com.noid.privacy) — 81 checks, 10 categories, permission audit, Chrome hardening, anti-theft |
---
## 📜 License ## 📜 License
### Dual-License Model ### Dual-License Model
@ -852,10 +862,15 @@ The authors are not responsible for any damage or data loss.
## 📈 Project Status ## 📈 Project Status
**Current Version:** 2.2.2 **Current Version:** 2.2.3
**Last Updated:** December 22, 2025 **Last Updated:** January 7, 2026
**Status:** Production-Ready **Status:** Production-Ready
### Release Highlights v2.2.3
- **Critical Fix:** Restore Mode manual module selection crash
- Fix: `.Split()` wrong .NET overload → `-split` operator
### Release Highlights v2.2.2 ### Release Highlights v2.2.2
- **Performance:** Firewall snapshot 60-120s → 2-5s (batch query fix) - **Performance:** Firewall snapshot 60-120s → 2-5s (batch query fix)
@ -867,15 +882,6 @@ The authors are not responsible for any damage or data loss.
- **Fix:** `.Count` property bug in 5 files (Where-Object single-object results) - **Fix:** `.Count` property bug in 5 files (Where-Object single-object results)
- **Improved:** ASR prompt text ("untrusted" → "new software" - more neutral) - **Improved:** ASR prompt text ("untrusted" → "new software" - more neutral)
### Release Highlights v2.2.0
- 630+ settings (expanded from 580+)
- NonInteractive mode for GUI integration
- Third-party AV detection and graceful ASR skip
- AntiAI enhanced to 32 policies (was 24)
- Pre-Framework ASR snapshot
- Smart Registry Backup with JSON fallback
📋 [See Full Changelog](CHANGELOG.md) 📋 [See Full Changelog](CHANGELOG.md)
--- ---

View file

@ -92,9 +92,15 @@ NoID Privacy implements multiple security layers:
### Before Running ### Before Running
1. ✅ **Verify Script Integrity** 1. ✅ **Verify Script Integrity**
```powershell ```powershell
# Check file hash (coming soon - SHA256 checksums in releases) # Compare against CHECKSUMS.sha256 from GitHub Release
Get-FileHash .\NoIDPrivacy.ps1 -Algorithm SHA256 Get-FileHash .\NoIDPrivacy.ps1 -Algorithm SHA256
# Or verify the entire release folder:
Get-ChildItem *.ps1, *.psm1 | ForEach-Object {
"$((Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()) $($_.Name)"
}
``` ```
Each GitHub release includes a `CHECKSUMS.sha256` file with SHA256 hashes of all release files.
2. ✅ **Review Code** 2. ✅ **Review Code**
- This is open-source - read the code! - This is open-source - read the code!

View file

@ -7,12 +7,12 @@ REM This script launches NoIDPrivacy-Interactive.ps1 with
REM Administrator privileges (auto-elevation). REM Administrator privileges (auto-elevation).
REM REM
REM Author: NexusOne23 REM Author: NexusOne23
REM Version: 2.2.2 REM Version: 2.2.3
REM ======================================== REM ========================================
setlocal setlocal
title NoID Privacy v2.2.2 title NoID Privacy v2.2.3
REM Get the directory where this batch file is located REM Get the directory where this batch file is located
set "SCRIPT_DIR=%~dp0" set "SCRIPT_DIR=%~dp0"
@ -23,7 +23,7 @@ if %errorLevel% == 0 (
REM Already admin, run PowerShell script directly REM Already admin, run PowerShell script directly
echo Running NoID Privacy Interactive Menu with Administrator privileges... echo Running NoID Privacy Interactive Menu with Administrator privileges...
echo. echo.
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1" %* "%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -NoProfile -File "%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1" %*
pause pause
exit /b exit /b
) )
@ -33,7 +33,7 @@ echo Requesting Administrator privileges...
echo. echo.
REM Use PowerShell to elevate and run the script REM Use PowerShell to elevate and run the script
powershell.exe -Command "Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -NoProfile -File \"%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1\" %*' -Verb RunAs" "%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe" -Command "Start-Process '%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe' -ArgumentList '-ExecutionPolicy Bypass -NoProfile -File \"%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1\" %*' -Verb RunAs"
REM Exit this non-elevated instance REM Exit this non-elevated instance
exit /b exit /b

View file

@ -17,7 +17,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+, Pester 5.0+ Requires: PowerShell 5.1+, Pester 5.0+
.EXAMPLE .EXAMPLE

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
.EXAMPLE .EXAMPLE

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: Pester 5.0+ Requires: Pester 5.0+
#> #>

View file

@ -0,0 +1,74 @@
<#
.SYNOPSIS
Generates SHA256 checksums for release files.
.DESCRIPTION
Creates a CHECKSUMS.sha256 file containing SHA256 hashes of all release files.
Used for verifying download integrity.
.PARAMETER ReleasePath
Path to the release folder or ZIP file(s).
.PARAMETER OutputFile
Output file for checksums. Default: CHECKSUMS.sha256 in the same directory.
.EXAMPLE
.\Generate-ReleaseChecksums.ps1 -ReleasePath "C:\Release\NoIDPrivacy-v2.2.3"
.EXAMPLE
.\Generate-ReleaseChecksums.ps1 -ReleasePath ".\NoIDPrivacy-v2.2.3.zip"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ReleasePath,
[Parameter(Mandatory = $false)]
[string]$OutputFile
)
$ErrorActionPreference = 'Stop'
Write-Host "`n=== NoID Privacy Release Checksum Generator ===" -ForegroundColor Cyan
# Determine if path is file or directory
if (Test-Path $ReleasePath -PathType Container) {
$files = Get-ChildItem -Path $ReleasePath -File -Recurse | Where-Object { $_.Extension -in '.zip', '.exe', '.ps1', '.psm1' }
$basePath = $ReleasePath
}
elseif (Test-Path $ReleasePath -PathType Leaf) {
$files = Get-Item $ReleasePath
$basePath = Split-Path $ReleasePath -Parent
}
else {
Write-Error "Path not found: $ReleasePath"
exit 1
}
if (-not $OutputFile) {
$OutputFile = Join-Path $basePath "CHECKSUMS.sha256"
}
Write-Host "Generating checksums for $($files.Count) file(s)..." -ForegroundColor Yellow
$checksums = @()
$checksums += "# NoID Privacy Release Checksums"
$checksums += "# Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss UTC' -AsUTC)"
$checksums += "# Verify with: Get-FileHash -Algorithm SHA256 <file>"
$checksums += ""
foreach ($file in $files) {
Write-Host " Hashing: $($file.Name)" -ForegroundColor Gray
$hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash.ToLower()
$relativePath = $file.Name
$checksums += "$hash $relativePath"
}
$checksums | Out-File -FilePath $OutputFile -Encoding utf8
Write-Host "`nChecksums written to: $OutputFile" -ForegroundColor Green
Write-Host "`nContents:" -ForegroundColor Cyan
Get-Content $OutputFile | ForEach-Object { Write-Host " $_" }
Write-Host "`n=== Done ===" -ForegroundColor Cyan

View file

@ -18,7 +18,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
.EXAMPLE .EXAMPLE
@ -142,21 +142,26 @@ function Read-PolFile {
# Parse based on type # Parse based on type
switch ($type) { switch ($type) {
1 { # REG_SZ (String) 1 {
# REG_SZ (String)
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
} }
2 { # REG_EXPAND_SZ 2 {
# REG_EXPAND_SZ
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
} }
3 { # REG_BINARY 3 {
# REG_BINARY
$data = $dataBytes $data = $dataBytes
} }
4 { # REG_DWORD 4 {
# REG_DWORD
if ($dataBytes.Length -ge 4) { if ($dataBytes.Length -ge 4) {
$data = [BitConverter]::ToInt32($dataBytes, 0) $data = [BitConverter]::ToInt32($dataBytes, 0)
} }
} }
7 { # REG_MULTI_SZ 7 {
# REG_MULTI_SZ
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) -split '\x00' $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) -split '\x00'
} }
default { default {
@ -172,9 +177,9 @@ function Read-PolFile {
# Add entry # Add entry
$entries += [PSCustomObject]@{ $entries += [PSCustomObject]@{
KeyName = $keyName KeyName = $keyName
ValueName = $valueName ValueName = $valueName
Type = switch ($type) { Type = switch ($type) {
1 { "REG_SZ" } 1 { "REG_SZ" }
2 { "REG_EXPAND_SZ" } 2 { "REG_EXPAND_SZ" }
3 { "REG_BINARY" } 3 { "REG_BINARY" }
@ -183,7 +188,7 @@ function Read-PolFile {
11 { "REG_QWORD" } 11 { "REG_QWORD" }
default { "Unknown($type)" } default { "Unknown($type)" }
} }
Data = $data Data = $data
} }
} }
@ -273,9 +278,9 @@ if ($allComputerPolicies.Count -gt 0) {
# Create summary # Create summary
$summary = [PSCustomObject]@{ $summary = [PSCustomObject]@{
TotalEdgePolicies = $allComputerPolicies.Count TotalEdgePolicies = $allComputerPolicies.Count
ParsedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" ParsedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
BaselineVersion = "Edge v139" BaselineVersion = "Edge v139"
RegistryPaths = ($allComputerPolicies | Select-Object -ExpandProperty KeyName -Unique | Sort-Object) RegistryPaths = ($allComputerPolicies | Select-Object -ExpandProperty KeyName -Unique | Sort-Object)
} }
$summaryFile = Join-Path $OutputPath "Summary.json" $summaryFile = Join-Path $OutputPath "Summary.json"

View file

@ -25,7 +25,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
.EXAMPLE .EXAMPLE
@ -150,21 +150,26 @@ function Read-PolFile {
# Parse based on type # Parse based on type
switch ($type) { switch ($type) {
1 { # REG_SZ (String) 1 {
# REG_SZ (String)
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
} }
2 { # REG_EXPAND_SZ 2 {
# REG_EXPAND_SZ
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0)
} }
3 { # REG_BINARY 3 {
# REG_BINARY
$data = $dataBytes $data = $dataBytes
} }
4 { # REG_DWORD 4 {
# REG_DWORD
if ($dataBytes.Length -ge 4) { if ($dataBytes.Length -ge 4) {
$data = [BitConverter]::ToInt32($dataBytes, 0) $data = [BitConverter]::ToInt32($dataBytes, 0)
} }
} }
7 { # REG_MULTI_SZ 7 {
# REG_MULTI_SZ
$data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) -split '\x00' $data = [System.Text.Encoding]::Unicode.GetString($dataBytes).TrimEnd([char]0) -split '\x00'
} }
default { default {
@ -180,9 +185,9 @@ function Read-PolFile {
# Add entry # Add entry
$entries += [PSCustomObject]@{ $entries += [PSCustomObject]@{
KeyName = $keyName KeyName = $keyName
ValueName = $valueName ValueName = $valueName
Type = switch ($type) { Type = switch ($type) {
1 { "REG_SZ" } 1 { "REG_SZ" }
2 { "REG_EXPAND_SZ" } 2 { "REG_EXPAND_SZ" }
3 { "REG_BINARY" } 3 { "REG_BINARY" }
@ -191,7 +196,7 @@ function Read-PolFile {
11 { "REG_QWORD" } 11 { "REG_QWORD" }
default { "Unknown($type)" } default { "Unknown($type)" }
} }
Data = $data Data = $data
} }
} }
@ -296,10 +301,10 @@ function Read-AuditCsv {
# Skip header row # Skip header row
$policies = $csv | Select-Object -Skip 1 | ForEach-Object { $policies = $csv | Select-Object -Skip 1 | ForEach-Object {
[PSCustomObject]@{ [PSCustomObject]@{
Subcategory = $_.'Subcategory' Subcategory = $_.'Subcategory'
SubcategoryGUID = $_.'Subcategory GUID' SubcategoryGUID = $_.'Subcategory GUID'
InclusionSetting = $_.'Inclusion Setting' InclusionSetting = $_.'Inclusion Setting'
SettingValue = $_.'Setting Value' SettingValue = $_.'Setting Value'
} }
} }
@ -346,17 +351,17 @@ $gpoMapping = @{
$gpoPath = Join-Path $BaselinePath "GPOs" $gpoPath = Join-Path $BaselinePath "GPOs"
$allSettings = @{ $allSettings = @{
RegistryPolicies = @{ RegistryPolicies = @{
Computer = @() Computer = @()
User = @() User = @()
} }
SecurityTemplates = @{} SecurityTemplates = @{}
AuditPolicies = @() AuditPolicies = @()
Summary = @{ Summary = @{
TotalRegistrySettings = 0 TotalRegistrySettings = 0
TotalSecuritySettings = 0 TotalSecuritySettings = 0
TotalAuditPolicies = 0 TotalAuditPolicies = 0
TotalSettings = 0 TotalSettings = 0
} }
} }
@ -381,11 +386,11 @@ foreach ($guid in $gpoMapping.Keys) {
foreach ($entry in $entries) { foreach ($entry in $entries) {
$allSettings.RegistryPolicies.Computer += [PSCustomObject]@{ $allSettings.RegistryPolicies.Computer += [PSCustomObject]@{
GPO = $gpoName GPO = $gpoName
KeyName = $entry.KeyName KeyName = $entry.KeyName
ValueName = $entry.ValueName ValueName = $entry.ValueName
Type = $entry.Type Type = $entry.Type
Data = $entry.Data Data = $entry.Data
} }
} }
@ -401,11 +406,11 @@ foreach ($guid in $gpoMapping.Keys) {
foreach ($entry in $entries) { foreach ($entry in $entries) {
$allSettings.RegistryPolicies.User += [PSCustomObject]@{ $allSettings.RegistryPolicies.User += [PSCustomObject]@{
GPO = $gpoName GPO = $gpoName
KeyName = $entry.KeyName KeyName = $entry.KeyName
ValueName = $entry.ValueName ValueName = $entry.ValueName
Type = $entry.Type Type = $entry.Type
Data = $entry.Data Data = $entry.Data
} }
} }
@ -435,11 +440,11 @@ foreach ($guid in $gpoMapping.Keys) {
foreach ($policy in $policies) { foreach ($policy in $policies) {
$allSettings.AuditPolicies += [PSCustomObject]@{ $allSettings.AuditPolicies += [PSCustomObject]@{
GPO = $gpoName GPO = $gpoName
Subcategory = $policy.Subcategory Subcategory = $policy.Subcategory
SubcategoryGUID = $policy.SubcategoryGUID SubcategoryGUID = $policy.SubcategoryGUID
InclusionSetting = $policy.InclusionSetting InclusionSetting = $policy.InclusionSetting
SettingValue = $policy.SettingValue SettingValue = $policy.SettingValue
} }
} }
@ -452,8 +457,8 @@ foreach ($guid in $gpoMapping.Keys) {
# Calculate total # Calculate total
$allSettings.Summary.TotalSettings = $allSettings.Summary.TotalRegistrySettings + $allSettings.Summary.TotalSettings = $allSettings.Summary.TotalRegistrySettings +
$allSettings.Summary.TotalSecuritySettings + $allSettings.Summary.TotalSecuritySettings +
$allSettings.Summary.TotalAuditPolicies $allSettings.Summary.TotalAuditPolicies
# Save outputs # Save outputs
Write-Host "Saving parsed settings..." -ForegroundColor Cyan Write-Host "Saving parsed settings..." -ForegroundColor Cyan

View file

@ -27,7 +27,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
#> #>
#Requires -Version 5.1 #Requires -Version 5.1
@ -130,10 +130,10 @@ function Get-RegistryChecksFromJson {
# Skip metadata and excluded categories # Skip metadata and excluded categories
# NOTE: EnterpriseProtection is NOT skipped - it contains valid registry paths! # NOTE: EnterpriseProtection is NOT skipped - it contains valid registry paths!
if ($propName -in @('Mode', 'Description', 'BestFor', 'Warnings', 'Services', 'ScheduledTasks', if ($propName -in @('Mode', 'Description', 'BestFor', 'Warnings', 'Services', 'ScheduledTasks',
'Summary', 'AutomaticallyBlockedByMasterSwitch', 'ModuleName', 'Version', 'Summary', 'AutomaticallyBlockedByMasterSwitch', 'ModuleName', 'Version',
'TotalFeatures', 'TotalPolicies', 'URIHandlers', 'Note', 'FilePath', 'TotalFeatures', 'TotalPolicies', 'URIHandlers', 'Note', 'FilePath',
'HostsEntries', 'CloudBased', 'RequiresReboot', 'HostsEntries', 'CloudBased', 'RequiresReboot',
'RequiresADMX', 'Impact', 'Name')) { 'RequiresADMX', 'Impact', 'Name')) {
continue continue
} }
@ -962,78 +962,16 @@ try {
$currentASRIds = $mpPreference.AttackSurfaceReductionRules_Ids $currentASRIds = $mpPreference.AttackSurfaceReductionRules_Ids
$currentASRActions = $mpPreference.AttackSurfaceReductionRules_Actions $currentASRActions = $mpPreference.AttackSurfaceReductionRules_Actions
# Load expected ASR rules - JSON is array directly # Load expected ASR rules - JSON is array directly
$asrRules = Get-Content (Join-Path $asrConfigPath "ASR-Rules.json") -Raw | ConvertFrom-Json $asrRules = Get-Content (Join-Path $asrConfigPath "ASR-Rules.json") -Raw | ConvertFrom-Json
$asrFailed = @() $asrFailed = @()
$asrPassed = @() $asrPassed = @()
# Check if ASR rules are configured at all # Check if ASR rules are configured at all
if ($null -eq $currentASRIds -or $currentASRIds.Count -eq 0) { if ($null -eq $currentASRIds -or $currentASRIds.Count -eq 0) {
# No ASR rules configured - mark all as failed # No ASR rules configured - mark all as failed
foreach ($rule in $asrRules) { foreach ($rule in $asrRules) {
$results.Failed++
$expectedActionText = if ($rule.Action -eq 1) { "Block" } elseif ($rule.Action -eq 2) { "Audit" } else { "Disabled" }
$asrFailed += [PSCustomObject]@{
Rule = $rule.Name
GUID = $rule.GUID
Expected = $expectedActionText
Actual = "Not configured"
}
}
}
else {
# Rules where both BLOCK (1) and AUDIT (2) are considered "Pass"
# These are user-configurable rules where either mode is valid
$flexibleRules = @(
"d1e49aac-8f56-4280-b9ba-993a6d77406c", # PSExec/WMI (Management Tools)
"01443614-cd74-433a-b99e-2ecdc07bfc25" # Prevalence (New/Unknown Software)
)
foreach ($rule in $asrRules) {
# Case-insensitive GUID matching (Get-MpPreference may return different case)
$index = -1
for ($i = 0; $i -lt $currentASRIds.Count; $i++) {
if ($currentASRIds[$i] -eq $rule.GUID) {
$index = $i
break
}
}
if ($index -ge 0) {
$actualAction = $currentASRActions[$index]
$expectedAction = $rule.Action
# Check if this is a flexible rule (Block or Audit both count as Pass)
$isFlexibleRule = $flexibleRules -contains $rule.GUID
$isActiveMode = $actualAction -in @(1, 2) # Block or Audit
# For flexible rules: Pass if Block OR Audit
# For other rules: Pass only if exact match
$rulePassed = if ($isFlexibleRule) { $isActiveMode } else { $actualAction -eq $expectedAction }
if ($rulePassed) {
$results.Verified++
$actionText = if ($actualAction -eq 1) { "Block" } elseif ($actualAction -eq 2) { "Audit" } else { "Disabled" }
$asrPassed += [PSCustomObject]@{
Rule = $rule.Name
Expected = $actionText
Actual = $actionText
}
}
else {
$results.Failed++
$expectedActionText = if ($expectedAction -eq 1) { "Block" } elseif ($expectedAction -eq 2) { "Audit" } else { "Disabled" }
$actualActionText = if ($actualAction -eq 1) { "Block" } elseif ($actualAction -eq 2) { "Audit" } else { "Disabled" }
$asrFailed += [PSCustomObject]@{
Rule = $rule.Name
GUID = $rule.GUID
Expected = $expectedActionText
Actual = $actualActionText
}
}
}
else {
$results.Failed++ $results.Failed++
$expectedActionText = if ($rule.Action -eq 1) { "Block" } elseif ($rule.Action -eq 2) { "Audit" } else { "Disabled" } $expectedActionText = if ($rule.Action -eq 1) { "Block" } elseif ($rule.Action -eq 2) { "Audit" } else { "Disabled" }
$asrFailed += [PSCustomObject]@{ $asrFailed += [PSCustomObject]@{
@ -1044,28 +982,90 @@ try {
} }
} }
} }
} else {
# Rules where both BLOCK (1) and AUDIT (2) are considered "Pass"
# These are user-configurable rules where either mode is valid
$flexibleRules = @(
"d1e49aac-8f56-4280-b9ba-993a6d77406c", # PSExec/WMI (Management Tools)
"01443614-cd74-433a-b99e-2ecdc07bfc25" # Prevalence (New/Unknown Software)
)
# Add to AllSettings for HTML report foreach ($rule in $asrRules) {
$asrPassedCount = $results.ASRRules - $asrFailed.Count # Case-insensitive GUID matching (Get-MpPreference may return different case)
$results.AllSettings += [PSCustomObject]@{ $index = -1
Category = "ASR" for ($i = 0; $i -lt $currentASRIds.Count; $i++) {
Total = $results.ASRRules if ($currentASRIds[$i] -eq $rule.GUID) {
Passed = $asrPassedCount $index = $i
Failed = $asrFailed.Count break
PassedDetails = $asrPassed }
FailedDetails = $asrFailed }
}
if ($asrFailed.Count -gt 0) { if ($index -ge 0) {
$results.FailedSettings += [PSCustomObject]@{ $actualAction = $currentASRActions[$index]
Category = "ASR" $expectedAction = $rule.Action
Count = $asrFailed.Count
Details = $asrFailed # Check if this is a flexible rule (Block or Audit both count as Pass)
$isFlexibleRule = $flexibleRules -contains $rule.GUID
$isActiveMode = $actualAction -in @(1, 2) # Block or Audit
# For flexible rules: Pass if Block OR Audit
# For other rules: Pass only if exact match
$rulePassed = if ($isFlexibleRule) { $isActiveMode } else { $actualAction -eq $expectedAction }
if ($rulePassed) {
$results.Verified++
$actionText = if ($actualAction -eq 1) { "Block" } elseif ($actualAction -eq 2) { "Audit" } else { "Disabled" }
$asrPassed += [PSCustomObject]@{
Rule = $rule.Name
Expected = $actionText
Actual = $actionText
}
}
else {
$results.Failed++
$expectedActionText = if ($expectedAction -eq 1) { "Block" } elseif ($expectedAction -eq 2) { "Audit" } else { "Disabled" }
$actualActionText = if ($actualAction -eq 1) { "Block" } elseif ($actualAction -eq 2) { "Audit" } else { "Disabled" }
$asrFailed += [PSCustomObject]@{
Rule = $rule.Name
GUID = $rule.GUID
Expected = $expectedActionText
Actual = $actualActionText
}
}
}
else {
$results.Failed++
$expectedActionText = if ($rule.Action -eq 1) { "Block" } elseif ($rule.Action -eq 2) { "Audit" } else { "Disabled" }
$asrFailed += [PSCustomObject]@{
Rule = $rule.Name
GUID = $rule.GUID
Expected = $expectedActionText
Actual = "Not configured"
}
}
}
} }
}
Write-Host " ASR Rules: $($results.ASRRules - $asrFailed.Count)/$($results.ASRRules) verified" -ForegroundColor $(if ($asrFailed.Count -eq 0) { "Green" } else { "Yellow" }) # Add to AllSettings for HTML report
$asrPassedCount = $results.ASRRules - $asrFailed.Count
$results.AllSettings += [PSCustomObject]@{
Category = "ASR"
Total = $results.ASRRules
Passed = $asrPassedCount
Failed = $asrFailed.Count
PassedDetails = $asrPassed
FailedDetails = $asrFailed
}
if ($asrFailed.Count -gt 0) {
$results.FailedSettings += [PSCustomObject]@{
Category = "ASR"
Count = $asrFailed.Count
Details = $asrFailed
}
}
Write-Host " ASR Rules: $($results.ASRRules - $asrFailed.Count)/$($results.ASRRules) verified" -ForegroundColor $(if ($asrFailed.Count -eq 0) { "Green" } else { "Yellow" })
} # End of else (Defender active) } # End of else (Defender active)
} }
catch { catch {
@ -1303,8 +1303,8 @@ try {
if ($entry.ServerAddresses -and $entry.ServerAddresses.Count -gt 0) { if ($entry.ServerAddresses -and $entry.ServerAddresses.Count -gt 0) {
# Check if it's not DHCP (empty or localhost fallback) # Check if it's not DHCP (empty or localhost fallback)
$isDHCP = ($entry.ServerAddresses.Count -eq 0) -or $isDHCP = ($entry.ServerAddresses.Count -eq 0) -or
($entry.ServerAddresses -contains '127.0.0.1') -or ($entry.ServerAddresses -contains '127.0.0.1') -or
($entry.AddressOrigin -eq 'DHCP') ($entry.AddressOrigin -eq 'DHCP')
if (-not $isDHCP) { if (-not $isDHCP) {
$staticDNS = $true $staticDNS = $true
@ -1796,10 +1796,10 @@ try {
# We validate both Enabled=0 and DisabledByDefault=1 per version/component # We validate both Enabled=0 and DisabledByDefault=1 per version/component
$tlsChecks = @( $tlsChecks = @(
# Enabled flags # Enabled flags
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.0 Server Disabled"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.0 Server Disabled"; Optional = $false }
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.0 Client Disabled"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.0 Client Disabled"; Optional = $false }
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.1 Server Disabled"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.1 Server Disabled"; Optional = $false }
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.1 Client Disabled"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.1 Client Disabled"; Optional = $false }
# DisabledByDefault flags # DisabledByDefault flags
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"; Name = "DisabledByDefault"; Expected = 1; Desc = "TLS 1.0 Server DisabledByDefault"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server"; Name = "DisabledByDefault"; Expected = 1; Desc = "TLS 1.0 Server DisabledByDefault"; Optional = $false }
@{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client"; Name = "DisabledByDefault"; Expected = 1; Desc = "TLS 1.0 Client DisabledByDefault"; Optional = $false } @{ Path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client"; Name = "DisabledByDefault"; Expected = 1; Desc = "TLS 1.0 Client DisabledByDefault"; Optional = $false }
@ -1812,24 +1812,24 @@ try {
# Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/disable-http-proxy-auth-features # Reference: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/disable-http-proxy-auth-features
# NOTE: HKCU AutoDetect is set per-user via HKU in Apply, verified separately below # NOTE: HKCU AutoDetect is set per-user via HKU in Apply, verified separately below
$wpadChecks = @( $wpadChecks = @(
@{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DisableWpad"; Expected = 1; Desc = "WPAD Disabled (Official MS Key)"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp"; Name = "DisableWpad"; Expected = 1; Desc = "WPAD Disabled (Official MS Key)"; Optional = $false }
@{ Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"; Name = "WpadOverride"; Expected = 1; Desc = "WPAD Disabled (WpadOverride)"; Optional = $false } @{ Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Wpad"; Name = "WpadOverride"; Expected = 1; Desc = "WPAD Disabled (WpadOverride)"; Optional = $false }
@{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings"; Name = "AutoDetect"; Expected = 0; Desc = "WPAD AutoDetect (HKLM)"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings"; Name = "AutoDetect"; Expected = 0; Desc = "WPAD AutoDetect (HKLM)"; Optional = $false }
) )
# SRP Root Policy (2 checks) - ALWAYS required for CVE-2025-9491 mitigation # SRP Root Policy (2 checks) - ALWAYS required for CVE-2025-9491 mitigation
$srpRootChecks = @( $srpRootChecks = @(
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers"; Name = "DefaultLevel"; Expected = 262144; Desc = "SRP DefaultLevel (Unrestricted)"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers"; Name = "DefaultLevel"; Expected = 262144; Desc = "SRP DefaultLevel (Unrestricted)"; Optional = $false }
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers"; Name = "TransparentEnabled"; Expected = 1; Desc = "SRP TransparentEnabled"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Safer\CodeIdentifiers"; Name = "TransparentEnabled"; Expected = 1; Desc = "SRP TransparentEnabled"; Optional = $false }
) )
# Firewall Shields Up (1 check) - Maximum profile only, blocks ALL incoming on Public network # Firewall Shields Up (1 check) - Maximum profile only, blocks ALL incoming on Public network
# Optional = true because it's only applied for Maximum profile (user choice) # Optional = true because it's only applied for Maximum profile (user choice)
$shieldsUpCheck = @{ $shieldsUpCheck = @{
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile" Path = "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile"
Name = "DoNotAllowExceptions" Name = "DoNotAllowExceptions"
Expected = 1 Expected = 1
Desc = "Firewall Shields Up (Maximum only)" Desc = "Firewall Shields Up (Maximum only)"
Optional = $true Optional = $true
} }
@ -1837,10 +1837,10 @@ try {
# Optional = true because only applied for Maximum profile (user choice) # Optional = true because only applied for Maximum profile (user choice)
# Check 1: mDNS disabled via registry # Check 1: mDNS disabled via registry
$discoveryMdnsCheck = @{ $discoveryMdnsCheck = @{
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters" Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
Name = "EnableMDNS" Name = "EnableMDNS"
Expected = 0 Expected = 0
Desc = "Discovery Protocols: mDNS Disabled (Maximum only)" Desc = "Discovery Protocols: mDNS Disabled (Maximum only)"
Optional = $true Optional = $true
} }
@ -1850,10 +1850,10 @@ try {
# IPv6 Disable (mitm6 attack mitigation) - Maximum profile only # IPv6 Disable (mitm6 attack mitigation) - Maximum profile only
# Optional = true because only applied for Maximum profile (user choice) # Optional = true because only applied for Maximum profile (user choice)
$ipv6Check = @{ $ipv6Check = @{
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
Name = "DisabledComponents" Name = "DisabledComponents"
Expected = 255 # 0xFF = completely disabled Expected = 255 # 0xFF = completely disabled
Desc = "IPv6 Disabled (mitm6 mitigation, Maximum only)" Desc = "IPv6 Disabled (mitm6 mitigation, Maximum only)"
Optional = $true Optional = $true
} }
@ -1888,10 +1888,10 @@ try {
# Windows Update (4 Checks) - ALWAYS required - matches AdvancedSecurity module Config/WindowsUpdate.json # Windows Update (4 Checks) - ALWAYS required - matches AdvancedSecurity module Config/WindowsUpdate.json
$wuChecks = @( $wuChecks = @(
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "AllowOptionalContent"; Expected = 1; Desc = "WU: Get latest updates immediately (Policy)"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "AllowOptionalContent"; Expected = 1; Desc = "WU: Get latest updates immediately (Policy)"; Optional = $false }
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "SetAllowOptionalContent"; Expected = 1; Desc = "WU: AllowOptionalContent Policy Flag"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"; Name = "SetAllowOptionalContent"; Expected = 1; Desc = "WU: AllowOptionalContent Policy Flag"; Optional = $false }
@{ Path = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"; Name = "AllowMUUpdateService"; Expected = 1; Desc = "WU: Microsoft Update (Office, drivers)"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"; Name = "AllowMUUpdateService"; Expected = 1; Desc = "WU: Microsoft Update (Office, drivers)"; Optional = $false }
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"; Name = "DODownloadMode"; Expected = 0; Desc = "WU: P2P Delivery Optimization OFF"; Optional = $false } @{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization"; Name = "DODownloadMode"; Expected = 0; Desc = "WU: P2P Delivery Optimization OFF"; Optional = $false }
) )
# Finger Protocol (1 check) - verify outbound firewall rule created by AdvancedSecurity # Finger Protocol (1 check) - verify outbound firewall rule created by AdvancedSecurity
@ -1911,7 +1911,8 @@ try {
else { else {
$actualDesc = if ($portFilter) { $actualDesc = if ($portFilter) {
"Protocol=$($portFilter.Protocol), RemotePort=$($portFilter.RemotePort)" "Protocol=$($portFilter.Protocol), RemotePort=$($portFilter.RemotePort)"
} else { }
else {
"No port filter" "No port filter"
} }
} }
@ -2050,8 +2051,8 @@ try {
$hkuPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings" $hkuPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings"
$userSIDs = Get-ChildItem -Path "HKU:\" -ErrorAction SilentlyContinue | $userSIDs = Get-ChildItem -Path "HKU:\" -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -match '^S-1-5-21-' -and $_.PSChildName -notmatch '_Classes$' } | Where-Object { $_.PSChildName -match '^S-1-5-21-' -and $_.PSChildName -notmatch '_Classes$' } |
Select-Object -ExpandProperty PSChildName Select-Object -ExpandProperty PSChildName
$hkuCompliant = $true $hkuCompliant = $true
$hkuActualValue = "All users compliant" $hkuActualValue = "All users compliant"
@ -2222,10 +2223,10 @@ try {
$totalAdapters = $adapters.Count $totalAdapters = $adapters.Count
$disabledCount = 0 $disabledCount = 0
$nonCompliant = @() $nonCompliant = @()
foreach ($adapter in $adapters) { foreach ($adapter in $adapters) {
$adapterName = if ($adapter.Description.Length -gt 40) { $adapter.Description.Substring(0,37) + "..." } else { $adapter.Description } $adapterName = if ($adapter.Description.Length -gt 40) { $adapter.Description.Substring(0, 37) + "..." } else { $adapter.Description }
if ($adapter.TcpipNetbiosOptions -eq 2) { if ($adapter.TcpipNetbiosOptions -eq 2) {
$disabledCount++ $disabledCount++
} }
@ -2545,7 +2546,7 @@ catch {
# drift from per-category counters in case some success paths didn't # drift from per-category counters in case some success paths didn't
# manually increment $results.Verified. # manually increment $results.Verified.
$results.TotalSettings = ($results.AllSettings | Measure-Object -Property Total -Sum).Sum $results.TotalSettings = ($results.AllSettings | Measure-Object -Property Total -Sum).Sum
$results.Verified = ($results.AllSettings | Measure-Object -Property Passed -Sum).Sum $results.Verified = ($results.AllSettings | Measure-Object -Property Passed -Sum).Sum
$results.Duration = (Get-Date) - $startTime $results.Duration = (Get-Date) - $startTime
@ -2991,8 +2992,8 @@ try {
} }
.module-content { .module-content {
max-height: 5000px; max-height: none;
overflow: hidden; overflow: visible;
transition: max-height 0.3s ease; transition: max-height 0.3s ease;
} }
@ -3140,6 +3141,70 @@ try {
.controls, .export-section { .controls, .export-section {
display: none; display: none;
} }
/* Balanced header for print */
.header {
padding: 1.5rem 2rem;
page-break-inside: avoid;
}
.header h1 {
font-size: 1.8rem;
margin-bottom: 0.3rem;
}
.header .subtitle {
font-size: 1rem;
}
.header .badge {
margin-top: 0.5rem;
padding: 0.4rem 1.2rem;
font-size: 0.85rem;
}
/* Balanced meta-info for print */
.meta-info {
padding: 1rem 1.5rem;
gap: 1rem;
page-break-inside: avoid;
}
.meta-label {
font-size: 0.65rem;
}
.meta-value {
font-size: 0.95rem;
}
/* Balanced dashboard for print */
.dashboard {
padding: 1rem 1.5rem;
page-break-inside: avoid;
}
.stats-grid {
page-break-inside: avoid;
display: flex;
flex-wrap: nowrap;
gap: 1rem;
margin-bottom: 1rem;
}
.stat-card {
flex: 1;
min-width: 0;
padding: 1rem;
}
.stat-value {
font-size: 2rem;
}
.stat-label {
font-size: 0.75rem;
}
.progress-section {
margin: 0.75rem 0;
page-break-inside: avoid;
}
.progress-bar-container {
height: 40px;
}
.progress-bar-fill {
background: #10b981 !important;
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
.module-section { .module-section {
page-break-inside: avoid; page-break-inside: avoid;
} }
@ -3180,7 +3245,7 @@ try {
<body> <body>
<div class="container"> <div class="container">
<div class="header"> <div class="header">
<h1>NoID Privacy v2.2.2</h1> <h1>NoID Privacy v2.2.3</h1>
<p class="subtitle">Complete Hardening Compliance Report</p> <p class="subtitle">Complete Hardening Compliance Report</p>
<span class="badge">All $totalSettings Settings Verified</span> <span class="badge">All $totalSettings Settings Verified</span>
</div> </div>
@ -3200,7 +3265,7 @@ try {
</div> </div>
<div class="meta-item"> <div class="meta-item">
<span class="meta-label">Framework Version</span> <span class="meta-label">Framework Version</span>
<span class="meta-value">NoID Privacy v2.2.2</span> <span class="meta-value">NoID Privacy v2.2.3</span>
</div> </div>
</div> </div>
@ -3359,11 +3424,11 @@ try {
$friendlyName = $zoneSettingNames[$settingName] $friendlyName = $zoneSettingNames[$settingName]
if ($friendlyName) { if ($friendlyName) {
$zoneName = if ($pathInfo -like "*Zones\\0*") { "My Computer" } $zoneName = if ($pathInfo -like "*Zones\\0*") { "My Computer" }
elseif ($pathInfo -like "*Zones\\1*") { "Local Intranet" } elseif ($pathInfo -like "*Zones\\1*") { "Local Intranet" }
elseif ($pathInfo -like "*Zones\\2*") { "Trusted Sites" } elseif ($pathInfo -like "*Zones\\2*") { "Trusted Sites" }
elseif ($pathInfo -like "*Zones\\3*") { "Internet" } elseif ($pathInfo -like "*Zones\\3*") { "Internet" }
elseif ($pathInfo -like "*Zones\\4*") { "Restricted Sites" } elseif ($pathInfo -like "*Zones\\4*") { "Restricted Sites" }
else { "Zone" } else { "Zone" }
$settingName = "[$zoneName] $friendlyName" $settingName = "[$zoneName] $friendlyName"
} }
} }
@ -3376,14 +3441,14 @@ try {
elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") { elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") {
# IE FeatureControl settings # IE FeatureControl settings
$featureNames = @{ $featureNames = @{
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)" "FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
"FEATURE_MIME_HANDLING" = "MIME Handling Security" "FEATURE_MIME_HANDLING" = "MIME Handling Security"
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection" "FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
"FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install" "FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install"
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download" "FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)" "FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)" "FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block" "FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
} }
$processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" } $processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" }
foreach ($feature in $featureNames.Keys) { foreach ($feature in $featureNames.Keys) {
@ -3521,11 +3586,11 @@ try {
$friendlyName = $zoneSettingNames[$settingName] $friendlyName = $zoneSettingNames[$settingName]
if ($friendlyName) { if ($friendlyName) {
$zoneName = if ($pathInfo -like "*Zones\\0*" -or $pathInfo -like "*Zones\0*") { "My Computer" } $zoneName = if ($pathInfo -like "*Zones\\0*" -or $pathInfo -like "*Zones\0*") { "My Computer" }
elseif ($pathInfo -like "*Zones\\1*" -or $pathInfo -like "*Zones\1*") { "Local Intranet" } elseif ($pathInfo -like "*Zones\\1*" -or $pathInfo -like "*Zones\1*") { "Local Intranet" }
elseif ($pathInfo -like "*Zones\\2*" -or $pathInfo -like "*Zones\2*") { "Trusted Sites" } elseif ($pathInfo -like "*Zones\\2*" -or $pathInfo -like "*Zones\2*") { "Trusted Sites" }
elseif ($pathInfo -like "*Zones\\3*" -or $pathInfo -like "*Zones\3*") { "Internet" } elseif ($pathInfo -like "*Zones\\3*" -or $pathInfo -like "*Zones\3*") { "Internet" }
elseif ($pathInfo -like "*Zones\\4*" -or $pathInfo -like "*Zones\4*") { "Restricted Sites" } elseif ($pathInfo -like "*Zones\\4*" -or $pathInfo -like "*Zones\4*") { "Restricted Sites" }
else { "Zone" } else { "Zone" }
$settingName = "[$zoneName] $friendlyName" $settingName = "[$zoneName] $friendlyName"
} }
} }
@ -3538,14 +3603,14 @@ try {
elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") { elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") {
# IE FeatureControl settings # IE FeatureControl settings
$featureNames = @{ $featureNames = @{
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)" "FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
"FEATURE_MIME_HANDLING" = "MIME Handling Security" "FEATURE_MIME_HANDLING" = "MIME Handling Security"
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection" "FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
"FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install" "FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install"
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download" "FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)" "FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)" "FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block" "FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
} }
$processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" } $processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" }
foreach ($feature in $featureNames.Keys) { foreach ($feature in $featureNames.Keys) {
@ -3642,7 +3707,7 @@ try {
</div> </div>
<div class="footer"> <div class="footer">
<p>Generated by NoID Privacy v2.2.2</p> <p>Generated by NoID Privacy v2.2.3</p>
<p>Professional Windows 11 Security & Privacy Hardening Framework</p> <p>Professional Windows 11 Security & Privacy Hardening Framework</p>
</div> </div>
</div> </div>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>

View file

@ -7,7 +7,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -55,9 +55,9 @@ function Test-SecEditAvailable {
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
Available = $false Available = $false
Path = $null Path = $null
Version = $null Version = $null
Error = $null Error = $null
} }
try { try {
@ -105,9 +105,9 @@ function Test-AuditPolAvailable {
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
Available = $false Available = $false
Path = $null Path = $null
Version = $null Version = $null
Error = $null Error = $null
} }
try { try {
@ -154,10 +154,10 @@ function Test-WindowsDefenderAvailable {
param() param()
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
Available = $false Available = $false
ServiceRunning = $false ServiceRunning = $false
ServiceName = "WinDefend" ServiceName = "WinDefend"
Error = $null Error = $null
} }
try { try {
@ -198,16 +198,16 @@ function Test-AllDependencies {
param() param()
$result = [PSCustomObject]@{ $result = [PSCustomObject]@{
AllAvailable = $true AllAvailable = $true
SecurityBaseline = @{ SecurityBaseline = @{
secedit = $null secedit = $null
auditpol = $null auditpol = $null
} }
ASR = @{ ASR = @{
defender = $null defender = $null
} }
MissingCritical = @() MissingCritical = @()
MissingOptional = @() MissingOptional = @()
} }
# Check secedit.exe (CRITICAL for SecurityBaseline) # Check secedit.exe (CRITICAL for SecurityBaseline)

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -25,24 +25,24 @@ function Test-VBSCapable {
param() param()
$requirements = @{ $requirements = @{
UEFI = Test-UEFIBoot UEFI = Test-UEFIBoot
SecureBoot = Test-SecureBootEnabled SecureBoot = Test-SecureBootEnabled
TPM = (Test-TPMAvailable).Present TPM = (Test-TPMAvailable).Present
Virtualization = Test-VirtualizationEnabled Virtualization = Test-VirtualizationEnabled
Windows11 = (Get-WindowsVersion).IsWindows11 Windows11 = (Get-WindowsVersion).IsWindows11
} }
$allMet = $requirements.UEFI -and $requirements.SecureBoot -and ` $allMet = $requirements.UEFI -and $requirements.SecureBoot -and `
$requirements.TPM -and $requirements.Virtualization -and ` $requirements.TPM -and $requirements.Virtualization -and `
$requirements.Windows11 $requirements.Windows11
return [PSCustomObject]@{ return [PSCustomObject]@{
Capable = $allMet Capable = $allMet
UEFI = $requirements.UEFI UEFI = $requirements.UEFI
SecureBoot = $requirements.SecureBoot SecureBoot = $requirements.SecureBoot
TPM = $requirements.TPM TPM = $requirements.TPM
Virtualization = $requirements.Virtualization Virtualization = $requirements.Virtualization
Windows11 = $requirements.Windows11 Windows11 = $requirements.Windows11
} }
} }
@ -90,13 +90,13 @@ function Get-CPUInfo {
$cpu = Get-CimInstance -ClassName Win32_Processor -ErrorAction Stop | Select-Object -First 1 $cpu = Get-CimInstance -ClassName Win32_Processor -ErrorAction Stop | Select-Object -First 1
return [PSCustomObject]@{ return [PSCustomObject]@{
Name = $cpu.Name Name = $cpu.Name
Manufacturer = $cpu.Manufacturer Manufacturer = $cpu.Manufacturer
Cores = $cpu.NumberOfCores Cores = $cpu.NumberOfCores
LogicalProcessors = $cpu.NumberOfLogicalProcessors LogicalProcessors = $cpu.NumberOfLogicalProcessors
MaxClockSpeed = $cpu.MaxClockSpeed MaxClockSpeed = $cpu.MaxClockSpeed
VirtualizationEnabled = $cpu.VirtualizationFirmwareEnabled VirtualizationEnabled = $cpu.VirtualizationFirmwareEnabled
Architecture = $cpu.Architecture Architecture = $cpu.Architecture
} }
} }
catch { catch {
@ -123,9 +123,9 @@ function Get-MemoryInfo {
return [PSCustomObject]@{ return [PSCustomObject]@{
TotalPhysicalMemoryGB = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2) TotalPhysicalMemoryGB = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
FreePhysicalMemoryGB = [math]::Round($os.FreePhysicalMemory / 1MB / 1024, 2) FreePhysicalMemoryGB = [math]::Round($os.FreePhysicalMemory / 1MB / 1024, 2)
TotalVirtualMemoryGB = [math]::Round($os.TotalVirtualMemorySize / 1MB / 1024, 2) TotalVirtualMemoryGB = [math]::Round($os.TotalVirtualMemorySize / 1MB / 1024, 2)
FreeVirtualMemoryGB = [math]::Round($os.FreeVirtualMemory / 1MB / 1024, 2) FreeVirtualMemoryGB = [math]::Round($os.FreeVirtualMemory / 1MB / 1024, 2)
} }
} }
catch { catch {
@ -192,16 +192,16 @@ function Get-WindowsEditionInfo {
$supportsBitLocker = -not $isHome $supportsBitLocker = -not $isHome
return [PSCustomObject]@{ return [PSCustomObject]@{
Caption = $os.Caption Caption = $os.Caption
Version = $os.Version Version = $os.Version
BuildNumber = $os.BuildNumber BuildNumber = $os.BuildNumber
IsHome = $isHome IsHome = $isHome
IsPro = $isPro IsPro = $isPro
IsEnterprise = $isEnterprise IsEnterprise = $isEnterprise
IsEducation = $isEducation IsEducation = $isEducation
SupportsCredentialGuard = $supportsCredentialGuard SupportsCredentialGuard = $supportsCredentialGuard
SupportsAppLocker = $supportsAppLocker SupportsAppLocker = $supportsAppLocker
SupportsBitLocker = $supportsBitLocker SupportsBitLocker = $supportsBitLocker
} }
} }
catch { catch {
@ -223,16 +223,16 @@ function Get-HardwareReport {
param() param()
return [PSCustomObject]@{ return [PSCustomObject]@{
OS = Get-WindowsVersion OS = Get-WindowsVersion
Edition = Get-WindowsEditionInfo Edition = Get-WindowsEditionInfo
CPU = Get-CPUInfo CPU = Get-CPUInfo
Memory = Get-MemoryInfo Memory = Get-MemoryInfo
UEFI = Test-UEFIBoot UEFI = Test-UEFIBoot
SecureBoot = Test-SecureBootEnabled SecureBoot = Test-SecureBootEnabled
TPM = Test-TPMAvailable TPM = Test-TPMAvailable
Virtualization = Test-VirtualizationEnabled Virtualization = Test-VirtualizationEnabled
VBSCapable = Test-VBSCapable VBSCapable = Test-VBSCapable
SSD = Test-SSDDrive SSD = Test-SSDDrive
} }
} }

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>

View file

@ -8,7 +8,7 @@
.NOTES .NOTES
Author: NexusOne23 Author: NexusOne23
Version: 2.2.2 Version: 2.2.3
Requires: PowerShell 5.1+ Requires: PowerShell 5.1+
#> #>
@ -213,12 +213,12 @@ function Get-ServiceStatus {
$serviceWmi = Get-CimInstance -ClassName Win32_Service -Filter "Name='$ServiceName'" -ErrorAction Stop $serviceWmi = Get-CimInstance -ClassName Win32_Service -Filter "Name='$ServiceName'" -ErrorAction Stop
return [PSCustomObject]@{ return [PSCustomObject]@{
Name = $service.Name Name = $service.Name
DisplayName = $service.DisplayName DisplayName = $service.DisplayName
Status = $service.Status Status = $service.Status
StartType = $service.StartType StartType = $service.StartType
StartMode = $serviceWmi.StartMode StartMode = $serviceWmi.StartMode
PathName = $serviceWmi.PathName PathName = $serviceWmi.PathName
Description = $serviceWmi.Description Description = $serviceWmi.Description
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Before After
Before After

View file

@ -1,5 +1,5 @@
{ {
"version": "2.2.2", "version": "2.2.3",
"modules": { "modules": {
"SecurityBaseline": { "SecurityBaseline": {
"enabled": true, "enabled": true,
@ -48,7 +48,7 @@
"description": "Microsoft Edge v139 Security Baseline: 24 security policies", "description": "Microsoft Edge v139 Security Baseline: 24 security policies",
"_comment": "Interactive: Allow extensions (Y/N, default: Y)", "_comment": "Interactive: Allow extensions (Y/N, default: Y)",
"allowExtensions": true, "allowExtensions": true,
"version": "2.2.2", "version": "2.2.3",
"baseline": "Edge v139", "baseline": "Edge v139",
"policies": 24, "policies": 24,
"features": { "features": {
@ -75,7 +75,7 @@
"disableWirelessDisplay": false, "disableWirelessDisplay": false,
"disableDiscoveryProtocols": true, "disableDiscoveryProtocols": true,
"disableIPv6": false, "disableIPv6": false,
"version": "2.2.2", "version": "2.2.3",
"policies": 50, "policies": 50,
"features": { "features": {
"rdp_hardening": true, "rdp_hardening": true,
@ -94,7 +94,11 @@
"firewall_shields_up": true, "firewall_shields_up": true,
"ipv6_disable": true "ipv6_disable": true
}, },
"profiles": ["Balanced", "Enterprise", "Maximum"] "profiles": [
"Balanced",
"Enterprise",
"Maximum"
]
} }
}, },
"options": { "options": {