mirror of
https://github.com/NexusOne23/noid-privacy.git
synced 2026-04-18 05:39:06 +02:00
Compare commits
No commits in common. "main" and "v2.2.2" have entirely different histories.
68 changed files with 770 additions and 1483 deletions
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -32,7 +32,7 @@ A clear description of what actually happened.
|
|||
- **CPU**: [e.g., AMD Ryzen 7 9800X3D]
|
||||
- **TPM**: [e.g., 2.0 Present]
|
||||
- **Third-Party AV**: [e.g., None, Windows Defender only]
|
||||
- **Script Version**: [e.g., v2.2.4]
|
||||
- **Script Version**: [e.g., v2.2.1]
|
||||
- **Execution Mode**: [Interactive / Direct / DryRun]
|
||||
|
||||
**Get System Info:**
|
||||
|
|
|
|||
79
CHANGELOG.md
79
CHANGELOG.md
|
|
@ -7,63 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
---
|
||||
|
||||
## [2.2.4] - 2026-03-24
|
||||
|
||||
### 🔧 Enhancement Release
|
||||
|
||||
**Third-party security product detection for ASR module and verification.**
|
||||
|
||||
### ✨ Added
|
||||
|
||||
**EDR/XDR and Third-Party AV Detection ([#15](https://github.com/NexusOne23/noid-privacy/issues/15))**
|
||||
- New: 3-layer detection for third-party security products:
|
||||
- Layer 1: WMI `SecurityCenter2` (traditional AV: Bitdefender, Kaspersky, Avira, Norton, ESET, etc.)
|
||||
- Layer 2: Defender Passive Mode via `Get-MpComputerStatus` (EDR/XDR: CrowdStrike, SentinelOne, etc.)
|
||||
- Layer 3: 18 known EDR service names for display identification
|
||||
- New: `Test-ThirdPartySecurityProduct` function in `Utils/Dependencies.ps1` (central, reusable)
|
||||
- New: `Test-WindowsDefenderAvailable` now reports `IsPassiveMode` property
|
||||
- ASR module gracefully skips when third-party product detected (`Success = $true`, not an error)
|
||||
- Verify script counts ASR as 19/19 verified when third-party product is primary
|
||||
- Reported by: VM-Master
|
||||
|
||||
**Version Management**
|
||||
- New: `VERSION` file as single source of truth for version numbers
|
||||
- New: `Tools/Bump-Version.ps1` — automated version bump across all 61 project files
|
||||
- DryRun mode for preview, CHANGELOG.md excluded (historical entries preserved)
|
||||
|
||||
### 📁 Files Changed
|
||||
- `Utils/Dependencies.ps1` — New `Test-ThirdPartySecurityProduct`, updated `Test-WindowsDefenderAvailable`, updated `Test-AllDependencies`
|
||||
- `Modules/ASR/Public/Invoke-ASRRules.ps1` — 3-layer detection before Defender check, inline fallback for standalone mode
|
||||
- `Tools/Verify-Complete-Hardening.ps1` — 3-layer detection, ASR verified as skipped when third-party product active
|
||||
- `Tools/Bump-Version.ps1` — New file
|
||||
- `VERSION` — New file
|
||||
|
||||
---
|
||||
|
||||
## [2.2.3] - 2026-03-05
|
||||
|
||||
### 🔨 Bugfix Release
|
||||
|
||||
**Restore Mode crash fix and Recall snapshot storage verification fix.**
|
||||
|
||||
### 🔨 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
|
||||
|
||||
**Recall Snapshot Storage Verification (Bug)**
|
||||
- Fixed: "Maximum snapshot storage: 10 GB" verification always reported as failed
|
||||
- Root cause: Microsoft's WindowsAI CSP stores snapshot storage in **MB**, not GB (e.g., `10240` = 10 GB)
|
||||
- Fix: Updated expected values in config, apply, verify, and docs to use MB values
|
||||
- Affected values: 10→10240, 25→25600, 50→51200, 75→76800, 100→102400, 150→153600, 0=OS default unchanged
|
||||
- Reported by: VM-Master ([#14](https://github.com/NexusOne23/noid-privacy/issues/14))
|
||||
|
||||
---
|
||||
|
||||
## [2.2.2] - 2025-12-22
|
||||
|
||||
### 🚀 Performance Release
|
||||
|
|
@ -120,6 +63,11 @@ 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
|
||||
- Version numbers aligned across all 50+ files
|
||||
|
||||
### 🔐 Verify Download
|
||||
```
|
||||
SHA256: fdb364d48e67a6889b44a519ba061cd570411158b8bdeb9b91ec845b7e270d96
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## [2.2.0] - 2025-12-08
|
||||
|
|
@ -130,7 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
---
|
||||
|
||||
### 🌟 Release Highlights
|
||||
## 🌟 Release Highlights
|
||||
|
||||
✅ **630+ Settings** - Expanded from 580+ (Privacy, AntiAI, EdgeHardening, AdvSec Wireless Display)
|
||||
✅ **NonInteractive Mode** - Full GUI integration via config.json
|
||||
|
|
@ -246,7 +194,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
---
|
||||
|
||||
### 🌟 Release Highlights
|
||||
## 🌟 Release Highlights
|
||||
|
||||
✅ **All 7 Modules Production-Ready** - Complete framework with 580+ security settings
|
||||
✅ **Zero-Day Protection** - CVE-2025-9491 mitigation (SRP .lnk protection)
|
||||
|
|
@ -290,13 +238,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Windows Copilot (system-wide disabled + hardware key remapped)
|
||||
- Click to Do, Paint AI, Notepad AI, Settings Agent - all disabled
|
||||
|
||||
**EdgeHardening** (24 policies) - Microsoft Edge Security Baseline
|
||||
**EdgeHardening** (20 policies) - Microsoft Edge Security Baseline
|
||||
- SmartScreen enforced, Tracking Prevention strict
|
||||
- SSL/TLS hardening, Extension security
|
||||
- IE Mode restrictions
|
||||
- Native PowerShell implementation (no LGPO.exe)
|
||||
|
||||
**AdvancedSecurity** (50 settings) - Beyond Microsoft Baseline
|
||||
**AdvancedSecurity** (44 settings) - Beyond Microsoft Baseline
|
||||
- **SRP .lnk Protection (CVE-2025-9491)** - Zero-day mitigation for ClickFix malware
|
||||
- **RDP Hardening** - Disabled by default, TLS + NLA enforced
|
||||
- **Legacy Protocol Blocking** - SMBv1, NetBIOS, LLMNR, WPAD, PowerShell v2
|
||||
|
|
@ -309,7 +257,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
**Complete BAVR Pattern (Backup-Apply-Verify-Restore)**
|
||||
- All 580+ settings now fully verified in `Verify-Complete-Hardening.ps1`
|
||||
- EdgeHardening: 20 verification checks added
|
||||
- AdvancedSecurity: 44 verification checks added
|
||||
- AdvancedSecurity: 42 verification checks added
|
||||
- 100% coverage achieved (was 89.4%)
|
||||
|
||||
**Bloatware Removal & Restore**
|
||||
|
|
@ -437,10 +385,3 @@ Temp File Cleanup: Complete
|
|||
---
|
||||
|
||||
**Made with 🛡️ for the Windows Security Community**
|
||||
|
||||
[2.2.4]: https://github.com/NexusOne23/noid-privacy/compare/v2.2.3...v2.2.4
|
||||
[2.2.3]: https://github.com/NexusOne23/noid-privacy/compare/v2.2.2...v2.2.3
|
||||
[2.2.2]: https://github.com/NexusOne23/noid-privacy/compare/v2.2.1...v2.2.2
|
||||
[2.2.1]: https://github.com/NexusOne23/noid-privacy/compare/v2.2.0...v2.2.1
|
||||
[2.2.0]: https://github.com/NexusOne23/noid-privacy/compare/v2.1.0...v2.2.0
|
||||
[2.1.0]: https://github.com/NexusOne23/noid-privacy/releases/tag/v2.1.0
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Modules/
|
|||
|
||||
```
|
||||
Modules/AdvancedSecurity/
|
||||
├── AdvancedSecurity.psd1 # Manifest with version 2.2.4
|
||||
├── AdvancedSecurity.psd1 # Manifest with version 2.2.2
|
||||
├── AdvancedSecurity.psm1 # Loads Private/*.ps1 and Public/*.ps1
|
||||
├── Config/
|
||||
│ ├── RDP.json # RDP hardening config
|
||||
|
|
@ -105,7 +105,7 @@ Modules/AdvancedSecurity/
|
|||
```powershell
|
||||
@{
|
||||
RootModule = 'YourModule.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'YOUR-GUID-HERE' # Generate with [guid]::NewGuid()
|
||||
Author = 'Your Name'
|
||||
CompanyName = 'NoID Privacy'
|
||||
|
|
@ -128,7 +128,7 @@ Modules/AdvancedSecurity/
|
|||
Tags = @('Security', 'Hardening', 'Windows11')
|
||||
ProjectUri = 'https://github.com/yourusername/noid-privacy'
|
||||
ReleaseNotes = @"
|
||||
v2.2.4 - Initial Release
|
||||
v2.2.2 - Initial Release
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
"@
|
||||
|
|
@ -141,7 +141,7 @@ v2.2.4 - Initial Release
|
|||
```powershell
|
||||
@{
|
||||
RootModule = 'AdvancedSecurity.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
||||
Author = 'NexusOne23'
|
||||
Description = 'Advanced Security hardening beyond Microsoft Security Baseline'
|
||||
|
|
@ -155,7 +155,7 @@ v2.2.4 - Initial Release
|
|||
PSData = @{
|
||||
Tags = @('Security', 'Hardening', 'RDP', 'TLS', 'Windows11')
|
||||
ReleaseNotes = @"
|
||||
v2.2.4 - Production Release
|
||||
v2.2.2 - Production Release
|
||||
- RDP NLA enforcement + optional complete disable
|
||||
- WDigest credential protection
|
||||
- Administrative shares disable (domain-aware)
|
||||
|
|
@ -781,4 +781,4 @@ mkdir "Modules\YourModule\Config"
|
|||
|
||||
---
|
||||
|
||||
**Questions? Study AdvancedSecurity v2.2.4 - it's the reference implementation!** 🎯
|
||||
**Questions? Study AdvancedSecurity v2.2.2 - it's the reference implementation!** 🎯
|
||||
|
|
|
|||
143
Core/Config.ps1
143
Core/Config.ps1
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -79,104 +79,83 @@ function New-DefaultConfig {
|
|||
)
|
||||
|
||||
$defaultConfig = @{
|
||||
version = "2.2.4"
|
||||
version = "2.2.2"
|
||||
modules = @{
|
||||
SecurityBaseline = @{
|
||||
enabled = $true
|
||||
priority = 1
|
||||
status = "IMPLEMENTED"
|
||||
bitLockerUSBEnforcement = $false
|
||||
enabled = $true
|
||||
priority = 1
|
||||
status = "IMPLEMENTED"
|
||||
}
|
||||
ASR = @{
|
||||
enabled = $true
|
||||
priority = 2
|
||||
status = "IMPLEMENTED"
|
||||
usesManagementTools = $false
|
||||
allowNewSoftware = $false
|
||||
continueWithoutCloud = $true
|
||||
ASR = @{
|
||||
enabled = $true
|
||||
priority = 2
|
||||
status = "IMPLEMENTED"
|
||||
}
|
||||
DNS = @{
|
||||
enabled = $true
|
||||
DNS = @{
|
||||
enabled = $true
|
||||
priority = 3
|
||||
status = "IMPLEMENTED"
|
||||
provider = "Quad9"
|
||||
dohMode = "REQUIRE"
|
||||
provider = ""
|
||||
status = "IMPLEMENTED"
|
||||
}
|
||||
Privacy = @{
|
||||
enabled = $true
|
||||
priority = 4
|
||||
status = "IMPLEMENTED"
|
||||
mode = "MSRecommended"
|
||||
disableCloudClipboard = $true
|
||||
removeBloatware = $true
|
||||
Privacy = @{
|
||||
enabled = $true
|
||||
priority = 4
|
||||
mode = ""
|
||||
status = "IMPLEMENTED"
|
||||
}
|
||||
AntiAI = @{
|
||||
enabled = $true
|
||||
priority = 5
|
||||
status = "IMPLEMENTED"
|
||||
AntiAI = @{
|
||||
enabled = $true
|
||||
priority = 5
|
||||
status = "IMPLEMENTED"
|
||||
description = "Disable all Windows 11 AI features (Recall, Copilot, Paint AI, etc.)"
|
||||
}
|
||||
EdgeHardening = @{
|
||||
enabled = $true
|
||||
priority = 6
|
||||
status = "IMPLEMENTED"
|
||||
description = "Microsoft Edge v139 Security Baseline: 24 security policies"
|
||||
allowExtensions = $true
|
||||
version = "2.2.4"
|
||||
baseline = "Edge v139"
|
||||
policies = 24
|
||||
features = @{
|
||||
smartscreen_enforcement = $true
|
||||
site_isolation = $true
|
||||
ssl_error_blocking = $true
|
||||
extension_blocklist = $true
|
||||
ie_mode_restrictions = $true
|
||||
spectre_mitigations = $true
|
||||
application_encryption = $true
|
||||
EdgeHardening = @{
|
||||
enabled = $true
|
||||
priority = 6
|
||||
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."
|
||||
version = "2.2.2"
|
||||
baseline = "Edge v139"
|
||||
policies = 20
|
||||
features = @{
|
||||
smartscreen_enforcement = $true
|
||||
site_isolation = $true
|
||||
ssl_error_blocking = $true
|
||||
extension_blocklist = $true
|
||||
ie_mode_restrictions = $true
|
||||
spectre_mitigations = $true
|
||||
application_encryption = $true
|
||||
auth_scheme_restrictions = $true
|
||||
}
|
||||
}
|
||||
AdvancedSecurity = @{
|
||||
enabled = $true
|
||||
priority = 7
|
||||
status = "IMPLEMENTED"
|
||||
description = "Advanced Security hardening beyond MS Baseline"
|
||||
securityProfile = "Balanced"
|
||||
disableRDP = $true
|
||||
forceAdminShares = $false
|
||||
disableUPnP = $true
|
||||
disableWirelessDisplay = $false
|
||||
disableDiscoveryProtocols = $true
|
||||
disableIPv6 = $false
|
||||
version = "2.2.4"
|
||||
policies = 50
|
||||
features = @{
|
||||
rdp_hardening = $true
|
||||
wdigest_protection = $true
|
||||
admin_shares_disable = $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
|
||||
enabled = $true
|
||||
priority = 7
|
||||
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)"
|
||||
version = "2.2.2"
|
||||
policies = 36
|
||||
features = @{
|
||||
rdp_hardening = $true
|
||||
wdigest_protection = $true
|
||||
admin_shares_disable = $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
|
||||
}
|
||||
profiles = @("Balanced", "Enterprise", "Maximum")
|
||||
profiles = @("Balanced", "Enterprise", "Maximum")
|
||||
}
|
||||
}
|
||||
options = @{
|
||||
dryRun = $false
|
||||
createBackup = $true
|
||||
dryRun = $false
|
||||
createBackup = $true
|
||||
verboseLogging = $true
|
||||
autoReboot = $false
|
||||
nonInteractive = $false
|
||||
autoConfirm = $false
|
||||
autoReboot = $false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -434,7 +413,7 @@ function Get-EnabledModules {
|
|||
# Check if module is actually implemented
|
||||
if (Test-ModuleAvailability -ModuleName $moduleName) {
|
||||
$enabledModules += [PSCustomObject]@{
|
||||
Name = $moduleName
|
||||
Name = $moduleName
|
||||
Priority = $moduleConfig.priority
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
|
||||
.EXAMPLE
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
# All configuration comes from config.json via Initialize-Config.
|
||||
|
||||
# Script-level variables
|
||||
$script:FrameworkVersion = "2.2.4"
|
||||
$script:FrameworkVersion = "2.2.2"
|
||||
$script:FrameworkRoot = Split-Path -Parent $PSScriptRoot
|
||||
$script:ExecutionStartTime = Get-Date
|
||||
|
||||
|
|
@ -409,8 +409,8 @@ function Invoke-Hardening {
|
|||
else {
|
||||
# CLI mode: Auto-detect session type based on module count
|
||||
$autoSessionType = if ($modulesToExecute.Count -ge 7) { "wizard" }
|
||||
elseif ($modulesToExecute.Count -eq 1) { "advanced" }
|
||||
else { "manual" }
|
||||
elseif ($modulesToExecute.Count -eq 1) { "advanced" }
|
||||
else { "manual" }
|
||||
Set-SessionType -SessionType $autoSessionType
|
||||
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
|
||||
|
||||
$preFrameworkSnapshot = @{
|
||||
ASR = @{
|
||||
ASR = @{
|
||||
RuleIds = $ruleIds
|
||||
RuleActions = $ruleActions
|
||||
SnapshotDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -26,10 +26,10 @@ enum LogLevel {
|
|||
# NOTE: Must use Get-Variable to check existence (direct access fails in Strict Mode)
|
||||
if (-not (Get-Variable -Name 'LoggerConfig' -Scope Global -ErrorAction SilentlyContinue)) {
|
||||
$global:LoggerConfig = @{
|
||||
LogFilePath = ""
|
||||
MinimumLevel = [LogLevel]::INFO
|
||||
EnableConsole = $true
|
||||
EnableFile = $true
|
||||
LogFilePath = ""
|
||||
MinimumLevel = [LogLevel]::INFO
|
||||
EnableConsole = $true
|
||||
EnableFile = $true
|
||||
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)
|
||||
if ($global:LoggerConfig.EnableConsole -and $Level -ge [LogLevel]::INFO) {
|
||||
$consoleColor = switch ($Level) {
|
||||
([LogLevel]::DEBUG) { "Gray" }
|
||||
([LogLevel]::INFO) { "White" }
|
||||
([LogLevel]::DEBUG) { "Gray" }
|
||||
([LogLevel]::INFO) { "White" }
|
||||
([LogLevel]::WARNING) { "Yellow" }
|
||||
([LogLevel]::ERROR) { "Red" }
|
||||
([LogLevel]::ERROR) { "Red" }
|
||||
([LogLevel]::SUCCESS) { "Green" }
|
||||
default { "White" }
|
||||
}
|
||||
|
|
@ -245,15 +245,15 @@ function Get-ErrorContext {
|
|||
)
|
||||
|
||||
$context = @{
|
||||
Message = ""
|
||||
Exception = ""
|
||||
Category = ""
|
||||
Message = ""
|
||||
Exception = ""
|
||||
Category = ""
|
||||
TargetObject = ""
|
||||
ScriptName = ""
|
||||
LineNumber = 0
|
||||
Command = ""
|
||||
StackTrace = ""
|
||||
Summary = ""
|
||||
ScriptName = ""
|
||||
LineNumber = 0
|
||||
Command = ""
|
||||
StackTrace = ""
|
||||
Summary = ""
|
||||
}
|
||||
|
||||
if ($null -eq $ErrorRecord) {
|
||||
|
|
@ -271,15 +271,13 @@ function Get-ErrorContext {
|
|||
if ($ErrorRecord.InvocationInfo) {
|
||||
$context.ScriptName = if ($ErrorRecord.InvocationInfo.ScriptName) {
|
||||
Split-Path -Leaf $ErrorRecord.InvocationInfo.ScriptName
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
"N/A"
|
||||
}
|
||||
$context.LineNumber = $ErrorRecord.InvocationInfo.ScriptLineNumber
|
||||
$context.Command = if ($ErrorRecord.InvocationInfo.MyCommand) {
|
||||
$ErrorRecord.InvocationInfo.MyCommand.Name
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
"N/A"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
|
||||
Usage in modules:
|
||||
1. Call Test-NonInteractiveMode to check if prompts should be skipped
|
||||
|
|
@ -194,8 +194,7 @@ function Write-NonInteractiveDecision {
|
|||
|
||||
$message = if ($null -ne $Value) {
|
||||
"[GUI] $Decision : $Value"
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
"[GUI] $Decision"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ function Initialize-BackupSystem {
|
|||
displayName = "" # Auto-generated based on modules
|
||||
sessionType = "unknown" # wizard | advanced | manual
|
||||
timestamp = Get-Date -Format "o"
|
||||
frameworkVersion = "2.2.4"
|
||||
frameworkVersion = "2.2.2"
|
||||
modules = @()
|
||||
totalItems = 0
|
||||
restorable = $true
|
||||
|
|
@ -116,13 +116,13 @@ function Update-SessionDisplayName {
|
|||
# Calculate ACTUAL settings count (not backup items!)
|
||||
# Each module applies a specific number of settings (Paranoid mode = max):
|
||||
$settingsPerModule = @{
|
||||
"SecurityBaseline" = 425 # 335 Registry + 67 Security Template + 23 Audit
|
||||
"ASR" = 19 # 19 ASR Rules
|
||||
"DNS" = 5 # 5 DNS Settings
|
||||
"Privacy" = 78 # 54 Registry (MSRecommended) + 24 Bloatware
|
||||
"AntiAI" = 32 # 32 Registry Policies (15 features)
|
||||
"EdgeHardening" = 24 # 24 Edge Policies (22-23 applied depending on extensions)
|
||||
"AdvancedSecurity" = 50 # 50 Advanced Settings (15 features incl. Discovery Protocols + IPv6)
|
||||
"SecurityBaseline" = 425 # 335 Registry + 67 Security Template + 23 Audit
|
||||
"ASR" = 19 # 19 ASR Rules
|
||||
"DNS" = 5 # 5 DNS Settings
|
||||
"Privacy" = 78 # 54 Registry (MSRecommended) + 24 Bloatware
|
||||
"AntiAI" = 32 # 32 Registry Policies (15 features)
|
||||
"EdgeHardening" = 24 # 24 Edge Policies (22-23 applied depending on extensions)
|
||||
"AdvancedSecurity" = 50 # 50 Advanced Settings (15 features incl. Discovery Protocols + IPv6)
|
||||
}
|
||||
|
||||
$totalSettings = 0
|
||||
|
|
@ -382,10 +382,10 @@ function Backup-RegistryKey {
|
|||
|
||||
try {
|
||||
$emptyMarker = @{
|
||||
KeyPath = $KeyPath
|
||||
KeyPath = $KeyPath
|
||||
BackupDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
State = "NotExisted"
|
||||
Message = "Registry key did not exist before hardening - must be deleted during restore"
|
||||
State = "NotExisted"
|
||||
Message = "Registry key did not exist before hardening - must be deleted during restore"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$markerFile = Join-Path $backupFolder "$safeBackupName`_EMPTY.json"
|
||||
|
|
@ -935,10 +935,10 @@ function Restore-FromBackup {
|
|||
try {
|
||||
# Convert reg.exe path to PowerShell path
|
||||
$psKeyPath = $keyPathToRestore -replace 'HKEY_LOCAL_MACHINE', 'HKLM:' `
|
||||
-replace 'HKEY_CURRENT_USER', 'HKCU:' `
|
||||
-replace 'HKEY_CLASSES_ROOT', 'HKCR:' `
|
||||
-replace 'HKEY_USERS', 'HKU:' `
|
||||
-replace 'HKEY_CURRENT_CONFIG', 'HKCC:'
|
||||
-replace 'HKEY_CURRENT_USER', 'HKCU:' `
|
||||
-replace 'HKEY_CLASSES_ROOT', 'HKCR:' `
|
||||
-replace 'HKEY_USERS', 'HKU:' `
|
||||
-replace 'HKEY_CURRENT_CONFIG', 'HKCC:'
|
||||
|
||||
if (Test-Path $psKeyPath) {
|
||||
Write-Log -Level INFO -Message "Deleting existing protected key: $psKeyPath before re-import." -Module "Rollback"
|
||||
|
|
@ -1033,23 +1033,11 @@ function Invoke-RestoreRebootPrompt {
|
|||
Offers immediate or deferred reboot with countdown.
|
||||
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
|
||||
None
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$NoReboot,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$ForceReboot
|
||||
)
|
||||
param()
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
|
|
@ -1089,33 +1077,7 @@ function Invoke-RestoreRebootPrompt {
|
|||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# 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
|
||||
# Prompt user with validation loop
|
||||
do {
|
||||
Write-Host "Reboot now? [Y/N] (default: Y): " -NoNewline -ForegroundColor White
|
||||
$choice = Read-Host
|
||||
|
|
@ -1213,8 +1175,8 @@ function Restore-AllBackups {
|
|||
Write-Log -Level WARNING -Message "Full rollback completed with some failures" -Module "Rollback"
|
||||
}
|
||||
|
||||
# Prompt for reboot after restore (pass through reboot parameters)
|
||||
Invoke-RestoreRebootPrompt -NoReboot:$NoReboot -ForceReboot:$ForceReboot
|
||||
# Prompt for reboot after restore
|
||||
Invoke-RestoreRebootPrompt
|
||||
|
||||
return $allSucceeded
|
||||
}
|
||||
|
|
@ -1382,12 +1344,6 @@ function Restore-Session {
|
|||
.PARAMETER ModuleNames
|
||||
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
|
||||
Boolean indicating overall success
|
||||
#>
|
||||
|
|
@ -1398,13 +1354,7 @@ function Restore-Session {
|
|||
[string]$SessionPath,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string[]]$ModuleNames,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$NoReboot,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$ForceReboot
|
||||
[string[]]$ModuleNames
|
||||
)
|
||||
|
||||
if (-not (Test-Path $SessionPath)) {
|
||||
|
|
@ -1422,8 +1372,7 @@ function Restore-Session {
|
|||
Write-RestoreLog -Level INFO -Message "Session Path: $SessionPath"
|
||||
if ($ModuleNames) {
|
||||
Write-RestoreLog -Level INFO -Message "Specific Modules: $($ModuleNames -join ', ')"
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Write-RestoreLog -Level INFO -Message "Restoring: ALL modules"
|
||||
}
|
||||
Write-RestoreLog -Level INFO -Message "========================================"
|
||||
|
|
@ -1851,7 +1800,7 @@ function Restore-Session {
|
|||
for ($i = 0; $i -lt $preFramework.ASR.RuleIds.Count; $i++) {
|
||||
if ($preFramework.ASR.RuleActions[$i] -ne 0) {
|
||||
$asrRulesToRestore += @{
|
||||
GUID = $preFramework.ASR.RuleIds[$i]
|
||||
GUID = $preFramework.ASR.RuleIds[$i]
|
||||
Action = $preFramework.ASR.RuleActions[$i]
|
||||
}
|
||||
}
|
||||
|
|
@ -1894,8 +1843,8 @@ function Restore-Session {
|
|||
$ruleActions = $asrRulesToRestore | ForEach-Object { $_.Action }
|
||||
|
||||
Set-MpPreference -AttackSurfaceReductionRules_Ids $ruleIds `
|
||||
-AttackSurfaceReductionRules_Actions $ruleActions `
|
||||
-ErrorAction Stop
|
||||
-AttackSurfaceReductionRules_Actions $ruleActions `
|
||||
-ErrorAction Stop
|
||||
|
||||
$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"
|
||||
|
|
@ -1963,8 +1912,7 @@ function Restore-Session {
|
|||
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"
|
||||
}
|
||||
}
|
||||
|
|
@ -1988,10 +1936,10 @@ function Restore-Session {
|
|||
}
|
||||
|
||||
$regType = switch ($entry.Type) {
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"MultiString" { "MultiString" }
|
||||
default { "String" }
|
||||
default { "String" }
|
||||
}
|
||||
|
||||
$existing = Get-ItemProperty -Path $keyPath -Name $entry.Name -ErrorAction SilentlyContinue
|
||||
|
|
@ -2230,13 +2178,13 @@ function Restore-Session {
|
|||
}
|
||||
|
||||
$regType = switch ($entry.Type) {
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"MultiString" { "MultiString" }
|
||||
"ExpandString" { "ExpandString" }
|
||||
"Binary" { "Binary" }
|
||||
"QWord" { "QWord" }
|
||||
default { "String" }
|
||||
"Binary" { "Binary" }
|
||||
"QWord" { "QWord" }
|
||||
default { "String" }
|
||||
}
|
||||
|
||||
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
|
||||
|
|
@ -2298,7 +2246,7 @@ function Restore-Session {
|
|||
"HKCU:\Software\Microsoft\Windows\CurrentVersion\SystemSettings\AccountNotifications",
|
||||
"HKCU:\Software\Microsoft\Windows\CurrentVersion\UserProfileEngagement",
|
||||
"HKCU:\SOFTWARE\Microsoft\Personalization\Settings",
|
||||
# NEW: Input Personalization Settings (v2.2.4 - FIX missing HKCU restore)
|
||||
# NEW: Input Personalization Settings (v2.2.2 - FIX missing HKCU restore)
|
||||
"HKCU:\SOFTWARE\Microsoft\InputPersonalization",
|
||||
"HKCU:\SOFTWARE\Microsoft\InputPersonalization\TrainedDataStore",
|
||||
"HKCU:\Software\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\appDiagnostics"
|
||||
|
|
@ -2315,8 +2263,7 @@ function Restore-Session {
|
|||
Remove-ItemProperty -Path $keyPath -Name $prop -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
} catch {
|
||||
Write-Log -Level DEBUG -Message "Could not clear $keyPath : $_" -Module "Rollback"
|
||||
}
|
||||
}
|
||||
|
|
@ -2333,12 +2280,12 @@ function Restore-Session {
|
|||
}
|
||||
|
||||
$regType = switch ($entry.Type) {
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"MultiString" { "MultiString" }
|
||||
"ExpandString" { "ExpandString" }
|
||||
"Binary" { "Binary" }
|
||||
default { "String" }
|
||||
"Binary" { "Binary" }
|
||||
default { "String" }
|
||||
}
|
||||
|
||||
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
|
||||
|
|
@ -2516,13 +2463,13 @@ function Restore-Session {
|
|||
}
|
||||
|
||||
$regType = switch ($entry.Type) {
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"DWord" { "DWord" }
|
||||
"String" { "String" }
|
||||
"MultiString" { "MultiString" }
|
||||
"ExpandString" { "ExpandString" }
|
||||
"Binary" { "Binary" }
|
||||
"QWord" { "QWord" }
|
||||
default { "String" }
|
||||
"Binary" { "Binary" }
|
||||
"QWord" { "QWord" }
|
||||
default { "String" }
|
||||
}
|
||||
|
||||
New-ItemProperty -Path $entry.Path -Name $entry.Name -Value $entry.Value -PropertyType $regType -Force -ErrorAction Stop | Out-Null
|
||||
|
|
@ -2730,8 +2677,7 @@ function Restore-Session {
|
|||
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 ""
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Write-Host ""
|
||||
Write-Host " RESTORE COMPLETED WITH ISSUES " -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
|
@ -2744,8 +2690,8 @@ function Restore-Session {
|
|||
Write-Host ""
|
||||
Write-Host ""
|
||||
|
||||
# Prompt for reboot after restore (pass through reboot parameters)
|
||||
Invoke-RestoreRebootPrompt -NoReboot:$NoReboot -ForceReboot:$ForceReboot
|
||||
# Prompt for reboot after restore
|
||||
Invoke-RestoreRebootPrompt
|
||||
|
||||
# Final restore log entry
|
||||
$endTime = Get-Date
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -27,9 +27,9 @@ function Test-Prerequisites {
|
|||
Write-Log -Level INFO -Message "Starting prerequisite validation" -Module "Validator"
|
||||
|
||||
$result = [PSCustomObject]@{
|
||||
Success = $true
|
||||
Errors = @()
|
||||
Warnings = @()
|
||||
Success = $true
|
||||
Errors = @()
|
||||
Warnings = @()
|
||||
SystemInfo = $null
|
||||
}
|
||||
|
||||
|
|
@ -133,11 +133,11 @@ function Get-WindowsVersion {
|
|||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Version = $versionName
|
||||
BuildNumber = $buildNumber
|
||||
IsWindows11 = $isWindows11
|
||||
IsSupported = $isSupported
|
||||
Edition = $os.Caption
|
||||
Version = $versionName
|
||||
BuildNumber = $buildNumber
|
||||
IsWindows11 = $isWindows11
|
||||
IsSupported = $isSupported
|
||||
Edition = $os.Caption
|
||||
Architecture = $os.OSArchitecture
|
||||
}
|
||||
}
|
||||
|
|
@ -174,8 +174,8 @@ function Test-InternetConnectivity {
|
|||
param()
|
||||
|
||||
try {
|
||||
# Using Microsoft NCSI endpoint - same as Windows uses for connectivity detection
|
||||
$response = Test-Connection -ComputerName "www.msftconnecttest.com" -Count 1 -Quiet -ErrorAction Stop
|
||||
# Using Google DNS (8.8.8.8) - intentional for internet connectivity check
|
||||
$response = Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet -ErrorAction Stop
|
||||
return $response
|
||||
}
|
||||
catch {
|
||||
|
|
@ -200,26 +200,26 @@ function Test-TPMAvailable {
|
|||
|
||||
if ($null -eq $tpm) {
|
||||
return [PSCustomObject]@{
|
||||
Present = $false
|
||||
Version = "N/A"
|
||||
Enabled = $false
|
||||
Present = $false
|
||||
Version = "N/A"
|
||||
Enabled = $false
|
||||
Activated = $false
|
||||
}
|
||||
}
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Present = $tpm.TpmPresent
|
||||
Version = if ($tpm.ManufacturerVersion) { $tpm.ManufacturerVersion } else { "2.0" }
|
||||
Enabled = $tpm.TpmEnabled
|
||||
Present = $tpm.TpmPresent
|
||||
Version = if ($tpm.ManufacturerVersion) { $tpm.ManufacturerVersion } else { "2.0" }
|
||||
Enabled = $tpm.TpmEnabled
|
||||
Activated = $tpm.TpmActivated
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Log -Level WARNING -Message "Unable to check TPM status: $_" -Module "Validator"
|
||||
return [PSCustomObject]@{
|
||||
Present = $false
|
||||
Version = "Unknown"
|
||||
Enabled = $false
|
||||
Present = $false
|
||||
Version = "Unknown"
|
||||
Enabled = $false
|
||||
Activated = $false
|
||||
}
|
||||
}
|
||||
|
|
@ -294,14 +294,14 @@ function Get-SystemInfo {
|
|||
$internet = Test-InternetConnectivity
|
||||
|
||||
return [PSCustomObject]@{
|
||||
OS = $osInfo
|
||||
TPM = $tpmInfo
|
||||
SecureBoot = $secureBoot
|
||||
Virtualization = $virtualization
|
||||
IsAdministrator = $isAdmin
|
||||
OS = $osInfo
|
||||
TPM = $tpmInfo
|
||||
SecureBoot = $secureBoot
|
||||
Virtualization = $virtualization
|
||||
IsAdministrator = $isAdmin
|
||||
DiskSpaceAvailable = $diskSpace
|
||||
InternetConnected = $internet
|
||||
PowerShellVersion = $PSVersionTable.PSVersion.ToString()
|
||||
InternetConnected = $internet
|
||||
PowerShellVersion = $PSVersionTable.PSVersion.ToString()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -332,9 +332,9 @@ function Test-DomainJoined {
|
|||
|
||||
$result = [PSCustomObject]@{
|
||||
IsDomainJoined = $isDomainJoined
|
||||
DomainName = if ($isDomainJoined) { $computerSystem.Domain } else { "N/A" }
|
||||
Workgroup = if (-not $isDomainJoined) { $computerSystem.Workgroup } else { "N/A" }
|
||||
UserConfirmed = $false
|
||||
DomainName = if ($isDomainJoined) { $computerSystem.Domain } else { "N/A" }
|
||||
Workgroup = if (-not $isDomainJoined) { $computerSystem.Workgroup } else { "N/A" }
|
||||
UserConfirmed = $false
|
||||
}
|
||||
|
||||
if ($isDomainJoined) {
|
||||
|
|
@ -384,9 +384,9 @@ function Test-DomainJoined {
|
|||
Write-Log -Level ERROR -Message "Failed to check domain status: $_" -Module "Validator" -Exception $_.Exception
|
||||
return [PSCustomObject]@{
|
||||
IsDomainJoined = $false
|
||||
DomainName = "Error"
|
||||
Workgroup = "Error"
|
||||
UserConfirmed = $false
|
||||
DomainName = "Error"
|
||||
Workgroup = "Error"
|
||||
UserConfirmed = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -416,7 +416,7 @@ function Confirm-SystemBackup {
|
|||
Write-Log -Level INFO -Message "Backup recommendation: non-interactive confirmation (no prompt shown)" -Module "Validator"
|
||||
|
||||
$result = [PSCustomObject]@{
|
||||
UserConfirmed = $true
|
||||
UserConfirmed = $true
|
||||
BackupRecommended = $true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# NoID Privacy - Complete Feature List
|
||||
|
||||
**Framework Version:** v2.2.4
|
||||
**Framework Version:** v2.2.2
|
||||
**Total Security Settings:** 633 (Paranoid mode)
|
||||
**Modules:** 7 (All Production-Ready)
|
||||
**Last Updated:** December 22, 2025
|
||||
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
| Module | Settings | Status | Description |
|
||||
|--------|----------|--------|-------------|
|
||||
| **SecurityBaseline** | 425 | ✅ v2.2.4 | Microsoft Security Baseline for Windows 11 v25H2 |
|
||||
| **ASR** | 19 | ✅ v2.2.4 | Attack Surface Reduction rules |
|
||||
| **DNS** | 5 | ✅ v2.2.4 | Secure DNS with DoH encryption |
|
||||
| **Privacy** | 78 | ✅ v2.2.4 | Telemetry control, OneDrive hardening (Strict: 70 Registry + 2 Services + 6 OneDrive) |
|
||||
| **AntiAI** | 32 | ✅ v2.2.4 | AI lockdown (15 features, 32 compliance checks) |
|
||||
| **EdgeHardening** | 24 | ✅ v2.2.4 | Microsoft Edge browser security (24 policies) |
|
||||
| **AdvancedSecurity** | 50 | ✅ v2.2.4 | Advanced hardening beyond MS Baseline (incl. Wireless Display, Discovery Protocols, IPv6) |
|
||||
| **SecurityBaseline** | 425 | ✅ v2.2.2 | Microsoft Security Baseline for Windows 11 v25H2 |
|
||||
| **ASR** | 19 | ✅ v2.2.2 | Attack Surface Reduction rules |
|
||||
| **DNS** | 5 | ✅ v2.2.2 | Secure DNS with DoH encryption |
|
||||
| **Privacy** | 78 | ✅ v2.2.2 | Telemetry control, OneDrive hardening (Strict: 70 Registry + 2 Services + 6 OneDrive) |
|
||||
| **AntiAI** | 32 | ✅ v2.2.2 | AI lockdown (15 features, 32 compliance checks) |
|
||||
| **EdgeHardening** | 24 | ✅ v2.2.2 | Microsoft Edge browser security (24 policies) |
|
||||
| **AdvancedSecurity** | 50 | ✅ v2.2.2 | Advanced hardening beyond MS Baseline (incl. Wireless Display, Discovery Protocols, IPv6) |
|
||||
| **TOTAL** | **633** | ✅ **100%** | **Complete Framework (Paranoid mode)** |
|
||||
|
||||
---
|
||||
|
|
@ -238,7 +238,7 @@ Clipchamp.Clipchamp, SpotifyAB.SpotifyMusic
|
|||
|
||||
## 🤖 Module 5: AntiAI (32 Policies)
|
||||
|
||||
**Description:** Disable 15 Windows AI features via 32 registry policies (v2.2.4)
|
||||
**Description:** Disable 15 Windows AI features via 32 registry policies (v2.2.2)
|
||||
|
||||
### 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\SetDenyUriListForRecall = [...]
|
||||
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageDurationForRecallSnapshots = 30
|
||||
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageSpaceForRecallSnapshots = 10240
|
||||
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\SetMaximumStorageSpaceForRecallSnapshots = 10
|
||||
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI\TurnOffWindowsCopilot = 1
|
||||
HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot\TurnOffWindowsCopilot = 1
|
||||
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.4
|
||||
NoID Privacy v2.2.2
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Total Settings: 633 ✅
|
||||
|
|
@ -745,4 +745,4 @@ Framework Completion: 🎉 100% COMPLETE
|
|||
---
|
||||
|
||||
**Last Updated:** December 22, 2025
|
||||
**Framework Version:** v2.2.4
|
||||
**Framework Version:** v2.2.2
|
||||
|
|
|
|||
|
|
@ -1,31 +1,31 @@
|
|||
@{
|
||||
RootModule = 'ASR.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
GUID = 'b2c3d4e5-f6a7-8901-bcde-f23456789012'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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'
|
||||
RootModule = 'ASR.psm1'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'b2c3d4e5-f6a7-8901-bcde-f23456789012'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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'
|
||||
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
RequiredModules = @()
|
||||
RequiredModules = @()
|
||||
|
||||
FunctionsToExport = @(
|
||||
'Invoke-ASRRules'
|
||||
)
|
||||
|
||||
CmdletsToExport = @()
|
||||
CmdletsToExport = @()
|
||||
VariablesToExport = @()
|
||||
AliasesToExport = @()
|
||||
AliasesToExport = @()
|
||||
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Security', 'ASR', 'AttackSurfaceReduction', 'Defender', 'Windows11', 'Ransomware')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
Tags = @('Security', 'ASR', 'AttackSurfaceReduction', 'Defender', 'Windows11', 'Ransomware')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = @"
|
||||
v2.2.4 - Production Release
|
||||
v2.2.2 - Production Release
|
||||
- All 19 ASR rules implementation
|
||||
- Hybrid approach: Registry backup + Set-MpPreference application
|
||||
- SCCM/Configuration Manager detection
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges, Windows Defender
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -135,117 +135,50 @@ function Invoke-ASRRules {
|
|||
throw "Windows 11 or later required"
|
||||
}
|
||||
|
||||
# Check for third-party security products (AV or EDR/XDR)
|
||||
# This must happen BEFORE the Defender service check because:
|
||||
# - Traditional AVs may stop WinDefend entirely
|
||||
# - EDR/XDR (CrowdStrike, SentinelOne, etc.) leave WinDefend running in Passive Mode
|
||||
# - In both cases, ASR rules are not enforceable
|
||||
$securityProduct = $null
|
||||
if (Get-Command Test-ThirdPartySecurityProduct -ErrorAction SilentlyContinue) {
|
||||
$securityProduct = Test-ThirdPartySecurityProduct
|
||||
}
|
||||
else {
|
||||
# Fallback: Dependencies.ps1 not loaded (standalone module execution)
|
||||
# Inline 3-layer detection (mirrors Test-ThirdPartySecurityProduct)
|
||||
$securityProduct = [PSCustomObject]@{
|
||||
Detected = $false
|
||||
ProductName = $null
|
||||
DetectionMethod = $null
|
||||
DefenderPassiveMode = $false
|
||||
}
|
||||
|
||||
# Layer 1: WMI SecurityCenter2
|
||||
try {
|
||||
$avProducts = Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName "AntiVirusProduct" -ErrorAction SilentlyContinue
|
||||
$thirdPartyAV = $avProducts | Where-Object { $_.displayName -notmatch "Windows Defender|Microsoft Defender" } | Select-Object -First 1
|
||||
if ($thirdPartyAV) {
|
||||
$securityProduct.Detected = $true
|
||||
$securityProduct.ProductName = $thirdPartyAV.displayName
|
||||
$securityProduct.DetectionMethod = "SecurityCenter2"
|
||||
}
|
||||
}
|
||||
catch { $null = $null }
|
||||
|
||||
# Layer 2: Defender Passive Mode (catches EDR/XDR)
|
||||
if (-not $securityProduct.Detected) {
|
||||
try {
|
||||
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
|
||||
if ($defenderStatus -and $defenderStatus.AMRunningMode -eq "Passive Mode") {
|
||||
$securityProduct.Detected = $true
|
||||
$securityProduct.DefenderPassiveMode = $true
|
||||
$securityProduct.DetectionMethod = "PassiveMode"
|
||||
|
||||
# Layer 3: Known EDR service names for display name
|
||||
$edrServices = @(
|
||||
@{ Name = "CSFalconService"; Display = "CrowdStrike Falcon" },
|
||||
@{ Name = "SentinelAgent"; Display = "SentinelOne" },
|
||||
@{ Name = "CbDefense"; Display = "Carbon Black Cloud" },
|
||||
@{ Name = "CylanceSvc"; Display = "Cylance/Arctic Wolf Aurora" },
|
||||
@{ Name = "xagt"; Display = "Trellix Endpoint Security (HX)" },
|
||||
@{ Name = "masvc"; Display = "Trellix Agent" },
|
||||
@{ Name = "mfeatp"; Display = "Trellix Adaptive Threat Protection" },
|
||||
@{ Name = "cyserver"; Display = "Palo Alto Cortex XDR" },
|
||||
@{ Name = "EPSecurityService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "EPIntegrationService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "avp"; Display = "Kaspersky Endpoint Security" },
|
||||
@{ Name = "klnagent"; Display = "Kaspersky Security Center Agent" },
|
||||
@{ Name = "SEPAgent"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "SepMasterService"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "ekrn"; Display = "ESET Endpoint Security" },
|
||||
@{ Name = "EraAgentSvc"; Display = "ESET PROTECT Agent" },
|
||||
@{ Name = "Sophos MCS Agent"; Display = "Sophos Endpoint" },
|
||||
@{ Name = "HitmanPro.Alert"; Display = "Sophos Endpoint" }
|
||||
)
|
||||
|
||||
foreach ($edr in $edrServices) {
|
||||
$svc = Get-Service -Name $edr.Name -ErrorAction SilentlyContinue
|
||||
if ($svc -and $svc.Status -eq "Running") {
|
||||
$securityProduct.ProductName = $edr.Display
|
||||
$securityProduct.DetectionMethod = "PassiveMode+Service"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $securityProduct.ProductName) {
|
||||
$securityProduct.ProductName = "Unknown Security Product (Defender in Passive Mode)"
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { $null = $null }
|
||||
}
|
||||
}
|
||||
|
||||
# If third-party security product detected, skip ASR gracefully
|
||||
if ($securityProduct.Detected) {
|
||||
$avName = $securityProduct.ProductName
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Yellow
|
||||
Write-Host " ASR Module Skipped" -ForegroundColor Yellow
|
||||
Write-Host "========================================" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Third-party security product detected: $avName" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "ASR rules require Windows Defender as primary antivirus." -ForegroundColor Yellow
|
||||
Write-Host "Your security solution ($avName) has its own protection features." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "This is NOT an error - ASR will be skipped." -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
Write-Log -Level WARNING -Message "ASR skipped: Third-party security product detected ($avName). Detection: $($securityProduct.DetectionMethod)." -Module $moduleName
|
||||
|
||||
$result.Success = $true # Not an error - intentional skip
|
||||
$result.Warnings += "ASR skipped: Third-party security product detected ($avName). Your security solution provides its own protection."
|
||||
$result.RulesApplied = 0
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
# No third-party product detected - verify Defender is actually running
|
||||
# Check Windows Defender status and third-party AV
|
||||
$defenderService = Get-Service -Name "WinDefend" -ErrorAction SilentlyContinue
|
||||
$defenderRunning = $defenderService -and $defenderService.Status -eq "Running"
|
||||
|
||||
# Check for third-party antivirus (they disable Defender)
|
||||
$thirdPartyAV = $null
|
||||
try {
|
||||
$avProducts = Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName "AntiVirusProduct" -ErrorAction SilentlyContinue
|
||||
$thirdPartyAV = $avProducts | Where-Object { $_.displayName -notmatch "Windows Defender|Microsoft Defender" } | Select-Object -First 1
|
||||
}
|
||||
catch {
|
||||
# SecurityCenter2 not available - continue with Defender check only
|
||||
$null = $null
|
||||
}
|
||||
|
||||
if (-not $defenderRunning) {
|
||||
throw "Windows Defender service is not running and no third-party security product detected. ASR rules require Defender to be active."
|
||||
if ($thirdPartyAV) {
|
||||
# Third-party AV detected - skip ASR gracefully (not an error!)
|
||||
$avName = $thirdPartyAV.displayName
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Yellow
|
||||
Write-Host " ASR Module Skipped" -ForegroundColor Yellow
|
||||
Write-Host "========================================" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Third-party antivirus detected: $avName" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "ASR rules require Windows Defender to be active." -ForegroundColor Yellow
|
||||
Write-Host "Your antivirus ($avName) has its own protection features." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "This is NOT an error - ASR will be skipped." -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
Write-Log -Level WARNING -Message "ASR skipped: Third-party AV detected ($avName). Defender disabled." -Module $moduleName
|
||||
|
||||
$result.Success = $true # Not an error - intentional skip
|
||||
$result.Warnings += "ASR skipped: Third-party antivirus detected ($avName). Your AV provides similar protection."
|
||||
$result.RulesApplied = 0
|
||||
|
||||
return $result
|
||||
}
|
||||
else {
|
||||
# No third-party AV but Defender not running - this IS a problem
|
||||
throw "Windows Defender service is not running and no third-party antivirus detected. ASR rules require Defender to be active."
|
||||
}
|
||||
}
|
||||
|
||||
# Load ASR rule definitions
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Module manifest for AdvancedSecurity
|
||||
|
||||
# Version
|
||||
ModuleVersion = '2.2.4'
|
||||
ModuleVersion = '2.2.2'
|
||||
|
||||
# Unique ID
|
||||
GUID = 'e7f5a3d2-8c9b-4f1e-a6d3-9b2c8f4e5a1d'
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = @'
|
||||
v2.2.4 (2025-12-08)
|
||||
v2.2.2 (2025-12-08)
|
||||
- Production release of AdvancedSecurity module
|
||||
- 49 advanced hardening settings implemented (was 36)
|
||||
- NEW: Wireless Display (Miracast) security hardening
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# AdvancedSecurity Module Loader
|
||||
# Version: 2.2.4
|
||||
# Version: 2.2.2
|
||||
# Description: Advanced Security Hardening - Beyond Microsoft Security Baseline
|
||||
|
||||
# Get module path
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Administrative Shares Configuration",
|
||||
"description": "Configuration for disabling administrative shares (C$, ADMIN$, etc.) to prevent lateral movement",
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
|
||||
"Administrative_Shares": {
|
||||
"description": "Disable automatic creation and remove existing administrative shares",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Credential Protection Configuration",
|
||||
"description": "Configuration for credential hardening including WDigest protection",
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
|
||||
"WDigest_Protection": {
|
||||
"description": "Prevent WDigest from storing plaintext passwords in LSASS memory",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "RDP Hardening Configuration",
|
||||
"description": "Configuration for RDP (Remote Desktop Protocol) hardening including NLA enforcement and optional complete disable",
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
|
||||
"NLA_Enforcement": {
|
||||
"description": "Network Level Authentication (NLA) enforcement settings",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function Block-FingerProtocol {
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Administrator privileges
|
||||
|
||||
REFERENCES:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function Set-SRPRules {
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Administrator privileges
|
||||
|
||||
REFERENCES:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function Set-WindowsUpdate {
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Administrator privileges
|
||||
Based on: Windows Settings > Windows Update > Advanced options
|
||||
#>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function Invoke-AdvancedSecurity {
|
|||
- Enterprise: Conservative approach with domain-safety checks
|
||||
- Maximum: Maximum hardening for air-gapped/high-security environments
|
||||
|
||||
Features implemented (v2.2.4):
|
||||
Features implemented (v2.2.2):
|
||||
- RDP NLA enforcement + optional complete disable
|
||||
- WDigest credential protection
|
||||
- Administrative shares disable (domain-aware)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
@{
|
||||
RootModule = 'AntiAI.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
GUID = 'f8e9d7c6-5b4a-3c2d-1e0f-9a8b7c6d5e4f'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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.'
|
||||
RootModule = 'AntiAI.psm1'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'f8e9d7c6-5b4a-3c2d-1e0f-9a8b7c6d5e4f'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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.'
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
FunctionsToExport = @(
|
||||
'Invoke-AntiAI'
|
||||
)
|
||||
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Windows11', 'AI', 'Privacy', 'Security', 'Recall', 'Copilot', 'AntiAI')
|
||||
ProjectUri = 'https://github.com/yourusername/NoIDPrivacy'
|
||||
Tags = @('Windows11', 'AI', 'Privacy', 'Security', 'Recall', 'Copilot', 'AntiAI')
|
||||
ProjectUri = 'https://github.com/yourusername/NoIDPrivacy'
|
||||
ReleaseNotes = @'
|
||||
v1.0.0 - Initial Release
|
||||
- Disables 8+ Windows 11 AI features using official Microsoft policies
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
.NOTES
|
||||
Module: AntiAI
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Author: NoID Privacy
|
||||
#>
|
||||
|
||||
|
|
@ -22,12 +22,14 @@ $script:ModuleRoot = $PSScriptRoot
|
|||
|
||||
# Import private functions
|
||||
$privateFunctions = @(
|
||||
'Backup-AntiAISettings'
|
||||
'Restore-AntiAISettings'
|
||||
'Test-AntiAICompliance'
|
||||
'Set-SystemAIModels'
|
||||
'Disable-Recall'
|
||||
'Set-RecallProtection'
|
||||
'Disable-Copilot'
|
||||
'Disable-CopilotAdvanced' # NEW v2.2.4: URI handlers, Edge sidebar, Recall export
|
||||
'Disable-CopilotAdvanced' # NEW v2.2.2: URI handlers, Edge sidebar, Recall export
|
||||
'Disable-ClickToDo'
|
||||
'Disable-SettingsAgent'
|
||||
'Disable-ExplorerAI' # NEW: File Explorer AI Actions menu
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@
|
|||
},
|
||||
"SetMaximumStorageSpaceForRecallSnapshots": {
|
||||
"Type": "DWord",
|
||||
"Value": 10240,
|
||||
"Description": "Maximum snapshot storage: 10 GB = 10240 MB (Choices: 10240/25600/51200/76800/102400/153600 MB, 0=OS default)"
|
||||
"Value": 10,
|
||||
"Description": "Maximum snapshot storage: 10 GB (Choices: 10/25/50/75/100/150 GB, 0=OS default)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
.NOTES
|
||||
Requires Administrator privileges.
|
||||
Part of NoID Privacy AntiAI Module v2.2.4
|
||||
Part of NoID Privacy AntiAI Module v2.2.2
|
||||
#>
|
||||
function Disable-CopilotAdvanced {
|
||||
[CmdletBinding()]
|
||||
|
|
|
|||
|
|
@ -95,14 +95,14 @@ function Set-RecallProtection {
|
|||
Write-Log -Level DEBUG -Message "Set max snapshot retention: 30 days" -Module "AntiAI"
|
||||
$result.Applied++
|
||||
|
||||
# 4. Storage Space Limit - Max 10 GB (10240 MB per MS CSP)
|
||||
# 4. Storage Space Limit - Max 10 GB
|
||||
$existing = Get-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -ErrorAction SilentlyContinue
|
||||
if ($null -ne $existing) {
|
||||
Set-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10240 -Force
|
||||
Set-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10 -Force
|
||||
} else {
|
||||
New-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10240 -PropertyType DWord -Force | Out-Null
|
||||
New-ItemProperty -Path $regPath -Name "SetMaximumStorageSpaceForRecallSnapshots" -Value 10 -PropertyType DWord -Force | Out-Null
|
||||
}
|
||||
Write-Log -Level DEBUG -Message "Set max snapshot storage: 10 GB (10240 MB)" -Module "AntiAI"
|
||||
Write-Log -Level DEBUG -Message "Set max snapshot storage: 10 GB" -Module "AntiAI"
|
||||
$result.Applied++
|
||||
|
||||
# Verify
|
||||
|
|
@ -111,7 +111,7 @@ function Set-RecallProtection {
|
|||
$verified = ($null -ne $values.SetDenyAppListForRecall) -and
|
||||
($null -ne $values.SetDenyUriListForRecall) -and
|
||||
($values.SetMaximumStorageDurationForRecallSnapshots -eq 30) -and
|
||||
($values.SetMaximumStorageSpaceForRecallSnapshots -eq 10240)
|
||||
($values.SetMaximumStorageSpaceForRecallSnapshots -eq 10)
|
||||
|
||||
if ($verified) {
|
||||
Write-Log -Level DEBUG -Message "Verification SUCCESS: All Recall protection policies applied" -Module "AntiAI"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NoID Privacy
|
||||
Version: 2.2.4 (Extended validation)
|
||||
Version: 2.2.2 (Extended validation)
|
||||
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 "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 "SetMaximumStorageSpaceForRecallSnapshots" -ExpectedValue 10240 -Description "Max Storage: 10 GB (10240 MB)")
|
||||
(Test-RegistryValue -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI" -Name "SetMaximumStorageSpaceForRecallSnapshots" -ExpectedValue 10 -Description "Max Storage: 10 GB")
|
||||
)
|
||||
foreach ($check in $protectionChecks) {
|
||||
$results.Details += $check
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NoID Privacy
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Windows 11 24H2 or later, Administrator privileges
|
||||
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 " ANTI-AI MODULE v2.2.4" -ForegroundColor Cyan
|
||||
Write-Host " ANTI-AI MODULE v2.2.2" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
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\Policies\WindowsNotepad"; Name = "DisableAIFeatures"; Type = "DWord" },
|
||||
@{ Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsAI"; Name = "DisableSettingsAgent"; Type = "DWord" },
|
||||
# NEW v2.2.4: Advanced Copilot Blocking
|
||||
# NEW v2.2.2: Advanced Copilot Blocking
|
||||
@{ 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 = "ShowHubsSidebar"; Type = "DWord" },
|
||||
|
|
@ -196,7 +196,7 @@ function Invoke-AntiAI {
|
|||
$prop = Get-ItemProperty -Path $t.Path -Name $t.Name -ErrorAction SilentlyContinue
|
||||
if ($null -ne $prop -and $prop.PSObject.Properties.Name -contains $t.Name) {
|
||||
$entry.Exists = $true
|
||||
$entry.Value = $prop.$($t.Name)
|
||||
$entry.Value = $prop.$($t.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,8 +272,7 @@ function Invoke-AntiAI {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -356,7 +355,7 @@ function Invoke-AntiAI {
|
|||
}
|
||||
|
||||
# ============================================================================
|
||||
# ADVANCED COPILOT BLOCKING (NEW v2.2.4)
|
||||
# ADVANCED COPILOT BLOCKING (NEW v2.2.2)
|
||||
# ============================================================================
|
||||
Write-Host ""
|
||||
Write-Host " [Advanced Copilot Blocks]" -ForegroundColor Cyan
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# Module manifest for DNS module
|
||||
|
||||
RootModule = 'DNS.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'a8f7b3c9-4e5d-4a2b-9c1d-8f3e5a7b9c2d'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NoID Privacy
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,30 @@
|
|||
@{
|
||||
# Script module or binary module file associated with this manifest
|
||||
RootModule = 'EdgeHardening.psm1'
|
||||
RootModule = 'EdgeHardening.psm1'
|
||||
|
||||
# Version number of this module
|
||||
ModuleVersion = '2.2.4'
|
||||
ModuleVersion = '2.2.2'
|
||||
|
||||
# ID used to uniquely identify this module
|
||||
GUID = '8e3f4c2a-9b1d-4e7a-a2c5-6f8b3d9e1a4c'
|
||||
GUID = '8e3f4c2a-9b1d-4e7a-a2c5-6f8b3d9e1a4c'
|
||||
|
||||
# Author of this module
|
||||
Author = 'NexusOne23'
|
||||
Author = 'NexusOne23'
|
||||
|
||||
# Company or vendor of this module
|
||||
CompanyName = 'Open Source Project'
|
||||
CompanyName = 'Open Source Project'
|
||||
|
||||
# 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 = '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
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
# Modules that must be imported into the global environment prior to importing this module
|
||||
RequiredModules = @()
|
||||
RequiredModules = @()
|
||||
|
||||
# Functions to export from this module
|
||||
FunctionsToExport = @(
|
||||
|
|
@ -33,22 +33,22 @@
|
|||
)
|
||||
|
||||
# Cmdlets to export from this module
|
||||
CmdletsToExport = @()
|
||||
CmdletsToExport = @()
|
||||
|
||||
# Variables to export from this module
|
||||
VariablesToExport = @()
|
||||
|
||||
# Aliases to export from this module
|
||||
AliasesToExport = @()
|
||||
AliasesToExport = @()
|
||||
|
||||
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Security', 'Edge', 'Browser', 'Hardening', 'Baseline', 'Windows11', 'Privacy')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
Tags = @('Security', 'Edge', 'Browser', 'Hardening', 'Baseline', 'Windows11', 'Privacy')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = @"
|
||||
v2.2.4 - Production Release
|
||||
v2.2.2 - Production Release
|
||||
- Microsoft Edge v139 Security Baseline implementation
|
||||
- 20 security policies (native PowerShell, no LGPO.exe)
|
||||
- SmartScreen enforcement with override prevention
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
|
||||
IMPORTANT: This applies Microsoft's recommended security baseline.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Can be run without Administrator privileges
|
||||
#>
|
||||
|
||||
|
|
@ -103,8 +103,8 @@ function Test-EdgeHardening {
|
|||
|
||||
return [PSCustomObject]@{
|
||||
Compliant = $false
|
||||
Message = "Test failed: $($_.Exception.Message)"
|
||||
Details = @()
|
||||
Message = "Test failed: $($_.Exception.Message)"
|
||||
Details = @()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
@{
|
||||
RootModule = 'Privacy.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
GUID = 'a9f7c8d3-2e5b-4a1f-9c3d-7e8f5a6b2c4d'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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).'
|
||||
RootModule = 'Privacy.psm1'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'a9f7c8d3-2e5b-4a1f-9c3d-7e8f5a6b2c4d'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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).'
|
||||
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
|
|
@ -15,15 +15,15 @@
|
|||
'Test-PrivacyCompliance'
|
||||
)
|
||||
|
||||
CmdletsToExport = @()
|
||||
CmdletsToExport = @()
|
||||
VariablesToExport = @()
|
||||
AliasesToExport = @()
|
||||
AliasesToExport = @()
|
||||
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Privacy', 'Telemetry', 'Bloatware', 'OneDrive', 'Windows11', 'Security')
|
||||
LicenseUri = 'https://github.com/yourusername/NoIDPrivacyPro/blob/main/LICENSE'
|
||||
ProjectUri = 'https://github.com/yourusername/NoIDPrivacyPro'
|
||||
Tags = @('Privacy', 'Telemetry', 'Bloatware', 'OneDrive', 'Windows11', 'Security')
|
||||
LicenseUri = 'https://github.com/yourusername/NoIDPrivacyPro/blob/main/LICENSE'
|
||||
ProjectUri = 'https://github.com/yourusername/NoIDPrivacyPro'
|
||||
ReleaseNotes = 'Initial release - Privacy module with 3-mode support'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
.NOTES
|
||||
Module: Privacy
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Author: NoID Privacy
|
||||
#>
|
||||
|
||||
|
|
@ -26,6 +26,7 @@ $script:ModuleRoot = $PSScriptRoot
|
|||
# Import private functions
|
||||
$privateFunctions = @(
|
||||
'Backup-PrivacySettings',
|
||||
'Restore-PrivacySettings',
|
||||
'Set-TelemetrySettings',
|
||||
'Set-PersonalizationSettings',
|
||||
'Set-AppPrivacySettings',
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ function Invoke-PrivacyHardening {
|
|||
$bloatwareListPath = Join-Path $moduleBackupPath "REMOVED_APPS_LIST.txt"
|
||||
$listContent = @()
|
||||
$listContent += "================================================================"
|
||||
$listContent += " REMOVED APPS - NoID Privacy v2.2.4"
|
||||
$listContent += " REMOVED APPS - NoID Privacy v2.2.2"
|
||||
$listContent += " Session: $(Split-Path $moduleBackupPath -Leaf)"
|
||||
$listContent += " Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
||||
$listContent += "================================================================"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4 - Self-Contained Edition
|
||||
Version: 2.2.2 - Self-Contained Edition
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
|
||||
BREAKING CHANGE from v1.0:
|
||||
|
|
|
|||
|
|
@ -1,32 +1,32 @@
|
|||
@{
|
||||
RootModule = 'SecurityBaseline.psm1'
|
||||
ModuleVersion = '2.2.4'
|
||||
GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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)'
|
||||
RootModule = 'SecurityBaseline.psm1'
|
||||
ModuleVersion = '2.2.2'
|
||||
GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
||||
Author = 'NexusOne23'
|
||||
CompanyName = 'Open Source Project'
|
||||
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)'
|
||||
|
||||
PowerShellVersion = '5.1'
|
||||
|
||||
RequiredModules = @()
|
||||
RequiredModules = @()
|
||||
|
||||
FunctionsToExport = @(
|
||||
'Invoke-SecurityBaseline',
|
||||
'Restore-SecurityBaseline'
|
||||
)
|
||||
|
||||
CmdletsToExport = @()
|
||||
CmdletsToExport = @()
|
||||
VariablesToExport = @()
|
||||
AliasesToExport = @()
|
||||
AliasesToExport = @()
|
||||
|
||||
PrivateData = @{
|
||||
PrivateData = @{
|
||||
PSData = @{
|
||||
Tags = @('Security', 'Hardening', 'Windows11', 'Baseline', 'Microsoft', 'Enterprise')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
Tags = @('Security', 'Hardening', 'Windows11', 'Baseline', 'Microsoft', 'Enterprise')
|
||||
LicenseUri = ''
|
||||
ProjectUri = ''
|
||||
ReleaseNotes = @"
|
||||
v2.2.4 - Self-Contained Edition
|
||||
v2.2.2 - Self-Contained Edition
|
||||
- NO LGPO.exe REQUIRED! Fully self-contained implementation
|
||||
- 425 Microsoft Security Baseline settings for Windows 11 25H2
|
||||
- 335 Registry policies (Computer + User)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
resulting from its use. USE AT YOUR OWN RISK.
|
||||
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator
|
||||
For CLI mode use: NoIDPrivacy.ps1 -Module <name>
|
||||
#>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
# No parameters - interactive mode only
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$Host.UI.RawUI.WindowTitle = "NoID Privacy v2.2.4"
|
||||
$Host.UI.RawUI.WindowTitle = "NoID Privacy v2.2.2"
|
||||
|
||||
# Set script root path (required by modules to load configs)
|
||||
$script:RootPath = $PSScriptRoot
|
||||
|
|
@ -75,11 +75,11 @@ function Write-Step {
|
|||
|
||||
$symbol = switch ($Status) {
|
||||
"SUCCESS" { "[+]"; $color = "Green" }
|
||||
"ERROR" { "[-]"; $color = "Red" }
|
||||
"ERROR" { "[-]"; $color = "Red" }
|
||||
"WARNING" { "[!]"; $color = "Yellow" }
|
||||
"INFO" { "[>]"; $color = "Cyan" }
|
||||
"WAIT" { "[.]"; $color = "Gray" }
|
||||
default { "[ ]"; $color = "White" }
|
||||
"INFO" { "[>]"; $color = "Cyan" }
|
||||
"WAIT" { "[.]"; $color = "Gray" }
|
||||
default { "[ ]"; $color = "White" }
|
||||
}
|
||||
|
||||
Write-ColorText $symbol -Color $color -NoNewline
|
||||
|
|
@ -90,7 +90,7 @@ function Write-Banner {
|
|||
Clear-Host
|
||||
Write-Host ""
|
||||
Write-Host " ========================================" -ForegroundColor Cyan
|
||||
Write-Host " NoID Privacy v2.2.4 " -ForegroundColor Cyan
|
||||
Write-Host " NoID Privacy v2.2.2 " -ForegroundColor Cyan
|
||||
Write-Host " ========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
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 }
|
||||
$psVersion = $PSVersionTable.PSVersion.ToString()
|
||||
|
||||
$envLine = " Version 2.2.4"
|
||||
$envLine = " Version 2.2.2"
|
||||
if ($osBuild) {
|
||||
$envLine += " | Windows Build $osBuild"
|
||||
}
|
||||
|
|
@ -356,8 +356,7 @@ function Show-BackupList {
|
|||
# Force result to array to handle single-session case correctly
|
||||
if (Test-Path $backupPath) {
|
||||
$sessions = @(Get-BackupSessions -BackupDirectory $backupPath)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$sessions = @()
|
||||
}
|
||||
}
|
||||
|
|
@ -383,8 +382,8 @@ function Show-BackupList {
|
|||
try {
|
||||
$age = (Get-Date) - $session.Timestamp
|
||||
$ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" }
|
||||
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
|
||||
else { "$([math]::Round($age.TotalDays)) days ago" }
|
||||
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
|
||||
else { "$([math]::Round($age.TotalDays)) days ago" }
|
||||
}
|
||||
catch {
|
||||
$ageStr = "unknown age"
|
||||
|
|
@ -796,7 +795,7 @@ function Invoke-RestoreWorkflow {
|
|||
if ([string]::IsNullOrWhiteSpace($modeInput)) { $modeInput = "A" }
|
||||
$modeInput = $modeInput.Trim().ToUpper()
|
||||
|
||||
if ($modeInput -in @('A', 'M')) {
|
||||
if ($modeInput -in @('A','M')) {
|
||||
$restoreMode = $modeInput
|
||||
break
|
||||
}
|
||||
|
|
@ -819,7 +818,7 @@ function Invoke-RestoreWorkflow {
|
|||
}
|
||||
|
||||
$indices = @()
|
||||
foreach ($token in ($moduleInput -split '[,; ]')) {
|
||||
foreach ($token in $moduleInput.Split(',', ';', ' ')) {
|
||||
if (-not [string]::IsNullOrWhiteSpace($token)) {
|
||||
$parsed = 0
|
||||
if ([int]::TryParse($token.Trim(), [ref]$parsed)) {
|
||||
|
|
@ -838,7 +837,7 @@ function Invoke-RestoreWorkflow {
|
|||
}
|
||||
|
||||
foreach ($i in $indices) {
|
||||
$selectedModuleNames += $availableModules[$i - 1].name
|
||||
$selectedModuleNames += $availableModules[$i-1].name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
resulting from its use. USE AT YOUR OWN RISK.
|
||||
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Administrator privileges, Windows 11
|
||||
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
|
||||
# ============================================================================
|
||||
$script:EXIT_SUCCESS = 0 # All operations completed successfully
|
||||
$script:EXIT_ERROR_GENERAL = 1 # General/unspecified error
|
||||
$script:EXIT_SUCCESS = 0 # All operations completed successfully
|
||||
$script:EXIT_ERROR_GENERAL = 1 # General/unspecified error
|
||||
$script:EXIT_ERROR_PREREQUISITES = 2 # System requirements not met
|
||||
$script:EXIT_ERROR_CONFIG = 3 # Configuration file error
|
||||
$script:EXIT_ERROR_MODULE = 4 # One or more modules failed
|
||||
$script:EXIT_ERROR_FATAL = 5 # Fatal/unexpected exception
|
||||
$script:EXIT_SUCCESS_REBOOT = 10 # Success, reboot required
|
||||
$script:EXIT_ERROR_CONFIG = 3 # Configuration file error
|
||||
$script:EXIT_ERROR_MODULE = 4 # One or more modules failed
|
||||
$script:EXIT_ERROR_FATAL = 5 # Fatal/unexpected exception
|
||||
$script:EXIT_SUCCESS_REBOOT = 10 # Success, reboot required
|
||||
|
||||
# Script root path
|
||||
$script:RootPath = $PSScriptRoot
|
||||
|
|
@ -135,7 +135,7 @@ try {
|
|||
$logDirectory = Join-Path $script:RootPath "Logs"
|
||||
Initialize-Logger -LogDirectory $logDirectory -MinimumLevel $logLevel
|
||||
|
||||
Write-Log -Level INFO -Message "=== NoID Privacy Framework v2.2.4 ===" -Module "Main"
|
||||
Write-Log -Level INFO -Message "=== NoID Privacy Framework v2.2.2 ===" -Module "Main"
|
||||
Write-Log -Level INFO -Message "Starting framework initialization..." -Module "Main"
|
||||
|
||||
# Load other Core modules
|
||||
|
|
@ -216,7 +216,7 @@ catch {
|
|||
# Display banner
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " NoID Privacy - v2.2.4" -ForegroundColor Cyan
|
||||
Write-Host " NoID Privacy - v2.2.2" -ForegroundColor Cyan
|
||||
Write-Host " Windows 11 Security Hardening" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
|
@ -255,23 +255,23 @@ if (-not $Module) {
|
|||
if ([string]::IsNullOrWhiteSpace($selection)) { $selection = "99" }
|
||||
$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 "Invalid selection. Please choose from the menu." -ForegroundColor Red
|
||||
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) {
|
||||
"1" { $Module = "SecurityBaseline" }
|
||||
"2" { $Module = "ASR" }
|
||||
"3" { $Module = "DNS" }
|
||||
"4" { $Module = "Privacy" }
|
||||
"5" { $Module = "AntiAI" }
|
||||
"6" { $Module = "EdgeHardening" }
|
||||
"7" { $Module = "AdvancedSecurity" }
|
||||
"1" { $Module = "SecurityBaseline" }
|
||||
"2" { $Module = "ASR" }
|
||||
"3" { $Module = "DNS" }
|
||||
"4" { $Module = "Privacy" }
|
||||
"5" { $Module = "AntiAI" }
|
||||
"6" { $Module = "EdgeHardening" }
|
||||
"7" { $Module = "AdvancedSecurity" }
|
||||
"99" { $Module = "All" }
|
||||
"V" {
|
||||
"V" {
|
||||
# Verify all settings
|
||||
Write-Host ""
|
||||
Write-Host "Running complete verification..." -ForegroundColor Cyan
|
||||
|
|
@ -291,7 +291,7 @@ if (-not $Module) {
|
|||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
exit 0
|
||||
}
|
||||
"R" {
|
||||
"R" {
|
||||
# Restore from backup - Interactive session selection from disk
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
|
|
@ -365,7 +365,7 @@ if (-not $Module) {
|
|||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
exit 0
|
||||
}
|
||||
"B" {
|
||||
"B" {
|
||||
# List backups
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
|
|
@ -387,8 +387,8 @@ if (-not $Module) {
|
|||
foreach ($backup in $backups) {
|
||||
$age = (Get-Date) - $backup.CreationTime
|
||||
$ageStr = if ($age.TotalHours -lt 1) { "$([math]::Round($age.TotalMinutes)) minutes ago" }
|
||||
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
|
||||
else { "$([math]::Round($age.TotalDays)) days ago" }
|
||||
elseif ($age.TotalDays -lt 1) { "$([math]::Round($age.TotalHours)) hours ago" }
|
||||
else { "$([math]::Round($age.TotalDays)) days ago" }
|
||||
|
||||
Write-Host " - $($backup.Name)" -ForegroundColor Green -NoNewline
|
||||
Write-Host " ($ageStr)" -ForegroundColor Gray
|
||||
|
|
@ -404,7 +404,7 @@ if (-not $Module) {
|
|||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
exit 0
|
||||
}
|
||||
"I" {
|
||||
"I" {
|
||||
# System information
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
|
|
@ -451,7 +451,7 @@ if (-not $Module) {
|
|||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
exit 0
|
||||
}
|
||||
"0" {
|
||||
"0" {
|
||||
Write-Host "Exiting..." -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
|
|
|||
128
README.md
128
README.md
|
|
@ -1,15 +1,15 @@
|
|||
# 🛡️ NoID Privacy - Professional Windows 11 Security & Privacy Hardening Framework
|
||||
|
||||
> **⚠️ DISCLAIMER: USE AT YOUR OWN RISK.**
|
||||
> This tool makes deep modifications to the Windows Registry and System Services. While extensive backups are created, the authors accept **no responsibility for any damage, data loss, or system instability**. Always review changes before applying.
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://github.com/PowerShell/PowerShell)
|
||||
[](https://www.microsoft.com/windows/)
|
||||
[](LICENSE)
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
[](https://github.com/NexusOne23/noid-privacy/stargazers)
|
||||
[](https://github.com/NexusOne23/noid-privacy/commits)
|
||||
[](https://noid-privacy.com)
|
||||
[](CHANGELOG.md)
|
||||
[]()
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -24,42 +24,59 @@
|
|||
|
||||
**7 Independent Security Modules • Modular Design • Complete BAVR Pattern**
|
||||
|
||||
[](https://noid-privacy.com)
|
||||
|
||||
</div>
|
||||
|
||||
> **⚠️ DISCLAIMER:** This tool modifies Windows Registry and System Services. Full backups are created automatically (BAVR pattern), but always [create a system backup](#-system-backup-required) before running. Use at your own risk.
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><strong>⚠️ CRITICAL: Domain-Joined Systems & System Backup (click to expand)</strong></summary>
|
||||
## ⚠️ CRITICAL: Domain-Joined Systems & System Backup
|
||||
|
||||
> **⚡ READ THIS BEFORE RUNNING** This tool modifies critical Windows security settings!
|
||||
|
||||
### 🏢 Domain-Joined Systems (Active Directory)
|
||||
|
||||
**WARNING:** This tool is **NOT recommended for production domain-joined systems** without AD team coordination!
|
||||
|
||||
**Why?**
|
||||
- This tool modifies **local Group Policies**
|
||||
- Domain Group Policies **override local policies every 90 minutes**
|
||||
- Your hardening **may be reset automatically** by domain GPOs
|
||||
- Can lead to configuration conflicts and "flapping" behavior
|
||||
|
||||
**Recommended for:** Standalone systems, Home/Personal PCs, VMs, air-gapped systems, test/dev environments.
|
||||
**RECOMMENDED USE CASES:**
|
||||
- Standalone systems (Home/Workgroup)
|
||||
- Home/Personal PCs (not domain-joined)
|
||||
- Virtual machines (testing/lab environments)
|
||||
- Air-gapped systems
|
||||
- Test/development domain-joined systems (non-production)
|
||||
|
||||
**For Enterprise/Domain Environments:** Integrate these settings into your Domain Group Policies instead!
|
||||
**For Enterprise/Domain Environments:**
|
||||
- **Integrate these settings into your Domain Group Policies instead!**
|
||||
- Coordinate with your Active Directory team before using this tool
|
||||
|
||||
---
|
||||
|
||||
### 💾 System Backup REQUIRED
|
||||
|
||||
**Before running this tool, create:**
|
||||
**Before running this tool, you MUST create:**
|
||||
|
||||
1. **Windows System Restore Point** (recommended)
|
||||
2. **Full System Image/Backup** (critical!)
|
||||
3. **VM Snapshot** (if running in virtual machine)
|
||||
|
||||
The tool creates internal backups for rollback (BAVR pattern), but a full system backup protects against unforeseen issues, hardware failures, and configuration conflicts.
|
||||
**Why?**
|
||||
- This tool creates **internal backups** for rollback (Registry, Services, Tasks)
|
||||
- However, a **full system backup** protects against:
|
||||
- Unforeseen system issues
|
||||
- Hardware failures during hardening
|
||||
- Configuration conflicts
|
||||
- Critical errors
|
||||
|
||||
**Backup Tools:** Windows Backup, wbadmin, Macrium Reflect, Acronis, Hyper-V/VMware Snapshots.
|
||||
**Backup Tools:**
|
||||
- Windows Backup (Settings → System → Storage → Backup)
|
||||
- System Image (wbadmin, Macrium Reflect, Acronis)
|
||||
- Hyper-V/VMware: Checkpoint/Snapshot
|
||||
|
||||
</details>
|
||||
**⚠️ IMPORTANT: Create your backup BEFORE running the tool. The tool does NOT verify backup existence.**
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -245,8 +262,8 @@ The tool creates internal backups for rollback (BAVR pattern), but a full system
|
|||
- **Complete Restore** Registry, Services, Tasks, Files - everything
|
||||
- **Production-Ready** Tested on Windows 11 25H2, PowerShell 5.1+
|
||||
|
||||
**Before v2.1.0:** 89.4% verification coverage (62 settings missing)
|
||||
**Since v2.1.0:** 100% verification coverage (all 630+ settings verified)
|
||||
**Before v2.2.0:** 89.4% verification coverage (62 settings missing)
|
||||
**After v2.2.0:** 100% verification coverage (all 630+ settings verified)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -374,22 +391,25 @@ cd noid-privacy
|
|||
|
||||
| Module | Settings | Description | Status |
|
||||
|--------|----------|-------------|--------|
|
||||
| **SecurityBaseline** | 425 | Microsoft Security Baseline 25H2 | v2.2.4 |
|
||||
| **ASR** | 19 | Attack Surface Reduction Rules | v2.2.4 |
|
||||
| **DNS** | 5 | Secure DNS with DoH encryption | v2.2.4 |
|
||||
| **Privacy** | 78 | Telemetry, Bloatware, OneDrive hardening (Strict) | v2.2.4 |
|
||||
| **AntiAI** | 32 | AI lockdown (15 features, 32 compliance checks) | v2.2.4 |
|
||||
| **EdgeHardening** | 24 | Microsoft Edge security (24 policies) | v2.2.4 |
|
||||
| **AdvancedSecurity** | 50 | Beyond MS Baseline (SRP, Legacy protocols, Wireless Display, Discovery Protocols, IPv6) | v2.2.4 |
|
||||
| **SecurityBaseline** | 425 | Microsoft Security Baseline 25H2 | v2.2.2 |
|
||||
| **ASR** | 19 | Attack Surface Reduction Rules | v2.2.2 |
|
||||
| **DNS** | 5 | Secure DNS with DoH encryption | v2.2.2 |
|
||||
| **Privacy** | 78 | Telemetry, Bloatware, OneDrive hardening (Strict) | v2.2.2 |
|
||||
| **AntiAI** | 32 | AI lockdown (15 features, 32 compliance checks) | v2.2.2 |
|
||||
| **EdgeHardening** | 24 | Microsoft Edge security (24 policies) | v2.2.2 |
|
||||
| **AdvancedSecurity** | 50 | Beyond MS Baseline (SRP, Legacy protocols, Wireless Display, Discovery Protocols, IPv6) | v2.2.2 |
|
||||
| **TOTAL** | **633** | **Complete Framework (Paranoid mode)** | **Production** |
|
||||
|
||||
**Release Highlights:**
|
||||
|
||||
- **v2.2.4:** EDR/XDR detection — CrowdStrike, SentinelOne, Carbon Black + 15 more ([#15](https://github.com/NexusOne23/noid-privacy/issues/15))
|
||||
- **v2.2.3:** Restore Mode crash fix, Recall snapshot storage verification fix ([#14](https://github.com/NexusOne23/noid-privacy/issues/14))
|
||||
- **v2.2.2:** Firewall snapshot 60-120s → 2-5s (batch query performance fix)
|
||||
- **v2.2.1:** Multi-run session bug fix, `.Count` property bug in 5 files
|
||||
- **v2.2.0:** 100% verification coverage, SRP .lnk protection, RDP/TLS hardening, legacy protocol blocking
|
||||
- **v2.2.0:** 100% verification coverage (all 630+ settings verified)
|
||||
- **v2.2.0:** Improved Advanced Security module with SRP .lnk protection
|
||||
- **v2.2.0:** Enhanced RDP hardening with TLS + NLA enforced
|
||||
- **v2.2.0:** Legacy protocol blocking (SMBv1, NetBIOS, LLMNR, WPAD, PowerShell v2)
|
||||
- **v2.2.0:** TLS hardening (1.0/1.1 OFF, 1.2/1.3 ON)
|
||||
- **v2.2.0:** Windows Update interactive configuration
|
||||
- **v2.2.0:** Finger Protocol blocked (ClickFix malware protection)
|
||||
- **v2.2.0:** Enhanced Registry Backup (Smart JSON-Fallback for protected system keys)
|
||||
|
||||
📖 [Detailed Module Documentation](Docs/FEATURES.md)
|
||||
|
||||
|
|
@ -519,10 +539,10 @@ When a third-party antivirus is detected, you'll see a clear notification:
|
|||
ASR Module Skipped
|
||||
========================================
|
||||
|
||||
Third-party security product detected: Kaspersky Total Security
|
||||
Third-party antivirus detected: Kaspersky Total Security
|
||||
|
||||
ASR rules require Windows Defender as primary antivirus.
|
||||
Your security solution (Kaspersky Total Security) has its own protection features.
|
||||
ASR rules require Windows Defender to be active.
|
||||
Your antivirus (Kaspersky Total Security) has its own protection features.
|
||||
|
||||
This is NOT an error - ASR will be skipped.
|
||||
```
|
||||
|
|
@ -749,7 +769,7 @@ Logs/NoIDPrivacy_YYYYMMDD_HHMMSS.log
|
|||
- **[Features](Docs/FEATURES.md)** - Complete 630+ setting reference
|
||||
- **[Changelog](CHANGELOG.md)** - Version history
|
||||
- **[Quick Start](#-quick-start)** - Installation guide (see above)
|
||||
- **[Troubleshooting](#-troubleshooting)** - Common issues (see above)
|
||||
- **[Troubleshooting](#troubleshooting)** - Common issues (see above)
|
||||
|
||||
### 💬 Community
|
||||
|
||||
|
|
@ -767,17 +787,6 @@ Logs/NoIDPrivacy_YYYYMMDD_HHMMSS.log
|
|||
|
||||
---
|
||||
|
||||
## 🔗 The NoID Privacy Ecosystem
|
||||
|
||||
| Platform | Link |
|
||||
|----------|------|
|
||||
| 🌐 **Website** | [NoID-Privacy.com](https://noid-privacy.com) — All platforms, pricing, and documentation |
|
||||
| 🪟 **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 (free & open source) |
|
||||
| 📱 **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
|
||||
|
||||
### Dual-License Model
|
||||
|
|
@ -843,20 +852,10 @@ The authors are not responsible for any damage or data loss.
|
|||
|
||||
## 📈 Project Status
|
||||
|
||||
**Current Version:** 2.2.4
|
||||
**Current Version:** 2.2.2
|
||||
**Last Updated:** December 22, 2025
|
||||
**Status:** Production-Ready
|
||||
|
||||
### Release Highlights v2.2.4
|
||||
|
||||
- **Enhancement:** 3-layer detection for third-party security products (EDR/XDR + traditional AV)
|
||||
- **Enhancement:** ASR module gracefully skips when CrowdStrike, SentinelOne, etc. are primary ([#15](https://github.com/NexusOne23/noid-privacy/issues/15))
|
||||
- **Tooling:** `VERSION` file + `Bump-Version.ps1` for automated version management
|
||||
|
||||
### Release Highlights v2.2.3
|
||||
|
||||
- **Critical Fix:** Restore Mode manual module selection crash (`.Split()` → `-split`)
|
||||
- **Bug Fix:** Recall snapshot storage verification — MB vs GB unit mismatch ([#14](https://github.com/NexusOne23/noid-privacy/issues/14))
|
||||
|
||||
### Release Highlights v2.2.2
|
||||
|
||||
- **Performance:** Firewall snapshot 60-120s → 2-5s (batch query fix)
|
||||
|
|
@ -868,6 +867,15 @@ The authors are not responsible for any damage or data loss.
|
|||
- **Fix:** `.Count` property bug in 5 files (Where-Object single-object results)
|
||||
- **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)
|
||||
|
||||
---
|
||||
|
|
@ -876,9 +884,9 @@ The authors are not responsible for any damage or data loss.
|
|||
|
||||
**Made with 🛡️ for the Windows Security Community**
|
||||
|
||||
[Report Bug](https://github.com/NexusOne23/noid-privacy/issues) · [Request Feature](https://github.com/NexusOne23/noid-privacy/issues) · [Discussions](https://github.com/NexusOne23/noid-privacy/discussions) · [Website](https://noid-privacy.com)
|
||||
[Report Bug](https://github.com/NexusOne23/noid-privacy/issues) [Request Feature](https://github.com/NexusOne23/noid-privacy/issues) [Discussions](https://github.com/NexusOne23/noid-privacy/discussions)
|
||||
|
||||
**[⭐ Star this repo](https://github.com/NexusOne23/noid-privacy)** if you find it useful!
|
||||
**Star this repo** if you find it useful!
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -92,15 +92,9 @@ NoID Privacy implements multiple security layers:
|
|||
### Before Running
|
||||
1. ✅ **Verify Script Integrity**
|
||||
```powershell
|
||||
# Compare against CHECKSUMS.sha256 from GitHub Release
|
||||
# Check file hash (coming soon - SHA256 checksums in releases)
|
||||
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**
|
||||
- This is open-source - read the code!
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ REM This script launches NoIDPrivacy-Interactive.ps1 with
|
|||
REM Administrator privileges (auto-elevation).
|
||||
REM
|
||||
REM Author: NexusOne23
|
||||
REM Version: 2.2.4
|
||||
REM Version: 2.2.2
|
||||
REM ========================================
|
||||
|
||||
setlocal
|
||||
|
||||
title NoID Privacy v2.2.4
|
||||
title NoID Privacy v2.2.2
|
||||
|
||||
REM Get the directory where this batch file is located
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
|
|
@ -23,7 +23,7 @@ if %errorLevel% == 0 (
|
|||
REM Already admin, run PowerShell script directly
|
||||
echo Running NoID Privacy Interactive Menu with Administrator privileges...
|
||||
echo.
|
||||
"%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -NoProfile -File "%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1" %*
|
||||
powershell.exe -ExecutionPolicy Bypass -NoProfile -File "%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1" %*
|
||||
pause
|
||||
exit /b
|
||||
)
|
||||
|
|
@ -33,7 +33,7 @@ echo Requesting Administrator privileges...
|
|||
echo.
|
||||
|
||||
REM Use PowerShell to elevate and run the script
|
||||
"%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"
|
||||
powershell.exe -Command "Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -NoProfile -File \"%SCRIPT_DIR%NoIDPrivacy-Interactive.ps1\" %*' -Verb RunAs"
|
||||
|
||||
REM Exit this non-elevated instance
|
||||
exit /b
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+, Pester 5.0+
|
||||
|
||||
.EXAMPLE
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
|
||||
.EXAMPLE
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: Pester 5.0+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,160 +0,0 @@
|
|||
#Requires -Version 5.1
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Bump version number across all project files
|
||||
|
||||
.DESCRIPTION
|
||||
Reads the current version from the VERSION file, replaces it with the new
|
||||
version in all project files, and updates the VERSION file.
|
||||
|
||||
CHANGELOG.md is excluded because it contains historical version entries
|
||||
that must not be modified.
|
||||
|
||||
.PARAMETER NewVersion
|
||||
The new version number (e.g., "2.2.4")
|
||||
|
||||
.PARAMETER DryRun
|
||||
Preview changes without modifying any files
|
||||
|
||||
.EXAMPLE
|
||||
.\Bump-Version.ps1 -NewVersion "2.2.4"
|
||||
Bump all files from current version to 2.2.4
|
||||
|
||||
.EXAMPLE
|
||||
.\Bump-Version.ps1 -NewVersion "2.2.4" -DryRun
|
||||
Preview what would change without modifying files
|
||||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
The VERSION file at the project root is the single source of truth.
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidatePattern('^\d+\.\d+\.\d+$')]
|
||||
[string]$NewVersion,
|
||||
|
||||
[switch]$DryRun
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Resolve project root (one level up from Tools/)
|
||||
$projectRoot = Split-Path $PSScriptRoot -Parent
|
||||
$versionFile = Join-Path $projectRoot "VERSION"
|
||||
|
||||
# Read current version
|
||||
if (-not (Test-Path $versionFile)) {
|
||||
Write-Host "ERROR: VERSION file not found at: $versionFile" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$oldVersion = (Get-Content $versionFile -Raw).Trim()
|
||||
|
||||
if (-not ($oldVersion -match '^\d+\.\d+\.\d+$')) {
|
||||
Write-Host "ERROR: Invalid version in VERSION file: '$oldVersion'" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($oldVersion -eq $NewVersion) {
|
||||
Write-Host "ERROR: New version ($NewVersion) is identical to current version ($oldVersion)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# File extensions to process
|
||||
$extensions = @("*.ps1", "*.psm1", "*.psd1", "*.json", "*.md", "*.bat", "*.yml")
|
||||
|
||||
# Files to exclude (relative to project root)
|
||||
$excludedFiles = @("CHANGELOG.md")
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " NoID Privacy Version Bump" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host " Current version: $oldVersion" -ForegroundColor White
|
||||
Write-Host " New version: $NewVersion" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Host " [DRY RUN - No files will be modified]" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Collect all matching files
|
||||
$allFiles = @()
|
||||
foreach ($ext in $extensions) {
|
||||
$allFiles += Get-ChildItem -Path $projectRoot -Filter $ext -Recurse -File |
|
||||
Where-Object { $_.FullName -notmatch '[\\/]\.git[\\/]' }
|
||||
}
|
||||
|
||||
# Process files
|
||||
$changedFiles = 0
|
||||
$totalReplacements = 0
|
||||
|
||||
foreach ($file in $allFiles) {
|
||||
$relativePath = $file.FullName.Substring($projectRoot.Length + 1)
|
||||
|
||||
# Check exclusion list
|
||||
$isExcluded = $false
|
||||
foreach ($excluded in $excludedFiles) {
|
||||
if ($relativePath -eq $excluded) {
|
||||
$isExcluded = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($isExcluded) {
|
||||
Write-Host " [SKIP] $relativePath (excluded)" -ForegroundColor DarkGray
|
||||
continue
|
||||
}
|
||||
|
||||
# Read file content
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
|
||||
# Count occurrences
|
||||
$count = ([regex]::Matches($content, [regex]::Escape($oldVersion))).Count
|
||||
|
||||
if ($count -gt 0) {
|
||||
$changedFiles++
|
||||
$totalReplacements += $count
|
||||
|
||||
Write-Host " [BUMP] $relativePath ($count replacement$(if ($count -gt 1) {'s'}))" -ForegroundColor Green
|
||||
|
||||
if (-not $DryRun) {
|
||||
$newContent = $content.Replace($oldVersion, $NewVersion)
|
||||
[System.IO.File]::WriteAllText($file.FullName, $newContent, [System.Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Update VERSION file
|
||||
if (-not $DryRun) {
|
||||
[System.IO.File]::WriteAllText($versionFile, "$NewVersion`n", [System.Text.UTF8Encoding]::new($false))
|
||||
}
|
||||
|
||||
# Summary
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " Summary" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host " Files changed: $changedFiles" -ForegroundColor White
|
||||
Write-Host " Total replacements: $totalReplacements" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Host " DRY RUN complete. No files were modified." -ForegroundColor Yellow
|
||||
Write-Host " Run without -DryRun to apply changes." -ForegroundColor Yellow
|
||||
}
|
||||
else {
|
||||
Write-Host " Version bumped: $oldVersion -> $NewVersion" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host " Next steps:" -ForegroundColor White
|
||||
Write-Host " 1. Update CHANGELOG.md with new version section" -ForegroundColor Gray
|
||||
Write-Host " 2. Review changes: git diff" -ForegroundColor Gray
|
||||
Write-Host " 3. Commit: git add -A && git commit -m 'chore: bump version to $NewVersion'" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
<#
|
||||
.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.4"
|
||||
|
||||
.EXAMPLE
|
||||
.\Generate-ReleaseChecksums.ps1 -ReleasePath ".\NoIDPrivacy-v2.2.4.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
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
|
||||
.EXAMPLE
|
||||
|
|
@ -142,26 +142,21 @@ function Read-PolFile {
|
|||
|
||||
# Parse based on type
|
||||
switch ($type) {
|
||||
1 {
|
||||
# REG_SZ (String)
|
||||
1 { # REG_SZ (String)
|
||||
$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)
|
||||
}
|
||||
3 {
|
||||
# REG_BINARY
|
||||
3 { # REG_BINARY
|
||||
$data = $dataBytes
|
||||
}
|
||||
4 {
|
||||
# REG_DWORD
|
||||
4 { # REG_DWORD
|
||||
if ($dataBytes.Length -ge 4) {
|
||||
$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'
|
||||
}
|
||||
default {
|
||||
|
|
@ -177,9 +172,9 @@ function Read-PolFile {
|
|||
|
||||
# Add entry
|
||||
$entries += [PSCustomObject]@{
|
||||
KeyName = $keyName
|
||||
KeyName = $keyName
|
||||
ValueName = $valueName
|
||||
Type = switch ($type) {
|
||||
Type = switch ($type) {
|
||||
1 { "REG_SZ" }
|
||||
2 { "REG_EXPAND_SZ" }
|
||||
3 { "REG_BINARY" }
|
||||
|
|
@ -188,7 +183,7 @@ function Read-PolFile {
|
|||
11 { "REG_QWORD" }
|
||||
default { "Unknown($type)" }
|
||||
}
|
||||
Data = $data
|
||||
Data = $data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,9 +273,9 @@ if ($allComputerPolicies.Count -gt 0) {
|
|||
# Create summary
|
||||
$summary = [PSCustomObject]@{
|
||||
TotalEdgePolicies = $allComputerPolicies.Count
|
||||
ParsedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
BaselineVersion = "Edge v139"
|
||||
RegistryPaths = ($allComputerPolicies | Select-Object -ExpandProperty KeyName -Unique | Sort-Object)
|
||||
ParsedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
BaselineVersion = "Edge v139"
|
||||
RegistryPaths = ($allComputerPolicies | Select-Object -ExpandProperty KeyName -Unique | Sort-Object)
|
||||
}
|
||||
|
||||
$summaryFile = Join-Path $OutputPath "Summary.json"
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
|
||||
.EXAMPLE
|
||||
|
|
@ -150,26 +150,21 @@ function Read-PolFile {
|
|||
|
||||
# Parse based on type
|
||||
switch ($type) {
|
||||
1 {
|
||||
# REG_SZ (String)
|
||||
1 { # REG_SZ (String)
|
||||
$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)
|
||||
}
|
||||
3 {
|
||||
# REG_BINARY
|
||||
3 { # REG_BINARY
|
||||
$data = $dataBytes
|
||||
}
|
||||
4 {
|
||||
# REG_DWORD
|
||||
4 { # REG_DWORD
|
||||
if ($dataBytes.Length -ge 4) {
|
||||
$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'
|
||||
}
|
||||
default {
|
||||
|
|
@ -185,9 +180,9 @@ function Read-PolFile {
|
|||
|
||||
# Add entry
|
||||
$entries += [PSCustomObject]@{
|
||||
KeyName = $keyName
|
||||
KeyName = $keyName
|
||||
ValueName = $valueName
|
||||
Type = switch ($type) {
|
||||
Type = switch ($type) {
|
||||
1 { "REG_SZ" }
|
||||
2 { "REG_EXPAND_SZ" }
|
||||
3 { "REG_BINARY" }
|
||||
|
|
@ -196,7 +191,7 @@ function Read-PolFile {
|
|||
11 { "REG_QWORD" }
|
||||
default { "Unknown($type)" }
|
||||
}
|
||||
Data = $data
|
||||
Data = $data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -301,10 +296,10 @@ function Read-AuditCsv {
|
|||
# Skip header row
|
||||
$policies = $csv | Select-Object -Skip 1 | ForEach-Object {
|
||||
[PSCustomObject]@{
|
||||
Subcategory = $_.'Subcategory'
|
||||
SubcategoryGUID = $_.'Subcategory GUID'
|
||||
Subcategory = $_.'Subcategory'
|
||||
SubcategoryGUID = $_.'Subcategory GUID'
|
||||
InclusionSetting = $_.'Inclusion Setting'
|
||||
SettingValue = $_.'Setting Value'
|
||||
SettingValue = $_.'Setting Value'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,17 +346,17 @@ $gpoMapping = @{
|
|||
$gpoPath = Join-Path $BaselinePath "GPOs"
|
||||
|
||||
$allSettings = @{
|
||||
RegistryPolicies = @{
|
||||
RegistryPolicies = @{
|
||||
Computer = @()
|
||||
User = @()
|
||||
User = @()
|
||||
}
|
||||
SecurityTemplates = @{}
|
||||
AuditPolicies = @()
|
||||
Summary = @{
|
||||
AuditPolicies = @()
|
||||
Summary = @{
|
||||
TotalRegistrySettings = 0
|
||||
TotalSecuritySettings = 0
|
||||
TotalAuditPolicies = 0
|
||||
TotalSettings = 0
|
||||
TotalAuditPolicies = 0
|
||||
TotalSettings = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -386,11 +381,11 @@ foreach ($guid in $gpoMapping.Keys) {
|
|||
|
||||
foreach ($entry in $entries) {
|
||||
$allSettings.RegistryPolicies.Computer += [PSCustomObject]@{
|
||||
GPO = $gpoName
|
||||
KeyName = $entry.KeyName
|
||||
GPO = $gpoName
|
||||
KeyName = $entry.KeyName
|
||||
ValueName = $entry.ValueName
|
||||
Type = $entry.Type
|
||||
Data = $entry.Data
|
||||
Type = $entry.Type
|
||||
Data = $entry.Data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,11 +401,11 @@ foreach ($guid in $gpoMapping.Keys) {
|
|||
|
||||
foreach ($entry in $entries) {
|
||||
$allSettings.RegistryPolicies.User += [PSCustomObject]@{
|
||||
GPO = $gpoName
|
||||
KeyName = $entry.KeyName
|
||||
GPO = $gpoName
|
||||
KeyName = $entry.KeyName
|
||||
ValueName = $entry.ValueName
|
||||
Type = $entry.Type
|
||||
Data = $entry.Data
|
||||
Type = $entry.Type
|
||||
Data = $entry.Data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -440,11 +435,11 @@ foreach ($guid in $gpoMapping.Keys) {
|
|||
|
||||
foreach ($policy in $policies) {
|
||||
$allSettings.AuditPolicies += [PSCustomObject]@{
|
||||
GPO = $gpoName
|
||||
Subcategory = $policy.Subcategory
|
||||
SubcategoryGUID = $policy.SubcategoryGUID
|
||||
GPO = $gpoName
|
||||
Subcategory = $policy.Subcategory
|
||||
SubcategoryGUID = $policy.SubcategoryGUID
|
||||
InclusionSetting = $policy.InclusionSetting
|
||||
SettingValue = $policy.SettingValue
|
||||
SettingValue = $policy.SettingValue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -457,8 +452,8 @@ foreach ($guid in $gpoMapping.Keys) {
|
|||
|
||||
# Calculate total
|
||||
$allSettings.Summary.TotalSettings = $allSettings.Summary.TotalRegistrySettings +
|
||||
$allSettings.Summary.TotalSecuritySettings +
|
||||
$allSettings.Summary.TotalAuditPolicies
|
||||
$allSettings.Summary.TotalSecuritySettings +
|
||||
$allSettings.Summary.TotalAuditPolicies
|
||||
|
||||
# Save outputs
|
||||
Write-Host "Saving parsed settings..." -ForegroundColor Cyan
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
#>
|
||||
|
||||
#Requires -Version 5.1
|
||||
|
|
@ -130,10 +130,10 @@ function Get-RegistryChecksFromJson {
|
|||
# Skip metadata and excluded categories
|
||||
# NOTE: EnterpriseProtection is NOT skipped - it contains valid registry paths!
|
||||
if ($propName -in @('Mode', 'Description', 'BestFor', 'Warnings', 'Services', 'ScheduledTasks',
|
||||
'Summary', 'AutomaticallyBlockedByMasterSwitch', 'ModuleName', 'Version',
|
||||
'TotalFeatures', 'TotalPolicies', 'URIHandlers', 'Note', 'FilePath',
|
||||
'HostsEntries', 'CloudBased', 'RequiresReboot',
|
||||
'RequiresADMX', 'Impact', 'Name')) {
|
||||
'Summary', 'AutomaticallyBlockedByMasterSwitch', 'ModuleName', 'Version',
|
||||
'TotalFeatures', 'TotalPolicies', 'URIHandlers', 'Note', 'FilePath',
|
||||
'HostsEntries', 'CloudBased', 'RequiresReboot',
|
||||
'RequiresADMX', 'Impact', 'Name')) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -913,99 +913,36 @@ catch {
|
|||
Write-Host "[4/$totalSteps] Verifying ASR Rules (19)..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Check if Windows Defender is active or if third-party security product is managing protection
|
||||
# Uses 3-layer detection: SecurityCenter2 (traditional AV) + Passive Mode (EDR/XDR) + Known Services
|
||||
$securityProduct = [PSCustomObject]@{
|
||||
Detected = $false
|
||||
ProductName = $null
|
||||
DetectionMethod = $null
|
||||
DefenderPassiveMode = $false
|
||||
}
|
||||
# Check if Windows Defender is active or if third-party AV is managing security
|
||||
$thirdPartyAV = $null
|
||||
$defenderManaged = $true
|
||||
|
||||
# Layer 1: WMI SecurityCenter2 (traditional AV: Bitdefender, Kaspersky, Avira, Norton, etc.)
|
||||
try {
|
||||
# Check for third-party AV products
|
||||
$avProducts = Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName "AntiVirusProduct" -ErrorAction SilentlyContinue
|
||||
$thirdPartyAV = $avProducts | Where-Object { $_.displayName -notmatch "Windows Defender|Microsoft Defender" } | Select-Object -First 1
|
||||
|
||||
if ($thirdPartyAV) {
|
||||
$securityProduct.Detected = $true
|
||||
$securityProduct.ProductName = $thirdPartyAV.displayName
|
||||
$securityProduct.DetectionMethod = "SecurityCenter2"
|
||||
# Try to access Defender - if it fails, third-party AV is managing
|
||||
try {
|
||||
$null = Get-MpPreference -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$defenderManaged = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$null = $null # SecurityCenter2 not available - continue to Layer 2
|
||||
# SecurityCenter2 not available - assume Defender is active
|
||||
$null = $null # Intentionally empty - suppress PSScriptAnalyzer warning
|
||||
}
|
||||
|
||||
# Layer 2: Defender Passive Mode (EDR/XDR: CrowdStrike Falcon, SentinelOne, Carbon Black, etc.)
|
||||
if (-not $securityProduct.Detected) {
|
||||
try {
|
||||
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
|
||||
if ($defenderStatus -and $defenderStatus.AMRunningMode -eq "Passive Mode") {
|
||||
$securityProduct.Detected = $true
|
||||
$securityProduct.DefenderPassiveMode = $true
|
||||
$securityProduct.DetectionMethod = "PassiveMode"
|
||||
# If third-party AV is managing ASR (Defender unavailable)
|
||||
if (-not $defenderManaged -and $thirdPartyAV) {
|
||||
Write-Host " Third-party AV detected: $($thirdPartyAV.displayName)" -ForegroundColor Cyan
|
||||
Write-Host " ASR rules are managed by your antivirus solution" -ForegroundColor Green
|
||||
|
||||
# Layer 3: Known EDR service names for display name
|
||||
$edrServices = @(
|
||||
@{ Name = "CSFalconService"; Display = "CrowdStrike Falcon" },
|
||||
@{ Name = "SentinelAgent"; Display = "SentinelOne" },
|
||||
@{ Name = "CbDefense"; Display = "Carbon Black Cloud" },
|
||||
@{ Name = "CylanceSvc"; Display = "Cylance/Arctic Wolf Aurora" },
|
||||
@{ Name = "xagt"; Display = "Trellix Endpoint Security (HX)" },
|
||||
@{ Name = "masvc"; Display = "Trellix Agent" },
|
||||
@{ Name = "mfeatp"; Display = "Trellix Adaptive Threat Protection" },
|
||||
@{ Name = "cyserver"; Display = "Palo Alto Cortex XDR" },
|
||||
@{ Name = "EPSecurityService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "EPIntegrationService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "avp"; Display = "Kaspersky Endpoint Security" },
|
||||
@{ Name = "klnagent"; Display = "Kaspersky Security Center Agent" },
|
||||
@{ Name = "SEPAgent"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "SepMasterService"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "ekrn"; Display = "ESET Endpoint Security" },
|
||||
@{ Name = "EraAgentSvc"; Display = "ESET PROTECT Agent" },
|
||||
@{ Name = "Sophos MCS Agent"; Display = "Sophos Endpoint" },
|
||||
@{ Name = "HitmanPro.Alert"; Display = "Sophos Endpoint" }
|
||||
)
|
||||
|
||||
foreach ($edr in $edrServices) {
|
||||
$svc = Get-Service -Name $edr.Name -ErrorAction SilentlyContinue
|
||||
if ($svc -and $svc.Status -eq "Running") {
|
||||
$securityProduct.ProductName = $edr.Display
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $securityProduct.ProductName) {
|
||||
$securityProduct.ProductName = "Unknown Security Product (Defender in Passive Mode)"
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$null = $null # Get-MpComputerStatus not available
|
||||
}
|
||||
}
|
||||
|
||||
# Also check: Defender not running at all + no product detected via SecurityCenter2
|
||||
# but product may still be present (fallback for edge cases)
|
||||
if (-not $securityProduct.Detected) {
|
||||
try {
|
||||
$null = Get-MpPreference -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
# Get-MpPreference failed = Defender is not functional
|
||||
# This means something else is managing AV, even if we can't identify it
|
||||
$securityProduct.Detected = $true
|
||||
$securityProduct.ProductName = "Unknown Security Product (Defender unavailable)"
|
||||
$securityProduct.DetectionMethod = "DefenderUnavailable"
|
||||
}
|
||||
}
|
||||
|
||||
# If third-party security product detected - count ASR as verified (product handles protection)
|
||||
if ($securityProduct.Detected) {
|
||||
Write-Host " Third-party security product detected: $($securityProduct.ProductName)" -ForegroundColor Cyan
|
||||
Write-Host " ASR rules are managed by your security solution" -ForegroundColor Green
|
||||
|
||||
# Count all ASR rules as verified (security product is handling protection)
|
||||
# Count all ASR rules as verified (AV is handling protection)
|
||||
$results.Verified += $EXPECTED_ASR_COUNT
|
||||
|
||||
$results.AllSettings += [PSCustomObject]@{
|
||||
|
|
@ -1013,11 +950,11 @@ try {
|
|||
Total = $EXPECTED_ASR_COUNT
|
||||
Passed = $EXPECTED_ASR_COUNT
|
||||
Failed = 0
|
||||
PassedDetails = @([PSCustomObject]@{ Rule = "All rules"; Expected = "Managed by $($securityProduct.ProductName)"; Actual = "Protected" })
|
||||
PassedDetails = @([PSCustomObject]@{ Rule = "All rules"; Expected = "Managed by $($thirdPartyAV.displayName)"; Actual = "Protected" })
|
||||
FailedDetails = @()
|
||||
}
|
||||
|
||||
Write-Host " ASR: $EXPECTED_ASR_COUNT/$EXPECTED_ASR_COUNT verified (Third-Party Security)" -ForegroundColor Green
|
||||
Write-Host " ASR: $EXPECTED_ASR_COUNT/$EXPECTED_ASR_COUNT verified (Third-Party AV)" -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
# Defender is active - verify ASR rules normally
|
||||
|
|
@ -1025,16 +962,78 @@ try {
|
|||
$currentASRIds = $mpPreference.AttackSurfaceReductionRules_Ids
|
||||
$currentASRActions = $mpPreference.AttackSurfaceReductionRules_Actions
|
||||
|
||||
# Load expected ASR rules - JSON is array directly
|
||||
$asrRules = Get-Content (Join-Path $asrConfigPath "ASR-Rules.json") -Raw | ConvertFrom-Json
|
||||
# Load expected ASR rules - JSON is array directly
|
||||
$asrRules = Get-Content (Join-Path $asrConfigPath "ASR-Rules.json") -Raw | ConvertFrom-Json
|
||||
|
||||
$asrFailed = @()
|
||||
$asrPassed = @()
|
||||
$asrFailed = @()
|
||||
$asrPassed = @()
|
||||
|
||||
# Check if ASR rules are configured at all
|
||||
if ($null -eq $currentASRIds -or $currentASRIds.Count -eq 0) {
|
||||
# No ASR rules configured - mark all as failed
|
||||
foreach ($rule in $asrRules) {
|
||||
# Check if ASR rules are configured at all
|
||||
if ($null -eq $currentASRIds -or $currentASRIds.Count -eq 0) {
|
||||
# No ASR rules configured - mark all as failed
|
||||
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++
|
||||
$expectedActionText = if ($rule.Action -eq 1) { "Block" } elseif ($rule.Action -eq 2) { "Audit" } else { "Disabled" }
|
||||
$asrFailed += [PSCustomObject]@{
|
||||
|
|
@ -1045,90 +1044,28 @@ 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)
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
# 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 ($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++
|
||||
$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"
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($asrFailed.Count -gt 0) {
|
||||
$results.FailedSettings += [PSCustomObject]@{
|
||||
Category = "ASR"
|
||||
Count = $asrFailed.Count
|
||||
Details = $asrFailed
|
||||
}
|
||||
}
|
||||
|
||||
# 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" })
|
||||
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)
|
||||
}
|
||||
catch {
|
||||
|
|
@ -1366,8 +1303,8 @@ try {
|
|||
if ($entry.ServerAddresses -and $entry.ServerAddresses.Count -gt 0) {
|
||||
# Check if it's not DHCP (empty or localhost fallback)
|
||||
$isDHCP = ($entry.ServerAddresses.Count -eq 0) -or
|
||||
($entry.ServerAddresses -contains '127.0.0.1') -or
|
||||
($entry.AddressOrigin -eq 'DHCP')
|
||||
($entry.ServerAddresses -contains '127.0.0.1') -or
|
||||
($entry.AddressOrigin -eq 'DHCP')
|
||||
|
||||
if (-not $isDHCP) {
|
||||
$staticDNS = $true
|
||||
|
|
@ -1859,10 +1796,10 @@ try {
|
|||
# We validate both Enabled=0 and DisabledByDefault=1 per version/component
|
||||
$tlsChecks = @(
|
||||
# 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\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\Client"; Name = "Enabled"; Expected = 0; Desc = "TLS 1.1 Client 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.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 }
|
||||
# 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\Client"; Name = "DisabledByDefault"; Expected = 1; Desc = "TLS 1.0 Client DisabledByDefault"; Optional = $false }
|
||||
|
|
@ -1875,24 +1812,24 @@ try {
|
|||
# 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
|
||||
$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\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\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"; Name = "AutoDetect"; Expected = 0; Desc = "WPAD AutoDetect (HKLM)"; Optional = $false }
|
||||
)
|
||||
|
||||
# SRP Root Policy (2 checks) - ALWAYS required for CVE-2025-9491 mitigation
|
||||
$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 = "TransparentEnabled"; Expected = 1; Desc = "SRP TransparentEnabled"; 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 }
|
||||
)
|
||||
|
||||
# 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)
|
||||
$shieldsUpCheck = @{
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile"
|
||||
Name = "DoNotAllowExceptions"
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile"
|
||||
Name = "DoNotAllowExceptions"
|
||||
Expected = 1
|
||||
Desc = "Firewall Shields Up (Maximum only)"
|
||||
Desc = "Firewall Shields Up (Maximum only)"
|
||||
Optional = $true
|
||||
}
|
||||
|
||||
|
|
@ -1900,10 +1837,10 @@ try {
|
|||
# Optional = true because only applied for Maximum profile (user choice)
|
||||
# Check 1: mDNS disabled via registry
|
||||
$discoveryMdnsCheck = @{
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
|
||||
Name = "EnableMDNS"
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
|
||||
Name = "EnableMDNS"
|
||||
Expected = 0
|
||||
Desc = "Discovery Protocols: mDNS Disabled (Maximum only)"
|
||||
Desc = "Discovery Protocols: mDNS Disabled (Maximum only)"
|
||||
Optional = $true
|
||||
}
|
||||
|
||||
|
|
@ -1913,10 +1850,10 @@ try {
|
|||
# IPv6 Disable (mitm6 attack mitigation) - Maximum profile only
|
||||
# Optional = true because only applied for Maximum profile (user choice)
|
||||
$ipv6Check = @{
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
|
||||
Name = "DisabledComponents"
|
||||
Path = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
|
||||
Name = "DisabledComponents"
|
||||
Expected = 255 # 0xFF = completely disabled
|
||||
Desc = "IPv6 Disabled (mitm6 mitigation, Maximum only)"
|
||||
Desc = "IPv6 Disabled (mitm6 mitigation, Maximum only)"
|
||||
Optional = $true
|
||||
}
|
||||
|
||||
|
|
@ -1951,10 +1888,10 @@ try {
|
|||
|
||||
# Windows Update (4 Checks) - ALWAYS required - matches AdvancedSecurity module Config/WindowsUpdate.json
|
||||
$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 = "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\Policies\Microsoft\Windows\DeliveryOptimization"; Name = "DODownloadMode"; Expected = 0; Desc = "WU: P2P Delivery Optimization OFF"; 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\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 }
|
||||
)
|
||||
|
||||
# Finger Protocol (1 check) - verify outbound firewall rule created by AdvancedSecurity
|
||||
|
|
@ -1974,8 +1911,7 @@ try {
|
|||
else {
|
||||
$actualDesc = if ($portFilter) {
|
||||
"Protocol=$($portFilter.Protocol), RemotePort=$($portFilter.RemotePort)"
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
"No port filter"
|
||||
}
|
||||
}
|
||||
|
|
@ -2114,8 +2050,8 @@ try {
|
|||
|
||||
$hkuPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings"
|
||||
$userSIDs = Get-ChildItem -Path "HKU:\" -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.PSChildName -match '^S-1-5-21-' -and $_.PSChildName -notmatch '_Classes$' } |
|
||||
Select-Object -ExpandProperty PSChildName
|
||||
Where-Object { $_.PSChildName -match '^S-1-5-21-' -and $_.PSChildName -notmatch '_Classes$' } |
|
||||
Select-Object -ExpandProperty PSChildName
|
||||
|
||||
$hkuCompliant = $true
|
||||
$hkuActualValue = "All users compliant"
|
||||
|
|
@ -2286,10 +2222,10 @@ try {
|
|||
|
||||
$totalAdapters = $adapters.Count
|
||||
$disabledCount = 0
|
||||
$nonCompliant = @()
|
||||
$nonCompliant = @()
|
||||
|
||||
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) {
|
||||
$disabledCount++
|
||||
}
|
||||
|
|
@ -2609,7 +2545,7 @@ catch {
|
|||
# drift from per-category counters in case some success paths didn't
|
||||
# manually increment $results.Verified.
|
||||
$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
|
||||
|
||||
|
|
@ -3055,8 +2991,8 @@ try {
|
|||
}
|
||||
|
||||
.module-content {
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
max-height: 5000px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
}
|
||||
|
||||
|
|
@ -3204,70 +3140,6 @@ try {
|
|||
.controls, .export-section {
|
||||
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 {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
|
@ -3308,7 +3180,7 @@ try {
|
|||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>NoID Privacy v2.2.4</h1>
|
||||
<h1>NoID Privacy v2.2.2</h1>
|
||||
<p class="subtitle">Complete Hardening Compliance Report</p>
|
||||
<span class="badge">All $totalSettings Settings Verified</span>
|
||||
</div>
|
||||
|
|
@ -3328,7 +3200,7 @@ try {
|
|||
</div>
|
||||
<div class="meta-item">
|
||||
<span class="meta-label">Framework Version</span>
|
||||
<span class="meta-value">NoID Privacy v2.2.4</span>
|
||||
<span class="meta-value">NoID Privacy v2.2.2</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -3487,11 +3359,11 @@ try {
|
|||
$friendlyName = $zoneSettingNames[$settingName]
|
||||
if ($friendlyName) {
|
||||
$zoneName = if ($pathInfo -like "*Zones\\0*") { "My Computer" }
|
||||
elseif ($pathInfo -like "*Zones\\1*") { "Local Intranet" }
|
||||
elseif ($pathInfo -like "*Zones\\2*") { "Trusted Sites" }
|
||||
elseif ($pathInfo -like "*Zones\\3*") { "Internet" }
|
||||
elseif ($pathInfo -like "*Zones\\4*") { "Restricted Sites" }
|
||||
else { "Zone" }
|
||||
elseif ($pathInfo -like "*Zones\\1*") { "Local Intranet" }
|
||||
elseif ($pathInfo -like "*Zones\\2*") { "Trusted Sites" }
|
||||
elseif ($pathInfo -like "*Zones\\3*") { "Internet" }
|
||||
elseif ($pathInfo -like "*Zones\\4*") { "Restricted Sites" }
|
||||
else { "Zone" }
|
||||
$settingName = "[$zoneName] $friendlyName"
|
||||
}
|
||||
}
|
||||
|
|
@ -3504,14 +3376,14 @@ try {
|
|||
elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") {
|
||||
# IE FeatureControl settings
|
||||
$featureNames = @{
|
||||
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
|
||||
"FEATURE_MIME_HANDLING" = "MIME Handling Security"
|
||||
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
|
||||
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
|
||||
"FEATURE_MIME_HANDLING" = "MIME Handling Security"
|
||||
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
|
||||
"FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install"
|
||||
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
|
||||
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
|
||||
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
|
||||
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
|
||||
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
|
||||
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
|
||||
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
|
||||
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
|
||||
}
|
||||
$processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" }
|
||||
foreach ($feature in $featureNames.Keys) {
|
||||
|
|
@ -3649,11 +3521,11 @@ try {
|
|||
$friendlyName = $zoneSettingNames[$settingName]
|
||||
if ($friendlyName) {
|
||||
$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\\2*" -or $pathInfo -like "*Zones\2*") { "Trusted Sites" }
|
||||
elseif ($pathInfo -like "*Zones\\3*" -or $pathInfo -like "*Zones\3*") { "Internet" }
|
||||
elseif ($pathInfo -like "*Zones\\4*" -or $pathInfo -like "*Zones\4*") { "Restricted Sites" }
|
||||
else { "Zone" }
|
||||
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\\3*" -or $pathInfo -like "*Zones\3*") { "Internet" }
|
||||
elseif ($pathInfo -like "*Zones\\4*" -or $pathInfo -like "*Zones\4*") { "Restricted Sites" }
|
||||
else { "Zone" }
|
||||
$settingName = "[$zoneName] $friendlyName"
|
||||
}
|
||||
}
|
||||
|
|
@ -3666,14 +3538,14 @@ try {
|
|||
elseif (($settingName -eq "iexplore.exe" -or $settingName -eq "explorer.exe") -and $pathInfo -like "*FeatureControl*") {
|
||||
# IE FeatureControl settings
|
||||
$featureNames = @{
|
||||
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
|
||||
"FEATURE_MIME_HANDLING" = "MIME Handling Security"
|
||||
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
|
||||
"FEATURE_DISABLE_MK_PROTOCOL" = "Disable MK Protocol (Security)"
|
||||
"FEATURE_MIME_HANDLING" = "MIME Handling Security"
|
||||
"FEATURE_MIME_SNIFFING" = "MIME Sniffing Protection"
|
||||
"FEATURE_RESTRICT_ACTIVEXINSTALL" = "Restrict ActiveX Install"
|
||||
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
|
||||
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
|
||||
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
|
||||
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
|
||||
"FEATURE_RESTRICT_FILEDOWNLOAD" = "Restrict File Download"
|
||||
"FEATURE_SECURITYBAND" = "Security Band (Info Bar)"
|
||||
"FEATURE_WINDOW_RESTRICTIONS" = "Window Restrictions (Pop-up Block)"
|
||||
"FEATURE_ZONE_ELEVATION" = "Zone Elevation Block"
|
||||
}
|
||||
$processName = if ($settingName -eq "iexplore.exe") { "IE" } else { "Explorer" }
|
||||
foreach ($feature in $featureNames.Keys) {
|
||||
|
|
@ -3770,7 +3642,7 @@ try {
|
|||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>Generated by NoID Privacy v2.2.4</p>
|
||||
<p>Generated by NoID Privacy v2.2.2</p>
|
||||
<p>Professional Windows 11 Security & Privacy Hardening Framework</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -55,9 +55,9 @@ function Test-SecEditAvailable {
|
|||
|
||||
$result = [PSCustomObject]@{
|
||||
Available = $false
|
||||
Path = $null
|
||||
Version = $null
|
||||
Error = $null
|
||||
Path = $null
|
||||
Version = $null
|
||||
Error = $null
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -105,9 +105,9 @@ function Test-AuditPolAvailable {
|
|||
|
||||
$result = [PSCustomObject]@{
|
||||
Available = $false
|
||||
Path = $null
|
||||
Version = $null
|
||||
Error = $null
|
||||
Path = $null
|
||||
Version = $null
|
||||
Error = $null
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -138,124 +138,13 @@ function Test-AuditPolAvailable {
|
|||
return $result
|
||||
}
|
||||
|
||||
function Test-ThirdPartySecurityProduct {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Detect third-party antivirus or EDR/XDR products
|
||||
|
||||
.DESCRIPTION
|
||||
Unified detection function used by ASR module and Verify script.
|
||||
Uses a 3-layer approach:
|
||||
|
||||
Layer 1: WMI SecurityCenter2 (catches traditional AV: Bitdefender, Kaspersky, Avira, Norton, ESET, etc.)
|
||||
Layer 2: Defender Passive Mode via Get-MpComputerStatus (catches EDR/XDR: CrowdStrike, SentinelOne, etc.)
|
||||
Layer 3: Known EDR service names (provides display name for Layer 2 detections)
|
||||
|
||||
.OUTPUTS
|
||||
PSCustomObject with:
|
||||
- Detected: Boolean - True if third-party product found
|
||||
- ProductName: String - Name of detected product
|
||||
- DetectionMethod: String - How it was detected (SecurityCenter2, PassiveMode, Service)
|
||||
- DefenderPassiveMode: Boolean - True if Defender is in passive mode
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
[OutputType([PSCustomObject])]
|
||||
param()
|
||||
|
||||
$result = [PSCustomObject]@{
|
||||
Detected = $false
|
||||
ProductName = $null
|
||||
DetectionMethod = $null
|
||||
DefenderPassiveMode = $false
|
||||
}
|
||||
|
||||
# Layer 1: WMI SecurityCenter2 (traditional AV products)
|
||||
try {
|
||||
$avProducts = Get-CimInstance -Namespace "root/SecurityCenter2" -ClassName "AntiVirusProduct" -ErrorAction SilentlyContinue
|
||||
$thirdPartyAV = $avProducts | Where-Object { $_.displayName -notmatch "Windows Defender|Microsoft Defender" } | Select-Object -First 1
|
||||
|
||||
if ($thirdPartyAV) {
|
||||
$result.Detected = $true
|
||||
$result.ProductName = $thirdPartyAV.displayName
|
||||
$result.DetectionMethod = "SecurityCenter2"
|
||||
|
||||
# Also check passive mode for complete info
|
||||
try {
|
||||
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
|
||||
if ($defenderStatus -and $defenderStatus.AMRunningMode -eq "Passive Mode") {
|
||||
$result.DefenderPassiveMode = $true
|
||||
}
|
||||
}
|
||||
catch { $null = $null }
|
||||
|
||||
return $result
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# SecurityCenter2 not available (e.g., Server OS) - continue to Layer 2
|
||||
$null = $null
|
||||
}
|
||||
|
||||
# Layer 2: Defender Passive Mode detection (catches EDR/XDR like CrowdStrike, SentinelOne, etc.)
|
||||
try {
|
||||
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
|
||||
if ($defenderStatus -and $defenderStatus.AMRunningMode -eq "Passive Mode") {
|
||||
$result.Detected = $true
|
||||
$result.DefenderPassiveMode = $true
|
||||
$result.DetectionMethod = "PassiveMode"
|
||||
|
||||
# Layer 3: Try to identify the specific EDR/XDR product by service name
|
||||
$edrServices = @(
|
||||
@{ Name = "CSFalconService"; Display = "CrowdStrike Falcon" },
|
||||
@{ Name = "SentinelAgent"; Display = "SentinelOne" },
|
||||
@{ Name = "CbDefense"; Display = "Carbon Black Cloud" },
|
||||
@{ Name = "CylanceSvc"; Display = "Cylance/Arctic Wolf Aurora" },
|
||||
@{ Name = "xagt"; Display = "Trellix Endpoint Security (HX)" },
|
||||
@{ Name = "masvc"; Display = "Trellix Agent" },
|
||||
@{ Name = "mfeatp"; Display = "Trellix Adaptive Threat Protection" },
|
||||
@{ Name = "cyserver"; Display = "Palo Alto Cortex XDR" },
|
||||
@{ Name = "EPSecurityService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "EPIntegrationService"; Display = "Bitdefender GravityZone" },
|
||||
@{ Name = "avp"; Display = "Kaspersky Endpoint Security" },
|
||||
@{ Name = "klnagent"; Display = "Kaspersky Security Center Agent" },
|
||||
@{ Name = "SEPAgent"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "SepMasterService"; Display = "Broadcom/Symantec Endpoint Protection" },
|
||||
@{ Name = "ekrn"; Display = "ESET Endpoint Security" },
|
||||
@{ Name = "EraAgentSvc"; Display = "ESET PROTECT Agent" },
|
||||
@{ Name = "Sophos MCS Agent"; Display = "Sophos Endpoint" },
|
||||
@{ Name = "HitmanPro.Alert"; Display = "Sophos Endpoint" }
|
||||
)
|
||||
|
||||
foreach ($edr in $edrServices) {
|
||||
$svc = Get-Service -Name $edr.Name -ErrorAction SilentlyContinue
|
||||
if ($svc -and $svc.Status -eq "Running") {
|
||||
$result.ProductName = $edr.Display
|
||||
$result.DetectionMethod = "PassiveMode+Service"
|
||||
return $result
|
||||
}
|
||||
}
|
||||
|
||||
# No known service found but Defender IS in passive mode = unknown product
|
||||
$result.ProductName = "Unknown Security Product (Defender in Passive Mode)"
|
||||
return $result
|
||||
}
|
||||
}
|
||||
catch {
|
||||
# Get-MpComputerStatus failed - Defender may not be available at all
|
||||
$null = $null
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
function Test-WindowsDefenderAvailable {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Check if Windows Defender is available and running as primary AV
|
||||
Check if Windows Defender is available and running
|
||||
|
||||
.DESCRIPTION
|
||||
Verifies Windows Defender service status (required for ASR module).
|
||||
Now also detects Passive Mode where Defender is running but not primary.
|
||||
Verifies Windows Defender service status (required for ASR module)
|
||||
|
||||
.OUTPUTS
|
||||
PSCustomObject with availability status
|
||||
|
|
@ -265,11 +154,10 @@ function Test-WindowsDefenderAvailable {
|
|||
param()
|
||||
|
||||
$result = [PSCustomObject]@{
|
||||
Available = $false
|
||||
Available = $false
|
||||
ServiceRunning = $false
|
||||
IsPassiveMode = $false
|
||||
ServiceName = "WinDefend"
|
||||
Error = $null
|
||||
ServiceName = "WinDefend"
|
||||
Error = $null
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -282,17 +170,6 @@ function Test-WindowsDefenderAvailable {
|
|||
if (-not $result.ServiceRunning) {
|
||||
$result.Error = "Windows Defender service exists but is not running (Status: $($defenderService.Status))"
|
||||
}
|
||||
else {
|
||||
# Check if Defender is in Passive Mode (another AV is primary)
|
||||
try {
|
||||
$defenderStatus = Get-MpComputerStatus -ErrorAction SilentlyContinue
|
||||
if ($defenderStatus -and $defenderStatus.AMRunningMode -eq "Passive Mode") {
|
||||
$result.IsPassiveMode = $true
|
||||
$result.Error = "Windows Defender is running in Passive Mode (third-party security product is primary)"
|
||||
}
|
||||
}
|
||||
catch { $null = $null }
|
||||
}
|
||||
}
|
||||
else {
|
||||
$result.Error = "Windows Defender service (WinDefend) not found"
|
||||
|
|
@ -321,16 +198,16 @@ function Test-AllDependencies {
|
|||
param()
|
||||
|
||||
$result = [PSCustomObject]@{
|
||||
AllAvailable = $true
|
||||
AllAvailable = $true
|
||||
SecurityBaseline = @{
|
||||
secedit = $null
|
||||
secedit = $null
|
||||
auditpol = $null
|
||||
}
|
||||
ASR = @{
|
||||
ASR = @{
|
||||
defender = $null
|
||||
}
|
||||
MissingCritical = @()
|
||||
MissingOptional = @()
|
||||
MissingCritical = @()
|
||||
MissingOptional = @()
|
||||
}
|
||||
|
||||
# Check secedit.exe (CRITICAL for SecurityBaseline)
|
||||
|
|
@ -352,20 +229,8 @@ function Test-AllDependencies {
|
|||
# Check Windows Defender (CRITICAL for ASR)
|
||||
$result.ASR.defender = Test-WindowsDefenderAvailable
|
||||
if (-not $result.ASR.defender.Available -or -not $result.ASR.defender.ServiceRunning) {
|
||||
# Check if a third-party security product is present (not a critical failure)
|
||||
$thirdParty = Test-ThirdPartySecurityProduct
|
||||
if ($thirdParty.Detected) {
|
||||
$result.MissingOptional += "Windows Defender not primary (ASR skipped: $($thirdParty.ProductName))"
|
||||
}
|
||||
else {
|
||||
$result.AllAvailable = $false
|
||||
$result.MissingCritical += "Windows Defender (required for ASR module)"
|
||||
}
|
||||
}
|
||||
elseif ($result.ASR.defender.IsPassiveMode) {
|
||||
$thirdParty = Test-ThirdPartySecurityProduct
|
||||
$productName = if ($thirdParty.ProductName) { $thirdParty.ProductName } else { "Unknown" }
|
||||
$result.MissingOptional += "Windows Defender in Passive Mode (ASR skipped: $productName)"
|
||||
$result.AllAvailable = $false
|
||||
$result.MissingCritical += "Windows Defender (required for ASR module)"
|
||||
}
|
||||
|
||||
return $result
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -25,24 +25,24 @@ function Test-VBSCapable {
|
|||
param()
|
||||
|
||||
$requirements = @{
|
||||
UEFI = Test-UEFIBoot
|
||||
SecureBoot = Test-SecureBootEnabled
|
||||
TPM = (Test-TPMAvailable).Present
|
||||
UEFI = Test-UEFIBoot
|
||||
SecureBoot = Test-SecureBootEnabled
|
||||
TPM = (Test-TPMAvailable).Present
|
||||
Virtualization = Test-VirtualizationEnabled
|
||||
Windows11 = (Get-WindowsVersion).IsWindows11
|
||||
Windows11 = (Get-WindowsVersion).IsWindows11
|
||||
}
|
||||
|
||||
$allMet = $requirements.UEFI -and $requirements.SecureBoot -and `
|
||||
$requirements.TPM -and $requirements.Virtualization -and `
|
||||
$requirements.Windows11
|
||||
$requirements.TPM -and $requirements.Virtualization -and `
|
||||
$requirements.Windows11
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Capable = $allMet
|
||||
UEFI = $requirements.UEFI
|
||||
SecureBoot = $requirements.SecureBoot
|
||||
TPM = $requirements.TPM
|
||||
Capable = $allMet
|
||||
UEFI = $requirements.UEFI
|
||||
SecureBoot = $requirements.SecureBoot
|
||||
TPM = $requirements.TPM
|
||||
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
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Name = $cpu.Name
|
||||
Manufacturer = $cpu.Manufacturer
|
||||
Cores = $cpu.NumberOfCores
|
||||
LogicalProcessors = $cpu.NumberOfLogicalProcessors
|
||||
MaxClockSpeed = $cpu.MaxClockSpeed
|
||||
Name = $cpu.Name
|
||||
Manufacturer = $cpu.Manufacturer
|
||||
Cores = $cpu.NumberOfCores
|
||||
LogicalProcessors = $cpu.NumberOfLogicalProcessors
|
||||
MaxClockSpeed = $cpu.MaxClockSpeed
|
||||
VirtualizationEnabled = $cpu.VirtualizationFirmwareEnabled
|
||||
Architecture = $cpu.Architecture
|
||||
Architecture = $cpu.Architecture
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
|
@ -123,9 +123,9 @@ function Get-MemoryInfo {
|
|||
|
||||
return [PSCustomObject]@{
|
||||
TotalPhysicalMemoryGB = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
|
||||
FreePhysicalMemoryGB = [math]::Round($os.FreePhysicalMemory / 1MB / 1024, 2)
|
||||
TotalVirtualMemoryGB = [math]::Round($os.TotalVirtualMemorySize / 1MB / 1024, 2)
|
||||
FreeVirtualMemoryGB = [math]::Round($os.FreeVirtualMemory / 1MB / 1024, 2)
|
||||
FreePhysicalMemoryGB = [math]::Round($os.FreePhysicalMemory / 1MB / 1024, 2)
|
||||
TotalVirtualMemoryGB = [math]::Round($os.TotalVirtualMemorySize / 1MB / 1024, 2)
|
||||
FreeVirtualMemoryGB = [math]::Round($os.FreeVirtualMemory / 1MB / 1024, 2)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
|
@ -192,16 +192,16 @@ function Get-WindowsEditionInfo {
|
|||
$supportsBitLocker = -not $isHome
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Caption = $os.Caption
|
||||
Version = $os.Version
|
||||
BuildNumber = $os.BuildNumber
|
||||
IsHome = $isHome
|
||||
IsPro = $isPro
|
||||
IsEnterprise = $isEnterprise
|
||||
IsEducation = $isEducation
|
||||
Caption = $os.Caption
|
||||
Version = $os.Version
|
||||
BuildNumber = $os.BuildNumber
|
||||
IsHome = $isHome
|
||||
IsPro = $isPro
|
||||
IsEnterprise = $isEnterprise
|
||||
IsEducation = $isEducation
|
||||
SupportsCredentialGuard = $supportsCredentialGuard
|
||||
SupportsAppLocker = $supportsAppLocker
|
||||
SupportsBitLocker = $supportsBitLocker
|
||||
SupportsAppLocker = $supportsAppLocker
|
||||
SupportsBitLocker = $supportsBitLocker
|
||||
}
|
||||
}
|
||||
catch {
|
||||
|
|
@ -223,16 +223,16 @@ function Get-HardwareReport {
|
|||
param()
|
||||
|
||||
return [PSCustomObject]@{
|
||||
OS = Get-WindowsVersion
|
||||
Edition = Get-WindowsEditionInfo
|
||||
CPU = Get-CPUInfo
|
||||
Memory = Get-MemoryInfo
|
||||
UEFI = Test-UEFIBoot
|
||||
SecureBoot = Test-SecureBootEnabled
|
||||
TPM = Test-TPMAvailable
|
||||
OS = Get-WindowsVersion
|
||||
Edition = Get-WindowsEditionInfo
|
||||
CPU = Get-CPUInfo
|
||||
Memory = Get-MemoryInfo
|
||||
UEFI = Test-UEFIBoot
|
||||
SecureBoot = Test-SecureBootEnabled
|
||||
TPM = Test-TPMAvailable
|
||||
Virtualization = Test-VirtualizationEnabled
|
||||
VBSCapable = Test-VBSCapable
|
||||
SSD = Test-SSDDrive
|
||||
VBSCapable = Test-VBSCapable
|
||||
SSD = Test-SSDDrive
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
.NOTES
|
||||
Author: NexusOne23
|
||||
Version: 2.2.4
|
||||
Version: 2.2.2
|
||||
Requires: PowerShell 5.1+
|
||||
#>
|
||||
|
||||
|
|
@ -213,12 +213,12 @@ function Get-ServiceStatus {
|
|||
$serviceWmi = Get-CimInstance -ClassName Win32_Service -Filter "Name='$ServiceName'" -ErrorAction Stop
|
||||
|
||||
return [PSCustomObject]@{
|
||||
Name = $service.Name
|
||||
Name = $service.Name
|
||||
DisplayName = $service.DisplayName
|
||||
Status = $service.Status
|
||||
StartType = $service.StartType
|
||||
StartMode = $serviceWmi.StartMode
|
||||
PathName = $serviceWmi.PathName
|
||||
Status = $service.Status
|
||||
StartType = $service.StartType
|
||||
StartMode = $serviceWmi.StartMode
|
||||
PathName = $serviceWmi.PathName
|
||||
Description = $serviceWmi.Description
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
VERSION
1
VERSION
|
|
@ -1 +0,0 @@
|
|||
2.2.4
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
12
config.json
12
config.json
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
"modules": {
|
||||
"SecurityBaseline": {
|
||||
"enabled": true,
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
"description": "Microsoft Edge v139 Security Baseline: 24 security policies",
|
||||
"_comment": "Interactive: Allow extensions (Y/N, default: Y)",
|
||||
"allowExtensions": true,
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
"baseline": "Edge v139",
|
||||
"policies": 24,
|
||||
"features": {
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
"disableWirelessDisplay": false,
|
||||
"disableDiscoveryProtocols": true,
|
||||
"disableIPv6": false,
|
||||
"version": "2.2.4",
|
||||
"version": "2.2.2",
|
||||
"policies": 50,
|
||||
"features": {
|
||||
"rdp_hardening": true,
|
||||
|
|
@ -94,11 +94,7 @@
|
|||
"firewall_shields_up": true,
|
||||
"ipv6_disable": true
|
||||
},
|
||||
"profiles": [
|
||||
"Balanced",
|
||||
"Enterprise",
|
||||
"Maximum"
|
||||
]
|
||||
"profiles": ["Balanced", "Enterprise", "Maximum"]
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue