first commit

This commit is contained in:
drjones
2026-05-23 21:58:06 -07:00
commit 1f5e63ca1f
73 changed files with 13565 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
"""Windows version / PowerShell capability probe.
Used by privacy features to log a single clear reason when a function silently
no-ops on older Windows Server hosts (Server 2008 R2 ships PowerShell 2.0 which
does not have ``Get-NetAdapter`` / ``Set-NetAdapter`` / ``Disable-NetAdapterBinding``
/ ``Get-DnsClientServerAddress`` / ``Rename-Computer``).
"""
from __future__ import annotations
import logging
import platform
import subprocess
import sys
from dataclasses import dataclass
from functools import lru_cache
log = logging.getLogger(__name__)
@dataclass(frozen=True)
class WinCompat:
release: str # e.g. "10", "2012ServerR2"
build: int # major build number
powershell_major: int # 0 = PowerShell not detected
has_net_cmdlets: bool # Get-NetAdapter etc. (PS 3.0+ on Server 2012+)
has_defender: bool # Add-MpPreference cmdlet exists
def summary(self) -> str:
if sys.platform != "win32":
return (
f"{platform.system()} release={self.release} "
f"PowerShell={self.powershell_major}.x "
"Windows-only privacy controls disabled"
)
return (
f"Windows release={self.release} build={self.build} "
f"PowerShell={self.powershell_major}.x "
f"NetAdapter cmdlets={'yes' if self.has_net_cmdlets else 'no'} "
f"Defender={'yes' if self.has_defender else 'no'}"
)
def _powershell_major() -> int:
try:
r = subprocess.run(
["powershell", "-NoProfile", "-NonInteractive", "-Command",
"$PSVersionTable.PSVersion.Major"],
capture_output=True,
text=True,
timeout=12,
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0),
)
out = (r.stdout or "").strip().splitlines()[-1] if r.stdout else ""
return int(out) if out.isdigit() else 0
except Exception:
return 0
def _has_cmdlet(name: str) -> bool:
try:
r = subprocess.run(
["powershell", "-NoProfile", "-NonInteractive", "-Command",
f"if (Get-Command {name} -ErrorAction SilentlyContinue) "
f"{{ 'yes' }} else {{ 'no' }}"],
capture_output=True,
text=True,
timeout=10,
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0),
)
return "yes" in (r.stdout or "").lower()
except Exception:
return False
@lru_cache(maxsize=1)
def probe() -> WinCompat:
"""Cached host probe. Cheap on subsequent calls."""
if sys.platform != "win32":
info = WinCompat(
release=platform.release(),
build=0,
powershell_major=0,
has_net_cmdlets=False,
has_defender=False,
)
log.info("Compat probe: %s", info.summary())
return info
release = platform.release()
try:
build = int(platform.version().split(".")[-1])
except Exception:
build = 0
ps = _powershell_major()
# PowerShell >= 3.0 is the gate for the modern Net* cmdlets that all the
# privacy features rely on. Anything older (Server 2008 R2 RTM) only has
# PS 2.0 and needs WMI / netsh / ipconfig fallbacks.
has_net = ps >= 3 and _has_cmdlet("Get-NetAdapter")
has_def = _has_cmdlet("Add-MpPreference")
info = WinCompat(
release=release,
build=build,
powershell_major=ps,
has_net_cmdlets=has_net,
has_defender=has_def,
)
log.info("WinCompat probe: %s", info.summary())
return info