mirror of
https://github.com/mr-r3b00t/go_darker
synced 2026-08-07 04:33:00 +00:00
948 lines
48 KiB
PowerShell
948 lines
48 KiB
PowerShell
#Requires -Version 5.1
|
|
<#
|
|
Manage-WindowsTelemetry.ps1
|
|
|
|
Purpose : View and control common Windows 11 telemetry / diagnostic-data
|
|
settings, services and scheduled tasks.
|
|
|
|
Scope : Shows what is currently ENABLED (data collecting) vs DISABLED,
|
|
and lets the user turn individual items - or everything - on/off.
|
|
|
|
Areas : Core diagnostic data (AllowTelemetry), diagnostic log limits,
|
|
Windows Error Reporting (full stack: flags, consent, service,
|
|
task - the modern successor to Dr. Watson), CEIP/SQM, AppCompat
|
|
appraiser, Cloud Content / Tailored Experiences, Activity
|
|
History, Advertising ID, Feedback (SIUF), inking/typing and
|
|
speech data, search suggestions, DiagTrack + related services,
|
|
telemetry scheduled tasks, Cortana/cloud search, cloud clipboard
|
|
and settings sync, suggestions/ads (Content Delivery Manager),
|
|
location, Find My Device, Copilot/Recall, Delivery Optimization,
|
|
and Windows SmartScreen ([SEC]: apps-and-files check, Store app
|
|
URL check, Enhanced Phishing Protection - excluded from bulk
|
|
disable unless requested).
|
|
|
|
Notes : - Windows PowerShell 5.1 compatible. ASCII-only source.
|
|
- Registry (HKLM) and service changes require Administrator.
|
|
- "Enabled" = the telemetry / data-collection behaviour is ON.
|
|
"Disabled" = the telemetry / data-collection behaviour is OFF.
|
|
- For policy-type values, "Enable" REMOVES the policy value to
|
|
restore the true Windows default (absent), so the Settings UI
|
|
is not left in a "managed by your organization" state.
|
|
|
|
User mode:
|
|
-UserMode restricts the tool to per-user (HKCU) items only - the ones
|
|
that need NO administrator rights. Run it as your normal (unelevated)
|
|
account for personal privacy hardening: it writes only YOUR user hive,
|
|
so it also avoids the "HKCU points at the admin's profile when you
|
|
elevate as a different user" pitfall. HKLM policy/service/task items
|
|
are hidden in this mode.
|
|
|
|
Usage :
|
|
.\Manage-WindowsTelemetry.ps1 # interactive menu (all items)
|
|
.\Manage-WindowsTelemetry.ps1 -UserMode # per-user items only, no admin
|
|
.\Manage-WindowsTelemetry.ps1 -UserMode -DisableAll # harden your user profile
|
|
.\Manage-WindowsTelemetry.ps1 -Report # print status and exit
|
|
.\Manage-WindowsTelemetry.ps1 -DisableAll # turn telemetry OFF (keeps [SEC]/[NET] ON)
|
|
.\Manage-WindowsTelemetry.ps1 -DisableAll -IncludeSecurity # also disable SmartScreen
|
|
.\Manage-WindowsTelemetry.ps1 -GoDark # MAX: disable everything incl [SEC]+[NET]
|
|
.\Manage-WindowsTelemetry.ps1 -EnableAll # restore Windows default ON
|
|
.\Manage-WindowsTelemetry.ps1 -Csv .\out.csv # export status and exit
|
|
.\Manage-WindowsTelemetry.ps1 -Report -Csv .\status.csv
|
|
|
|
DISCLAIMER: Review before use. Changing telemetry / service settings alters
|
|
system behaviour. Run in a test environment first. No warranty.
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[switch]$Report,
|
|
[switch]$DisableAll,
|
|
[switch]$EnableAll,
|
|
[switch]$IncludeSecurity, # also disable [SEC] SmartScreen features in bulk actions
|
|
[switch]$GoDark, # maximum: disable EVERYTHING incl [SEC] and [NET] callbacks
|
|
[switch]$UserMode, # only per-user (HKCU) items; no admin needed
|
|
[string]$Csv
|
|
)
|
|
|
|
Set-StrictMode -Version 2.0
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Elevation helpers
|
|
# ---------------------------------------------------------------------------
|
|
function Test-IsAdmin {
|
|
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
|
|
$pr = New-Object Security.Principal.WindowsPrincipal($id)
|
|
return $pr.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
}
|
|
|
|
$Script:IsAdmin = Test-IsAdmin
|
|
$Script:UserMode = [bool]$UserMode
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Registry helpers
|
|
# ---------------------------------------------------------------------------
|
|
function Resolve-RegPath {
|
|
param([string]$Hive, [string]$Path)
|
|
return ('{0}:\{1}' -f $Hive, $Path)
|
|
}
|
|
|
|
function Get-RegValue {
|
|
param([string]$FullPath, [string]$Name)
|
|
try {
|
|
if (-not (Test-Path -LiteralPath $FullPath)) { return $null }
|
|
$item = Get-ItemProperty -LiteralPath $FullPath -Name $Name -ErrorAction Stop
|
|
return $item.$Name
|
|
} catch {
|
|
return $null
|
|
}
|
|
}
|
|
|
|
function Set-RegValue {
|
|
param([string]$FullPath, [string]$Name, $Value, [string]$Type = 'DWord')
|
|
if (-not (Test-Path -LiteralPath $FullPath)) {
|
|
New-Item -Path $FullPath -Force | Out-Null
|
|
}
|
|
New-ItemProperty -LiteralPath $FullPath -Name $Name -Value $Value -PropertyType $Type -Force | Out-Null
|
|
}
|
|
|
|
function Remove-RegValue {
|
|
param([string]$FullPath, [string]$Name)
|
|
if (Test-Path -LiteralPath $FullPath) {
|
|
Remove-ItemProperty -LiteralPath $FullPath -Name $Name -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Control model
|
|
# Each control is a PSCustomObject with a Type that drives Get/Enable/Disable.
|
|
# Types: Reg, Service, Task
|
|
#
|
|
# RemoveOnEnable: for policy-style values whose Windows default is ABSENT.
|
|
# Enabling such a control deletes the value instead of writing OnValue, so
|
|
# the machine is not left policy-managed after an "enable".
|
|
# ---------------------------------------------------------------------------
|
|
function New-RegControl {
|
|
param(
|
|
[string]$Name, [string]$Category, [string]$Hive, [string]$Path,
|
|
[string]$ValueName, [int]$OnValue, [int]$OffValue,
|
|
[ValidateSet('On','Off')][string]$Default = 'On',
|
|
[string]$RegType = 'DWord', [string]$Note = '',
|
|
[switch]$RemoveOnEnable,
|
|
[switch]$Security, # marks a control whose "Disabled" state REDUCES protection
|
|
[switch]$GoDark, # ambient MS callback; only disabled by -GoDark or individually
|
|
[switch]$Critical # breaks important functionality; per-item "confirm close" required
|
|
)
|
|
[pscustomobject]@{
|
|
Type = 'Reg'
|
|
Name = $Name
|
|
Category = $Category
|
|
Note = $Note
|
|
FullPath = (Resolve-RegPath -Hive $Hive -Path $Path)
|
|
ValueName = $ValueName
|
|
OnValue = $OnValue
|
|
OffValue = $OffValue
|
|
Default = $Default
|
|
RegType = $RegType
|
|
RemoveOnEnable = [bool]$RemoveOnEnable
|
|
Security = [bool]$Security
|
|
GoDark = [bool]$GoDark
|
|
Critical = [bool]$Critical
|
|
AdminReq = ($Hive -eq 'HKLM')
|
|
}
|
|
}
|
|
|
|
function New-ServiceControl {
|
|
param(
|
|
[string]$Name, [string]$ServiceName,
|
|
[ValidateSet('Automatic','Manual')][string]$DefaultStartupType = 'Automatic',
|
|
[string]$Note = '', [string]$Category = 'Service',
|
|
[switch]$Critical
|
|
)
|
|
[pscustomobject]@{
|
|
Type = 'Service'
|
|
Name = $Name
|
|
Category = $Category
|
|
Note = $Note
|
|
ServiceName = $ServiceName
|
|
DefaultStartupType = $DefaultStartupType
|
|
Security = $false
|
|
GoDark = $false
|
|
Critical = [bool]$Critical
|
|
AdminReq = $true
|
|
}
|
|
}
|
|
|
|
function New-TaskControl {
|
|
param([string]$Name, [string[]]$Tasks, [string]$Note = '')
|
|
# $Tasks entries are full task paths, e.g. \Microsoft\Windows\Application Experience\ProgramDataUpdater
|
|
[pscustomobject]@{
|
|
Type = 'Task'
|
|
Name = $Name
|
|
Category = 'Scheduled Task'
|
|
Note = $Note
|
|
Tasks = $Tasks
|
|
Security = $false
|
|
GoDark = $false
|
|
Critical = $false
|
|
AdminReq = $true
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# State + actions
|
|
# ---------------------------------------------------------------------------
|
|
function Get-ControlState {
|
|
param($Ctrl)
|
|
switch ($Ctrl.Type) {
|
|
'Reg' {
|
|
$cur = Get-RegValue -FullPath $Ctrl.FullPath -Name $Ctrl.ValueName
|
|
if ($null -eq $cur) {
|
|
if ($Ctrl.Default -eq 'On') { return 'Enabled (default)' }
|
|
else { return 'Disabled (default)' }
|
|
}
|
|
$curInt = $null
|
|
try { $curInt = [int]$cur } catch {
|
|
return ('Enabled (value={0})' -f $cur) # non-numeric data: report, do not throw
|
|
}
|
|
if ($curInt -eq $Ctrl.OffValue) { return 'Disabled' }
|
|
if ($curInt -eq $Ctrl.OnValue) { return 'Enabled' }
|
|
return ('Enabled (value={0})' -f $curInt)
|
|
}
|
|
'Service' {
|
|
$svc = Get-Service -Name $Ctrl.ServiceName -ErrorAction SilentlyContinue
|
|
if ($null -eq $svc) { return 'Not present' }
|
|
if ($svc.StartType -eq 'Disabled') { return 'Disabled' }
|
|
return ('Enabled ({0}, {1})' -f $svc.StartType, $svc.Status)
|
|
}
|
|
'Task' {
|
|
$states = @()
|
|
foreach ($t in $Ctrl.Tasks) {
|
|
$leaf = Split-Path $t -Leaf
|
|
$path = (Split-Path $t -Parent) + '\'
|
|
$task = Get-ScheduledTask -TaskName $leaf -TaskPath $path -ErrorAction SilentlyContinue
|
|
if ($task) { $states += $task.State }
|
|
}
|
|
if ($states.Count -eq 0) { return 'Not present' }
|
|
if ($states -contains 'Ready' -or $states -contains 'Running') { return 'Enabled' }
|
|
return 'Disabled'
|
|
}
|
|
}
|
|
return 'Unknown'
|
|
}
|
|
|
|
function Set-ControlEnabled {
|
|
param($Ctrl) # Enable telemetry (restore Windows default behaviour)
|
|
switch ($Ctrl.Type) {
|
|
'Reg' {
|
|
if ($Ctrl.RemoveOnEnable) {
|
|
Remove-RegValue -FullPath $Ctrl.FullPath -Name $Ctrl.ValueName
|
|
} else {
|
|
Set-RegValue -FullPath $Ctrl.FullPath -Name $Ctrl.ValueName -Value $Ctrl.OnValue -Type $Ctrl.RegType
|
|
}
|
|
}
|
|
'Service' {
|
|
Set-Service -Name $Ctrl.ServiceName -StartupType $Ctrl.DefaultStartupType -ErrorAction Stop
|
|
if ($Ctrl.DefaultStartupType -eq 'Automatic') {
|
|
Start-Service -Name $Ctrl.ServiceName -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
'Task' {
|
|
foreach ($t in $Ctrl.Tasks) {
|
|
$leaf = Split-Path $t -Leaf
|
|
$path = (Split-Path $t -Parent) + '\'
|
|
Enable-ScheduledTask -TaskName $leaf -TaskPath $path -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function Set-ControlDisabled {
|
|
param($Ctrl) # Disable telemetry (privacy hardened)
|
|
switch ($Ctrl.Type) {
|
|
'Reg' {
|
|
Set-RegValue -FullPath $Ctrl.FullPath -Name $Ctrl.ValueName -Value $Ctrl.OffValue -Type $Ctrl.RegType
|
|
}
|
|
'Service' {
|
|
Stop-Service -Name $Ctrl.ServiceName -Force -ErrorAction SilentlyContinue
|
|
Set-Service -Name $Ctrl.ServiceName -StartupType Disabled -ErrorAction Stop
|
|
}
|
|
'Task' {
|
|
foreach ($t in $Ctrl.Tasks) {
|
|
$leaf = Split-Path $t -Leaf
|
|
$path = (Split-Path $t -Parent) + '\'
|
|
Disable-ScheduledTask -TaskName $leaf -TaskPath $path -ErrorAction SilentlyContinue | Out-Null
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Control catalog
|
|
# ---------------------------------------------------------------------------
|
|
function Get-Controls {
|
|
$c = New-Object System.Collections.ArrayList
|
|
|
|
# --- Core telemetry policy ---
|
|
[void]$c.Add( (New-RegControl -Name 'Diagnostic data (AllowTelemetry)' -Category 'Telemetry' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\DataCollection' `
|
|
-ValueName 'AllowTelemetry' -OnValue 3 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note '0=Off/Security 1=Required 3=Optional. Home/Pro treat 0 as 1.') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Diagnostic data (non-policy)' -Category 'Telemetry' `
|
|
-Hive HKLM -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection' `
|
|
-ValueName 'AllowTelemetry' -OnValue 3 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Feedback Notifications' -Category 'Telemetry' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\DataCollection' `
|
|
-ValueName 'DoNotShowFeedbackNotifications' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Disabled hides feedback prompts') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Diagnostic Log Collection' -Category 'Telemetry' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\DataCollection' `
|
|
-ValueName 'LimitDiagnosticLogCollection' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Disabled blocks extra diagnostic log upload') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'OneSettings Downloads' -Category 'Telemetry' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\DataCollection' `
|
|
-ValueName 'DisableOneSettingsDownloads' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Remote telemetry configuration channel') )
|
|
|
|
# --- Application compatibility / appraiser telemetry ---
|
|
[void]$c.Add( (New-RegControl -Name 'App Impact Telemetry (AITEnable)' -Category 'AppCompat' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\AppCompat' `
|
|
-ValueName 'AITEnable' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Inventory Collector' -Category 'AppCompat' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\AppCompat' `
|
|
-ValueName 'DisableInventory' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable) )
|
|
|
|
# --- Windows Error Reporting (successor to Dr. Watson) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Windows Error Reporting' -Category 'Error Reporting' `
|
|
-Hive HKLM -Path 'SOFTWARE\Microsoft\Windows\Windows Error Reporting' `
|
|
-ValueName 'Disabled' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Error Reporting (policy)' -Category 'Error Reporting' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting' `
|
|
-ValueName 'Disabled' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Group Policy variant; overrides the non-policy flag') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'WER Additional Data' -Category 'Error Reporting' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Error Reporting' `
|
|
-ValueName 'DontSendAdditionalData' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Disabled stops second-stage crash data upload') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'WER Consent Level' -Category 'Error Reporting' `
|
|
-Hive HKLM -Path 'SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent' `
|
|
-ValueName 'DefaultConsent' -OnValue 4 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note '1=always ask 2=params 3=params+safe 4=send all') )
|
|
|
|
# --- Customer Experience Improvement Program ---
|
|
[void]$c.Add( (New-RegControl -Name 'CEIP (SQM Client)' -Category 'CEIP' `
|
|
-Hive HKLM -Path 'SOFTWARE\Microsoft\SQMClient\Windows' `
|
|
-ValueName 'CEIPEnable' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
# --- Cloud content / consumer features / ads ---
|
|
[void]$c.Add( (New-RegControl -Name 'Windows Consumer Features' -Category 'Cloud Content' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\CloudContent' `
|
|
-ValueName 'DisableWindowsConsumerFeatures' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Tailored Experiences (policy)' -Category 'Cloud Content' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\CloudContent' `
|
|
-ValueName 'DisableTailoredExperiencesWithDiagnosticData' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable) )
|
|
|
|
# --- Activity history / timeline ---
|
|
[void]$c.Add( (New-RegControl -Name 'Publish User Activities' -Category 'Activity History' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'PublishUserActivities' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Upload User Activities' -Category 'Activity History' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'UploadUserActivities' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
# --- Per-user privacy (HKCU, no admin needed) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Advertising ID' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\AdvertisingInfo' `
|
|
-ValueName 'Enabled' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Tailored Experiences (user)' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\Privacy' `
|
|
-ValueName 'TailoredExperiencesWithDiagnosticDataEnabled' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Feedback Frequency (SIUF)' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Siuf\Rules' `
|
|
-ValueName 'NumberOfSIUFInPeriod' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Disabled = never asked for feedback') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Implicit Ink Collection' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\InputPersonalization' `
|
|
-ValueName 'RestrictImplicitInkCollection' -OnValue 0 -OffValue 1 -Default On `
|
|
-Note 'Inking personalization data') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Implicit Text Collection' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\InputPersonalization' `
|
|
-ValueName 'RestrictImplicitTextCollection' -OnValue 0 -OffValue 1 -Default On `
|
|
-Note 'Typing personalization data') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Typing Insights (TIPC)' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Input\TIPC' `
|
|
-ValueName 'Enabled' -OnValue 1 -OffValue 0 -Default On `
|
|
-Note 'Typing/ink telemetry channel') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Online Speech Recognition' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' `
|
|
-ValueName 'HasAccepted' -OnValue 1 -OffValue 0 -Default Off `
|
|
-Note 'Cloud speech; default off until user consents') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Linguistic Data Collection' -Category 'Privacy (User)' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\TextInput' `
|
|
-ValueName 'AllowLinguisticDataCollection' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Search Box Web Suggestions' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Policies\Microsoft\Windows\Explorer' `
|
|
-ValueName 'DisableSearchBoxSuggestions' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Win11 control for web results in Search') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Bing Search (legacy)' -Category 'Privacy (User)' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\Search' `
|
|
-ValueName 'BingSearchEnabled' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Win10-era value; largely ignored on Win11') )
|
|
|
|
# --- Search / Cortana cloud ---
|
|
[void]$c.Add( (New-RegControl -Name 'Cortana' -Category 'Search/Cortana' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Search' `
|
|
-ValueName 'AllowCortana' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Search Web Results (Cloud)' -Category 'Search/Cortana' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Search' `
|
|
-ValueName 'ConnectedSearchUseWeb' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Bing web results in Start/Search') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Cloud Content Search' -Category 'Search/Cortana' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Search' `
|
|
-ValueName 'AllowCloudSearch' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Search of OneDrive/Outlook/SharePoint content') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Search Uses Location' -Category 'Search/Cortana' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\Windows Search' `
|
|
-ValueName 'AllowSearchToUseLocation' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable) )
|
|
|
|
# --- Cloud sync (clipboard / settings) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Clipboard History' -Category 'Cloud Sync' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'AllowClipboardHistory' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Local clipboard history (Win+V)') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Cross-Device Clipboard (Cloud)' -Category 'Cloud Sync' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'AllowCrossDeviceClipboard' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Syncs clipboard contents to Microsoft cloud') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Settings Sync' -Category 'Cloud Sync' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\SettingSync' `
|
|
-ValueName 'DisableSettingSync' -OnValue 0 -OffValue 2 -Default On -RemoveOnEnable `
|
|
-Note 'Syncs Windows settings across devices via MS account') )
|
|
|
|
# --- Suggestions / ads (Content Delivery Manager, per-user) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Auto-install Suggested Apps' -Category 'Suggestions/Ads' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' `
|
|
-ValueName 'SilentInstalledAppsEnabled' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Start Menu Suggestions' -Category 'Suggestions/Ads' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' `
|
|
-ValueName 'SystemPaneSuggestionsEnabled' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Settings App Suggestions' -Category 'Suggestions/Ads' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' `
|
|
-ValueName 'SubscribedContent-338393Enabled' -OnValue 1 -OffValue 0 -Default On) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Tips and Notifications' -Category 'Suggestions/Ads' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' `
|
|
-ValueName 'SubscribedContent-338389Enabled' -OnValue 1 -OffValue 0 -Default On `
|
|
-Note 'Windows tips/suggestion notifications') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Lock Screen Spotlight' -Category 'Suggestions/Ads' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' `
|
|
-ValueName 'RotatingLockScreenOverlayEnabled' -OnValue 1 -OffValue 0 -Default On `
|
|
-Note 'Spotlight ads/facts on the lock screen') )
|
|
|
|
# --- Location ---
|
|
[void]$c.Add( (New-RegControl -Name 'Location Platform' -Category 'Location' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\LocationAndSensors' `
|
|
-ValueName 'DisableLocation' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'System-wide location services') )
|
|
|
|
# --- Find My Device ---
|
|
[void]$c.Add( (New-RegControl -Name 'Find My Device' -Category 'Find My Device' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\FindMyDevice' `
|
|
-ValueName 'AllowFindMyDevice' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note 'Periodic location reporting to your MS account') )
|
|
|
|
# --- AI features (Copilot / Recall) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Windows Copilot' -Category 'AI' `
|
|
-Hive HKCU -Path 'SOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' `
|
|
-ValueName 'TurnOffWindowsCopilot' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable) )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Recall (AI Data Analysis)' -Category 'AI' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\WindowsAI' `
|
|
-ValueName 'DisableAIDataAnalysis' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable `
|
|
-Note 'Recall screen snapshots (Copilot+ PCs)') )
|
|
|
|
# --- Delivery Optimization (update peer sharing) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Delivery Optimization P2P' -Category 'Network' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization' `
|
|
-ValueName 'DODownloadMode' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable `
|
|
-Note '0=HTTP only (no peers) 1=LAN 3=Internet peers') )
|
|
|
|
# --- Windows SmartScreen: OS-level URL/file reputation (SECURITY) ---
|
|
# These check apps, files and URLs against Microsoft's cloud reputation
|
|
# service. Disabling them REDUCES protection against malware/phishing.
|
|
[void]$c.Add( (New-RegControl -Name 'SmartScreen (apps and files)' -Category 'SmartScreen' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'EnableSmartScreen' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable -Security `
|
|
-Note 'SECURITY: shell check of downloaded apps/files') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'SmartScreen (Store apps)' -Category 'SmartScreen' `
|
|
-Hive HKCU -Path 'SOFTWARE\Microsoft\Windows\CurrentVersion\AppHost' `
|
|
-ValueName 'EnableWebContentEvaluation' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable -Security `
|
|
-Note 'SECURITY: URL check for web content in Store apps') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Enhanced Phishing Protection' -Category 'SmartScreen' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\WTDS\Components' `
|
|
-ValueName 'ServiceEnabled' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable -Security `
|
|
-Note 'SECURITY: Win11 password/phishing protection service') )
|
|
|
|
# --- Defender cloud (MAPS) - SECURITY, off reduces AV (Tamper Protection may block) ---
|
|
[void]$c.Add( (New-RegControl -Name 'Defender Cloud (MAPS)' -Category 'Defender Cloud' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows Defender\Spynet' `
|
|
-ValueName 'SpynetReporting' -OnValue 2 -OffValue 0 -Default On -RemoveOnEnable -Security `
|
|
-Note 'SECURITY: real-time cloud lookups. Tamper Protection may block changes.') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Defender Sample Submission' -Category 'Defender Cloud' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows Defender\Spynet' `
|
|
-ValueName 'SubmitSamplesConsent' -OnValue 1 -OffValue 2 -Default On -RemoveOnEnable -Security `
|
|
-Note 'SECURITY/PRIVACY: sends files to Microsoft. Tamper Protection may block changes.') )
|
|
|
|
# --- Ambient Microsoft callbacks ([NET]) - functional connections, go-dark only ---
|
|
[void]$c.Add( (New-RegControl -Name 'NCSI Active Probe' -Category 'Connectivity' `
|
|
-Hive HKLM -Path 'SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet' `
|
|
-ValueName 'EnableActiveProbing' -OnValue 1 -OffValue 0 -Default On -GoDark `
|
|
-Note 'Probes msftconnecttest.com. Off breaks captive-portal / internet indicator.') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Root Certificate Auto-Update' -Category 'Connectivity' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\SystemCertificates\AuthRoot' `
|
|
-ValueName 'DisableRootAutoUpdate' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable -GoDark `
|
|
-Note 'Off stops new/rotated trusted-root CAs downloading - can break HTTPS over time.') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Store App Auto-Update' -Category 'Connectivity' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\WindowsStore' `
|
|
-ValueName 'AutoDownload' -OnValue 4 -OffValue 2 -Default On -RemoveOnEnable -GoDark `
|
|
-Note 'Off stops Store apps auto-updating (including their security fixes).') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Font Streaming' -Category 'Connectivity' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\System' `
|
|
-ValueName 'EnableFontProviders' -OnValue 1 -OffValue 0 -Default On -RemoveOnEnable -GoDark `
|
|
-Note 'Off stops on-demand font downloads from Microsoft.') )
|
|
|
|
[void]$c.Add( (New-RegControl -Name 'Windows Media DRM Online' -Category 'Connectivity' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\WMDRM' `
|
|
-ValueName 'DisableOnline' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable -GoDark `
|
|
-Note 'Off stops Media DRM contacting Microsoft for licenses/individualization.') )
|
|
|
|
# --- Critical ([CRIT]) - breaks important functionality; per-item confirm-close ---
|
|
# NOT touched by any bulk action (not even -GoDark). Local-config stand-ins for
|
|
# what a hardened env does with WSUS / a local NTP server / network isolation.
|
|
[void]$c.Add( (New-RegControl -Name 'Windows Update Auto' -Category 'Critical' `
|
|
-Hive HKLM -Path 'SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' `
|
|
-ValueName 'NoAutoUpdate' -OnValue 0 -OffValue 1 -Default On -RemoveOnEnable -Critical `
|
|
-Note 'BREAKS SECURITY PATCHING. Off = no automatic update check/download. Use WSUS instead.') )
|
|
|
|
[void]$c.Add( (New-ServiceControl -Name 'Windows Time Sync (W32Time)' -Category 'Critical' `
|
|
-ServiceName 'W32Time' -DefaultStartupType Manual -Critical `
|
|
-Note 'BREAKS time sync (Kerberos/TLS drift). Off = no NTP to time.windows.com. Use a local time server.') )
|
|
|
|
# --- Services ---
|
|
[void]$c.Add( (New-ServiceControl -Name 'Connected User Experiences' `
|
|
-ServiceName 'DiagTrack' -DefaultStartupType Automatic `
|
|
-Note 'DiagTrack - primary telemetry service') )
|
|
|
|
[void]$c.Add( (New-ServiceControl -Name 'WAP Push Routing (dmwappush)' `
|
|
-ServiceName 'dmwappushservice' -DefaultStartupType Manual `
|
|
-Note 'Disabling can break provisioning package / MDM enrolment') )
|
|
|
|
[void]$c.Add( (New-ServiceControl -Name 'Error Reporting Svc (WerSvc)' `
|
|
-ServiceName 'WerSvc' -DefaultStartupType Manual `
|
|
-Note 'Runs WER report submission') )
|
|
|
|
# --- Scheduled tasks ---
|
|
[void]$c.Add( (New-TaskControl -Name 'Compatibility Appraiser tasks' -Tasks @(
|
|
'\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser',
|
|
'\Microsoft\Windows\Application Experience\ProgramDataUpdater',
|
|
'\Microsoft\Windows\Application Experience\StartupAppTask'
|
|
)) )
|
|
|
|
[void]$c.Add( (New-TaskControl -Name 'CEIP tasks' -Tasks @(
|
|
'\Microsoft\Windows\Customer Experience Improvement Program\Consolidator',
|
|
'\Microsoft\Windows\Customer Experience Improvement Program\UsbCeip',
|
|
'\Microsoft\Windows\Autochk\Proxy'
|
|
) -Note 'Includes Autochk\Proxy (kernel CEIP)') )
|
|
|
|
[void]$c.Add( (New-TaskControl -Name 'Feedback (SIUF) tasks' -Tasks @(
|
|
'\Microsoft\Windows\Feedback\Siuf\DmClient',
|
|
'\Microsoft\Windows\Feedback\Siuf\DmClientOnScenarioDownload'
|
|
)) )
|
|
|
|
[void]$c.Add( (New-TaskControl -Name 'Error Reporting task' -Tasks @(
|
|
'\Microsoft\Windows\Windows Error Reporting\QueueReporting'
|
|
)) )
|
|
|
|
[void]$c.Add( (New-TaskControl -Name 'Disk Diagnostic collector' -Tasks @(
|
|
'\Microsoft\Windows\DiskDiagnostic\Microsoft-Windows-DiskDiagnosticDataCollector'
|
|
)) )
|
|
|
|
return $c
|
|
}
|
|
|
|
# Restrict to per-user (HKCU, no-admin) items when in user mode.
|
|
function Select-ActiveControls {
|
|
param($All)
|
|
if ($Script:UserMode) {
|
|
return @($All | Where-Object { -not $_.AdminReq })
|
|
}
|
|
return $All
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Display
|
|
# ---------------------------------------------------------------------------
|
|
function Get-StateColor {
|
|
param([string]$State)
|
|
if ($State -like 'Disabled*') { return 'Green' }
|
|
if ($State -like 'Enabled*') { return 'Yellow' }
|
|
if ($State -like 'Not present*'){ return 'DarkGray' }
|
|
return 'Gray'
|
|
}
|
|
|
|
function Show-Status {
|
|
param($Controls)
|
|
|
|
Write-Host ''
|
|
Write-Host '==================================================================' -ForegroundColor Cyan
|
|
Write-Host ' Windows 11 Telemetry / Diagnostic Data Status' -ForegroundColor Cyan
|
|
Write-Host (' Host: {0} Admin: {1} {2}' -f $env:COMPUTERNAME, $Script:IsAdmin, (Get-Date)) -ForegroundColor DarkCyan
|
|
if ($Script:UserMode) {
|
|
Write-Host ' MODE: USER (per-user HKCU items only; no admin required)' -ForegroundColor Magenta
|
|
} else {
|
|
Write-Host ' MODE: FULL (per-user + system-wide items)' -ForegroundColor DarkCyan
|
|
}
|
|
Write-Host ' Enabled = collecting/on Disabled = hardened/off' -ForegroundColor DarkCyan
|
|
Write-Host '==================================================================' -ForegroundColor Cyan
|
|
Write-Host ('{0,-4}{1,-36}{2,-18}{3}' -f '#', 'Setting', 'Category', 'State') -ForegroundColor White
|
|
Write-Host ('{0,-4}{1,-36}{2,-18}{3}' -f '---', '-------', '--------', '-----') -ForegroundColor DarkGray
|
|
|
|
$i = 0
|
|
$nEnabled = 0; $nDisabled = 0; $nAbsent = 0; $nSecOff = 0; $nSec = 0; $nNet = 0; $nCrit = 0; $anyLock = $false
|
|
foreach ($ctrl in $Controls) {
|
|
$i++
|
|
$state = Get-ControlState -Ctrl $ctrl
|
|
if ($state -like 'Enabled*') { $nEnabled++ }
|
|
elseif ($state -like 'Disabled*') { $nDisabled++ }
|
|
elseif ($state -like 'Not present*') { $nAbsent++ }
|
|
$sec = ''
|
|
if ($ctrl.Security) {
|
|
$sec = ' [SEC]'; $nSec++
|
|
if ($state -like 'Disabled*') { $nSecOff++ }
|
|
} elseif ($ctrl.Critical) {
|
|
$sec = ' [CRIT]'; $nCrit++
|
|
} elseif ($ctrl.GoDark) {
|
|
$sec = ' [NET]'; $nNet++
|
|
}
|
|
$lock = ''
|
|
if ($ctrl.AdminReq -and -not $Script:IsAdmin) { $lock = ' *'; $anyLock = $true }
|
|
$line = ('{0,-4}{1,-36}{2,-18}' -f $i, ($ctrl.Name + $sec), $ctrl.Category)
|
|
Write-Host $line -NoNewline
|
|
Write-Host ($state + $lock) -ForegroundColor (Get-StateColor $state)
|
|
}
|
|
Write-Host ('{0,-4}{1,-36}{2,-18}{3}' -f '---', '-------', '--------', '-----') -ForegroundColor DarkGray
|
|
Write-Host (' Summary: {0} enabled, {1} disabled, {2} not present' -f $nEnabled, $nDisabled, $nAbsent) -ForegroundColor White
|
|
if ($nSec -gt 0) {
|
|
Write-Host ' [SEC] = anti-malware reputation check. Disabling REDUCES protection' -ForegroundColor DarkYellow
|
|
}
|
|
if ($nNet -gt 0) {
|
|
Write-Host ' [NET] = ambient Microsoft callback. Disabling can break functionality' -ForegroundColor DarkYellow
|
|
}
|
|
if ($nCrit -gt 0) {
|
|
Write-Host ' [CRIT] = breaks patching/time/trust. Never bulk-disabled; needs per-item confirm (X)' -ForegroundColor DarkYellow
|
|
}
|
|
if ($nSecOff -gt 0) {
|
|
Write-Host (' WARNING: {0} security SmartScreen feature(s) are currently OFF' -f $nSecOff) -ForegroundColor Red
|
|
}
|
|
if ($anyLock) {
|
|
Write-Host ' * requires Administrator to change (run elevated)' -ForegroundColor DarkYellow
|
|
}
|
|
Write-Host ''
|
|
}
|
|
|
|
function Export-StatusCsv {
|
|
param($Controls, [string]$Path)
|
|
$rows = foreach ($ctrl in $Controls) {
|
|
[pscustomobject]@{
|
|
Name = $ctrl.Name
|
|
Category = $ctrl.Category
|
|
Type = $ctrl.Type
|
|
State = (Get-ControlState -Ctrl $ctrl)
|
|
AdminReq = $ctrl.AdminReq
|
|
Note = $ctrl.Note
|
|
}
|
|
}
|
|
$rows | Export-Csv -Path $Path -NoTypeInformation -Encoding ASCII
|
|
Write-Host ("Status written to {0}" -f $Path) -ForegroundColor Green
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Apply helpers with guard rails
|
|
# ---------------------------------------------------------------------------
|
|
function Invoke-ControlAction {
|
|
param($Ctrl, [ValidateSet('Enable','Disable')][string]$Action)
|
|
|
|
if ($Ctrl.AdminReq -and -not $Script:IsAdmin) {
|
|
Write-Host (" SKIP {0} (needs Administrator)" -f $Ctrl.Name) -ForegroundColor DarkYellow
|
|
return
|
|
}
|
|
if ((Get-ControlState -Ctrl $Ctrl) -eq 'Not present') {
|
|
Write-Host (" SKIP {0} (not present on this system)" -f $Ctrl.Name) -ForegroundColor DarkGray
|
|
return
|
|
}
|
|
try {
|
|
if ($Action -eq 'Enable') { Set-ControlEnabled -Ctrl $Ctrl }
|
|
else { Set-ControlDisabled -Ctrl $Ctrl }
|
|
$new = Get-ControlState -Ctrl $Ctrl
|
|
Write-Host (" OK {0} -> {1}" -f $Ctrl.Name, $new) -ForegroundColor Green
|
|
} catch {
|
|
Write-Host (" FAIL {0}: {1}" -f $Ctrl.Name, $_.Exception.Message) -ForegroundColor Red
|
|
}
|
|
}
|
|
|
|
function Invoke-ConfirmClose {
|
|
param($Ctrl) # per-item "confirm close" for [CRIT] items
|
|
Write-Host ''
|
|
Write-Host ('CONFIRM CLOSE: {0}' -f $Ctrl.Name) -ForegroundColor Red
|
|
if ($Ctrl.Note) { Write-Host (' {0}' -f $Ctrl.Note) -ForegroundColor DarkYellow }
|
|
Write-Host ' Local-config only - a hardened env would use WSUS / local NTP / network isolation.' -ForegroundColor DarkYellow
|
|
if ((Read-Host ('Close this? type CLOSE')) -ceq 'CLOSE') {
|
|
Invoke-ControlAction -Ctrl $Ctrl -Action Disable
|
|
} else {
|
|
Write-Host ' Skipped.' -ForegroundColor DarkGray
|
|
}
|
|
}
|
|
|
|
function Invoke-AllAction {
|
|
param(
|
|
$Controls,
|
|
[ValidateSet('Enable','Disable')][string]$Action,
|
|
[switch]$WithSecurity, # when disabling, also include [SEC] SmartScreen/Defender features
|
|
[switch]$WithGoDark # when disabling, also include [NET] ambient callbacks
|
|
)
|
|
$verb = if ($Action -eq 'Enable') { 'ENABLE (restore Windows default)' } else { 'DISABLE (harden)' }
|
|
Write-Host ''
|
|
Write-Host ("Applying {0} to ALL items..." -f $verb) -ForegroundColor Cyan
|
|
$skippedSec = 0; $skippedNet = 0; $skippedCrit = 0
|
|
foreach ($ctrl in $Controls) {
|
|
if ($Action -eq 'Disable') {
|
|
# [CRIT] items are NEVER bulk-disabled (not even by go-dark) - confirm-close only.
|
|
if ($ctrl.Critical) { $skippedCrit++; continue }
|
|
# Never auto-disable security or ambient-callback items in bulk unless asked.
|
|
if ($ctrl.Security -and -not $WithSecurity) { $skippedSec++; continue }
|
|
if ($ctrl.GoDark -and -not $WithGoDark) { $skippedNet++; continue }
|
|
}
|
|
Invoke-ControlAction -Ctrl $ctrl -Action $Action
|
|
}
|
|
if ($skippedSec -gt 0) {
|
|
Write-Host (' Kept {0} [SEC] security feature(s) ON (use -IncludeSecurity / menu "S", or -GoDark).' -f $skippedSec) -ForegroundColor DarkYellow
|
|
}
|
|
if ($skippedNet -gt 0) {
|
|
Write-Host (' Kept {0} [NET] ambient callback(s) ON (use -GoDark / menu "G").' -f $skippedNet) -ForegroundColor DarkYellow
|
|
}
|
|
if ($skippedCrit -gt 0) {
|
|
Write-Host (' Kept {0} [CRIT] item(s) ON - close individually with confirm (menu "X").' -f $skippedCrit) -ForegroundColor DarkYellow
|
|
}
|
|
Write-Host ''
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Interactive menu
|
|
# ---------------------------------------------------------------------------
|
|
function Start-Menu {
|
|
param($Controls) # full catalog; the active view is filtered by user mode
|
|
while ($true) {
|
|
$view = @(Select-ActiveControls -All $Controls)
|
|
Show-Status -Controls $view
|
|
Write-Host 'Commands:' -ForegroundColor White
|
|
Write-Host ' <n> toggle item n (Enable<->Disable)'
|
|
Write-Host ' e <n> enable item n'
|
|
Write-Host ' d <n> disable item n'
|
|
Write-Host ' D disable ALL shown (harden; keeps [SEC] SmartScreen ON)'
|
|
Write-Host ' E enable ALL shown (restore Windows default)'
|
|
Write-Host ' S disable ALL [SEC] SmartScreen features (reduces security)'
|
|
Write-Host ' G GO DARK - disable EVERYTHING incl [SEC] + [NET] (max privacy)'
|
|
Write-Host ' X close [CRIT] items (Update/Time) one-by-one with confirm'
|
|
if ($Script:UserMode) {
|
|
Write-Host ' m switch to FULL mode (also show system-wide items)'
|
|
} else {
|
|
Write-Host ' m switch to USER mode (per-user items only, no admin)'
|
|
}
|
|
Write-Host ' r refresh view'
|
|
Write-Host ' c <path> export status to CSV'
|
|
Write-Host ' q quit'
|
|
Write-Host ''
|
|
$inp = Read-Host 'Select'
|
|
if ([string]::IsNullOrWhiteSpace($inp)) { continue }
|
|
$inp = $inp.Trim()
|
|
|
|
# -CaseSensitive so bare "d"/"e" do NOT match the ALL branches below
|
|
switch -Regex -CaseSensitive ($inp) {
|
|
'^[Qq]$' { return }
|
|
'^[Rr]$' { continue }
|
|
'^[Mm]$' { $Script:UserMode = -not $Script:UserMode; continue }
|
|
'^D$' {
|
|
if ((Read-Host 'Disable ALL shown telemetry? type YES') -ceq 'YES') {
|
|
Invoke-AllAction -Controls $view -Action Disable
|
|
}
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^E$' {
|
|
if ((Read-Host 'Enable ALL shown (Windows default)? type YES') -ceq 'YES') {
|
|
Invoke-AllAction -Controls $view -Action Enable
|
|
}
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^S$' {
|
|
$secList = @($view | Where-Object { $_.Security })
|
|
if ($secList.Count -eq 0) {
|
|
Write-Host 'No [SEC] controls shown (they are system-wide; switch to FULL mode with "m").' -ForegroundColor DarkYellow
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
Write-Host ''
|
|
Write-Host 'WARNING: This turns OFF Windows SmartScreen reputation checks' -ForegroundColor Red
|
|
Write-Host ('for {0} item(s). Windows will no longer warn about known' -f $secList.Count) -ForegroundColor Red
|
|
Write-Host 'malicious apps, files and phishing pages.' -ForegroundColor Red
|
|
if ((Read-Host 'Proceed? type DISABLE-SECURITY') -ceq 'DISABLE-SECURITY') {
|
|
Invoke-AllAction -Controls $secList -Action Disable -WithSecurity
|
|
}
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^G$' {
|
|
Write-Host ''
|
|
Write-Host '============================ GO DARK ============================' -ForegroundColor Red
|
|
Write-Host 'Disables EVERYTHING shown: telemetry + [SEC] anti-malware reputation' -ForegroundColor Red
|
|
Write-Host '(SmartScreen, Defender cloud) + [NET] ambient callbacks (connectivity' -ForegroundColor Red
|
|
Write-Host 'probe, root-cert auto-update, Store updates, font/DRM). This REDUCES' -ForegroundColor Red
|
|
Write-Host 'SECURITY and can BREAK functionality. Windows Update, activation,' -ForegroundColor Red
|
|
Write-Host 'cert revocation and time sync are intentionally left working.' -ForegroundColor Red
|
|
Write-Host 'Reverse anytime with E (enable all).' -ForegroundColor DarkYellow
|
|
Write-Host '==================================================================' -ForegroundColor Red
|
|
if ((Read-Host 'Proceed? type GO-DARK') -ceq 'GO-DARK') {
|
|
Invoke-AllAction -Controls $view -Action Disable -WithSecurity -WithGoDark
|
|
}
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^[Cc]\s+(.+)$' {
|
|
Export-StatusCsv -Controls $view -Path $Matches[1].Trim('"')
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^[Ee]\s+(\d+)$' {
|
|
$n = [int]$Matches[1]
|
|
if ($n -ge 1 -and $n -le $view.Count) { Invoke-ControlAction -Ctrl $view[$n-1] -Action Enable }
|
|
else { Write-Host 'Out of range' -ForegroundColor Red }
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^[Dd]\s+(\d+)$' {
|
|
$n = [int]$Matches[1]
|
|
if ($n -ge 1 -and $n -le $view.Count) {
|
|
$ctrl = $view[$n-1]
|
|
if ($ctrl.Critical) { Invoke-ConfirmClose -Ctrl $ctrl } else { Invoke-ControlAction -Ctrl $ctrl -Action Disable }
|
|
} else { Write-Host 'Out of range' -ForegroundColor Red }
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^X$' {
|
|
$critList = @($view | Where-Object { $_.Critical })
|
|
if ($critList.Count -eq 0) {
|
|
Write-Host 'No [CRIT] items shown.' -ForegroundColor DarkYellow
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
Write-Host ''
|
|
Write-Host ('Closing {0} [CRIT] connection(s), one at a time with confirmation.' -f $critList.Count) -ForegroundColor Red
|
|
Write-Host 'These break patching / time sync / trust. Reverse with E (enable all).' -ForegroundColor DarkYellow
|
|
foreach ($ctrl in $critList) { Invoke-ConfirmClose -Ctrl $ctrl }
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
'^\d+$' {
|
|
$n = [int]$inp
|
|
if ($n -ge 1 -and $n -le $view.Count) {
|
|
$ctrl = $view[$n-1]
|
|
$state = Get-ControlState -Ctrl $ctrl
|
|
if ($state -like 'Enabled*') {
|
|
if ($ctrl.Critical) { Invoke-ConfirmClose -Ctrl $ctrl } else { Invoke-ControlAction -Ctrl $ctrl -Action Disable }
|
|
} else { Invoke-ControlAction -Ctrl $ctrl -Action Enable }
|
|
} else { Write-Host 'Out of range' -ForegroundColor Red }
|
|
Read-Host 'Press Enter'; continue
|
|
}
|
|
default { Write-Host 'Unknown command (d/e need an item number; D/E/S/G/X/m act on the view)' -ForegroundColor Red; Start-Sleep -Milliseconds 600 }
|
|
}
|
|
}
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Main
|
|
# ---------------------------------------------------------------------------
|
|
$controls = Get-Controls
|
|
$active = @(Select-ActiveControls -All $controls)
|
|
|
|
if ($IncludeSecurity -and -not $DisableAll) {
|
|
Write-Host 'NOTE: -IncludeSecurity only has an effect together with -DisableAll; ignoring it.' -ForegroundColor DarkYellow
|
|
}
|
|
if ($UserMode) {
|
|
Write-Host ('USER MODE: showing {0} per-user item(s) only (no admin needed).' -f $active.Count) -ForegroundColor Magenta
|
|
}
|
|
|
|
if ($GoDark) {
|
|
Write-Host ''
|
|
Write-Host 'GO DARK: disabling ALL telemetry + [SEC] security + [NET] ambient callbacks.' -ForegroundColor Red
|
|
Write-Host 'Reduces security and can break functionality. Reverse with -EnableAll.' -ForegroundColor DarkYellow
|
|
Invoke-AllAction -Controls $active -Action Disable -WithSecurity -WithGoDark
|
|
Show-Status -Controls $active
|
|
if ($Csv) { Export-StatusCsv -Controls $active -Path $Csv }
|
|
return
|
|
}
|
|
if ($DisableAll) {
|
|
Invoke-AllAction -Controls $active -Action Disable -WithSecurity:$IncludeSecurity
|
|
Show-Status -Controls $active
|
|
if ($Csv) { Export-StatusCsv -Controls $active -Path $Csv }
|
|
return
|
|
}
|
|
if ($EnableAll) {
|
|
Invoke-AllAction -Controls $active -Action Enable
|
|
Show-Status -Controls $active
|
|
if ($Csv) { Export-StatusCsv -Controls $active -Path $Csv }
|
|
return
|
|
}
|
|
if ($Report -or $Csv) {
|
|
if ($Report) { Show-Status -Controls $active }
|
|
if ($Csv) { Export-StatusCsv -Controls $active -Path $Csv }
|
|
return
|
|
}
|
|
|
|
if ($UserMode) {
|
|
Write-Host ''
|
|
Write-Host 'USER MODE is on: changes apply to YOUR account only and need no' -ForegroundColor Magenta
|
|
Write-Host 'elevation. Press "m" in the menu to include system-wide items.' -ForegroundColor Magenta
|
|
} elseif (-not $Script:IsAdmin) {
|
|
Write-Host ''
|
|
Write-Host 'NOTE: Not running as Administrator. HKLM / service / task items' -ForegroundColor DarkYellow
|
|
Write-Host ' show as read-only (*). Use -UserMode (or "m") to work with' -ForegroundColor DarkYellow
|
|
Write-Host ' per-user items only, or relaunch elevated for the rest.' -ForegroundColor DarkYellow
|
|
}
|
|
|
|
# Start-Menu always receives the full catalog; user mode filters the view.
|
|
Start-Menu -Controls $controls
|