Files
SERVtomaste/Solidworks Licenses/scripts/00-install-privacy-lockdown.ps1
Anto01 57bcfa4a9a Add Solidworks licenses, scripts, and update server docs
- Add Solidworks license files and install guides
- Add PowerShell privacy lockdown scripts for Solidworks telemetry
- Add Siemens License Server v5.1 binary for NX
- Update DALIDOU-SERVER.md with storage layout, backup system, and DNS fixes
- Add MEGA-PLAN-BRAIN-SYSTEM.md for unified knowledge management
- Add Claude Code local settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 11:56:23 -05:00

697 lines
23 KiB
PowerShell

#Requires -RunAsAdministrator
<#
.SYNOPSIS
Master installation script for SolidWorks Privacy Lockdown.
.DESCRIPTION
Runs all privacy lockdown components in sequence:
1. Blocks telemetry domains via hosts file
2. Disables update/background services
3. Configures firewall rules
4. Disables in-app telemetry via registry
5. Verifies the lockdown
Generates a detailed report of all changes made.
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
Run this script to apply all privacy protections at once.
.EXAMPLE
.\00-install-privacy-lockdown.ps1
Applies all privacy protections.
.EXAMPLE
.\00-install-privacy-lockdown.ps1 -Undo
Removes all privacy protections and restores original settings.
.EXAMPLE
.\00-install-privacy-lockdown.ps1 -DryRun
Shows what would be changed without making any modifications.
#>
param(
[switch]$Undo, # Remove all protections
[switch]$DryRun, # Preview changes without applying
[switch]$SkipVerify, # Skip verification step
[string]$InstallPath = "C:\Program Files\SOLIDWORKS Corp",
[string]$ReportPath # Custom report path (default: script directory)
)
$scriptDir = $PSScriptRoot
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$reportDir = if ($ReportPath) { $ReportPath } else { Join-Path $scriptDir "reports" }
$reportFile = Join-Path $reportDir "lockdown-report_$timestamp.txt"
# Global report content
$script:report = @()
$script:changes = @{
HostsFile = @()
Services = @()
Firewall = @()
Registry = @()
}
function Initialize-Report {
# Create reports directory if needed
if (-not (Test-Path $reportDir)) {
New-Item -Path $reportDir -ItemType Directory -Force | Out-Null
}
$header = @"
================================================================================
SOLIDWORKS PRIVACY LOCKDOWN REPORT
Generated: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
Computer: $env:COMPUTERNAME
User: $env:USERNAME
Mode: $(if ($Undo) { "UNINSTALL" } elseif ($DryRun) { "DRY RUN (preview)" } else { "INSTALL" })
================================================================================
"@
$script:report += $header
Write-Host $header -ForegroundColor Cyan
}
function Add-ReportSection {
param(
[string]$Title,
[string]$Content
)
$section = @"
--------------------------------------------------------------------------------
$Title
--------------------------------------------------------------------------------
$Content
"@
$script:report += $section
}
function Add-ReportLine {
param([string]$Line)
$script:report += $Line
}
function Write-Log {
param(
[string]$Message,
[string]$Level = "INFO", # INFO, OK, WARN, ERROR, CHANGE
[string]$Category # HostsFile, Services, Firewall, Registry
)
$prefix = switch ($Level) {
"OK" { "[OK] "; $color = "Green" }
"WARN" { "[WARN] "; $color = "Yellow" }
"ERROR" { "[ERROR] "; $color = "Red" }
"CHANGE" { "[CHANGE]"; $color = "Magenta" }
"SKIP" { "[SKIP] "; $color = "Gray" }
"BEFORE" { "[BEFORE]"; $color = "DarkGray" }
"AFTER" { "[AFTER] "; $color = "White" }
default { "[INFO] "; $color = "White" }
}
$logLine = "$prefix $Message"
Write-Host $logLine -ForegroundColor $color
Add-ReportLine $logLine
# Track changes by category
if ($Category -and $Level -eq "CHANGE") {
$script:changes[$Category] += $Message
}
}
function Save-Report {
# Add summary section
$summary = @"
================================================================================
CHANGES SUMMARY
================================================================================
HOSTS FILE CHANGES ($($script:changes.HostsFile.Count)):
"@
if ($script:changes.HostsFile.Count -eq 0) {
$summary += "`n (no changes)"
} else {
foreach ($change in $script:changes.HostsFile) {
$summary += "`n - $change"
}
}
$summary += @"
SERVICES CHANGES ($($script:changes.Services.Count)):
"@
if ($script:changes.Services.Count -eq 0) {
$summary += "`n (no changes)"
} else {
foreach ($change in $script:changes.Services) {
$summary += "`n - $change"
}
}
$summary += @"
FIREWALL CHANGES ($($script:changes.Firewall.Count)):
"@
if ($script:changes.Firewall.Count -eq 0) {
$summary += "`n (no changes)"
} else {
foreach ($change in $script:changes.Firewall) {
$summary += "`n - $change"
}
}
$summary += @"
REGISTRY CHANGES ($($script:changes.Registry.Count)):
"@
if ($script:changes.Registry.Count -eq 0) {
$summary += "`n (no changes)"
} else {
foreach ($change in $script:changes.Registry) {
$summary += "`n - $change"
}
}
$totalChanges = $script:changes.HostsFile.Count + $script:changes.Services.Count +
$script:changes.Firewall.Count + $script:changes.Registry.Count
$summary += @"
================================================================================
TOTAL CHANGES: $totalChanges
REPORT SAVED: $reportFile
================================================================================
"@
$script:report += $summary
# Write report to file
$script:report -join "`n" | Set-Content -Path $reportFile -Force -Encoding UTF8
Write-Host ""
Write-Host "========================================" -ForegroundColor Green
Write-Host " REPORT SAVED" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Green
Write-Host " Location: $reportFile" -ForegroundColor White
Write-Host " Total changes: $totalChanges" -ForegroundColor White
Write-Host ""
}
function Test-IsAdmin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Get-SystemState {
Add-ReportSection -Title "SYSTEM STATE BEFORE CHANGES" -Content ""
# Hosts file state
Write-Log "Checking hosts file..." -Level "INFO"
$hostsPath = "C:\Windows\System32\drivers\etc\hosts"
$hostsContent = Get-Content $hostsPath -Raw -ErrorAction SilentlyContinue
if ($hostsContent -match "SOLIDWORKS TELEMETRY BLOCK") {
Write-Log "Hosts file: SolidWorks block already present" -Level "BEFORE"
} else {
Write-Log "Hosts file: No SolidWorks block found" -Level "BEFORE"
}
# Services state
Write-Log "Checking services..." -Level "INFO"
$services = Get-Service -DisplayName "*SOLIDWORKS*","*3DEXPERIENCE*","*Dassault*" -ErrorAction SilentlyContinue
if ($services) {
foreach ($svc in $services) {
Write-Log "Service: $($svc.DisplayName) - Status: $($svc.Status), StartType: $($svc.StartType)" -Level "BEFORE"
}
} else {
Write-Log "Services: No SolidWorks services found" -Level "BEFORE"
}
# Firewall rules state
Write-Log "Checking firewall rules..." -Level "INFO"
$rules = Get-NetFirewallRule -DisplayName "SolidWorks Privacy -*" -ErrorAction SilentlyContinue
if ($rules) {
foreach ($rule in $rules) {
Write-Log "Firewall: $($rule.DisplayName) - Action: $($rule.Action), Enabled: $($rule.Enabled)" -Level "BEFORE"
}
} else {
Write-Log "Firewall: No SolidWorks Privacy rules found" -Level "BEFORE"
}
# Registry state
Write-Log "Checking registry..." -Level "INFO"
$swBasePath = "HKCU:\Software\SolidWorks"
if (Test-Path $swBasePath) {
$versions = Get-ChildItem -Path $swBasePath -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -like "SOLIDWORKS *" }
foreach ($version in $versions) {
Write-Log "Registry: Found $($version.PSChildName)" -Level "BEFORE"
$perfPath = Join-Path $version.PSPath "Performance"
if (Test-Path $perfPath) {
$props = Get-ItemProperty -Path $perfPath -ErrorAction SilentlyContinue
if ($props.PSObject.Properties.Name -contains "OptInStatus") {
Write-Log " CEIP OptInStatus = $($props.OptInStatus)" -Level "BEFORE"
}
}
}
} else {
Write-Log "Registry: No SolidWorks keys found (SW may not be installed)" -Level "BEFORE"
}
Add-ReportLine ""
}
function Apply-HostsFileBlock {
Add-ReportSection -Title "HOSTS FILE MODIFICATIONS" -Content ""
$hostsPath = "C:\Windows\System32\drivers\etc\hosts"
$backupPath = "C:\Windows\System32\drivers\etc\hosts.backup.solidworks.$timestamp"
$blockDomains = @(
"api.3ds.com",
"www.3ds.com",
"swym.3ds.com",
"iam.3ds.com",
"cas.3ds.com",
"eu1-ds-iam.3dexperience.3ds.com",
"eu1-ds.3dexperience.3ds.com",
"update.solidworks.com",
"www.solidworks.com",
"sentry.io",
"o136956.ingest.sentry.io",
"telemetry.solidworks.com",
"analytics.3ds.com",
"collect.3ds.com",
"ifwe.3ds.com",
"eu1-ifwe.3dexperience.3ds.com",
"passport.3ds.com",
"3dswym.3ds.com"
)
$licensingDomains = @(
"activation.solidworks.com",
"license.solidworks.com",
"licensing.solidworks.com"
)
Write-Log "Licensing domains (preserved):" -Level "INFO"
foreach ($domain in $licensingDomains) {
Write-Log " ALLOW: $domain" -Level "OK"
}
Write-Log "" -Level "INFO"
Write-Log "Telemetry domains to block:" -Level "INFO"
if ($DryRun) {
foreach ($domain in $blockDomains) {
Write-Log " Would block: $domain" -Level "INFO"
}
Write-Log "[DRY RUN] No changes made to hosts file" -Level "WARN"
return
}
# Backup
Copy-Item -Path $hostsPath -Destination $backupPath -Force
Write-Log "Backup created: $backupPath" -Level "OK"
$content = Get-Content $hostsPath -Raw
$markerStart = "# === SOLIDWORKS TELEMETRY BLOCK START ==="
$markerEnd = "# === SOLIDWORKS TELEMETRY BLOCK END ==="
# Remove existing block if present
if ($content -match [regex]::Escape($markerStart)) {
$pattern = "$([regex]::Escape($markerStart))[\s\S]*?$([regex]::Escape($markerEnd))\r?\n?"
$content = $content -replace $pattern, ""
Write-Log "Removed existing block" -Level "INFO"
}
# Build new block
$blockContent = @()
$blockContent += ""
$blockContent += $markerStart
$blockContent += "# Blocks telemetry/analytics while preserving licensing"
$blockContent += "# Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$blockContent += "#"
foreach ($domain in $blockDomains) {
$blockContent += "127.0.0.1 $domain"
Write-Log "BLOCKED: $domain -> 127.0.0.1" -Level "CHANGE" -Category "HostsFile"
}
$blockContent += $markerEnd
# Apply
Set-Content -Path $hostsPath -Value $content.TrimEnd() -Force -NoNewline
Add-Content -Path $hostsPath -Value ($blockContent -join "`r`n") -Force
Write-Log "Hosts file updated successfully" -Level "OK"
}
function Remove-HostsFileBlock {
Add-ReportSection -Title "HOSTS FILE RESTORATION" -Content ""
$hostsPath = "C:\Windows\System32\drivers\etc\hosts"
$content = Get-Content $hostsPath -Raw
$markerStart = "# === SOLIDWORKS TELEMETRY BLOCK START ==="
$markerEnd = "# === SOLIDWORKS TELEMETRY BLOCK END ==="
if ($DryRun) {
if ($content -match [regex]::Escape($markerStart)) {
Write-Log "[DRY RUN] Would remove SolidWorks block from hosts file" -Level "WARN"
} else {
Write-Log "[DRY RUN] No SolidWorks block found to remove" -Level "INFO"
}
return
}
if ($content -match [regex]::Escape($markerStart)) {
$pattern = "$([regex]::Escape($markerStart))[\s\S]*?$([regex]::Escape($markerEnd))\r?\n?"
$newContent = $content -replace $pattern, ""
Set-Content -Path $hostsPath -Value $newContent.TrimEnd() -Force -NoNewline
Add-Content -Path $hostsPath -Value ""
Write-Log "Removed SolidWorks telemetry block from hosts file" -Level "CHANGE" -Category "HostsFile"
} else {
Write-Log "No SolidWorks block found in hosts file" -Level "SKIP"
}
}
function Manage-Services {
param([switch]$Restore)
$title = if ($Restore) { "SERVICES RESTORATION" } else { "SERVICES MODIFICATIONS" }
Add-ReportSection -Title $title -Content ""
$stateFile = "$env:USERPROFILE\solidworks-services-backup.json"
$services = Get-Service -DisplayName "*SOLIDWORKS*","*3DEXPERIENCE*","*Dassault*" -ErrorAction SilentlyContinue
if (-not $services -or $services.Count -eq 0) {
Write-Log "No SolidWorks services found on this system" -Level "INFO"
return
}
if ($Restore) {
if ($DryRun) {
Write-Log "[DRY RUN] Would restore services from: $stateFile" -Level "WARN"
return
}
if (Test-Path $stateFile) {
$states = Get-Content -Path $stateFile -Raw | ConvertFrom-Json
foreach ($serviceName in $states.PSObject.Properties.Name) {
$originalState = $states.$serviceName
try {
Set-Service -Name $serviceName -StartupType $originalState.StartType -ErrorAction Stop
Write-Log "Restored: $($originalState.DisplayName) -> $($originalState.StartType)" -Level "CHANGE" -Category "Services"
} catch {
Write-Log "Failed to restore $serviceName : $_" -Level "ERROR"
}
}
} else {
Write-Log "No backup file found: $stateFile" -Level "WARN"
}
return
}
# Save current states
$states = @{}
foreach ($svc in $services) {
$states[$svc.Name] = @{
DisplayName = $svc.DisplayName
Status = $svc.Status.ToString()
StartType = $svc.StartType.ToString()
}
}
if (-not $DryRun) {
$states | ConvertTo-Json -Depth 3 | Set-Content -Path $stateFile -Force
Write-Log "Service states backed up to: $stateFile" -Level "OK"
}
foreach ($svc in $services) {
$isUpdateService = $svc.DisplayName -match "update|download|background|3dexperience"
if ($isUpdateService) {
if ($DryRun) {
Write-Log "[DRY RUN] Would disable: $($svc.DisplayName) (currently: $($svc.StartType))" -Level "WARN"
} else {
try {
if ($svc.Status -eq "Running") {
Stop-Service -Name $svc.Name -Force -ErrorAction Stop
Write-Log "Stopped: $($svc.DisplayName)" -Level "OK"
}
Set-Service -Name $svc.Name -StartupType Disabled -ErrorAction Stop
Write-Log "Disabled: $($svc.DisplayName) (was: $($svc.StartType))" -Level "CHANGE" -Category "Services"
} catch {
Write-Log "Failed to disable $($svc.DisplayName): $_" -Level "ERROR"
}
}
} else {
Write-Log "Preserved: $($svc.DisplayName) ($($svc.StartType))" -Level "SKIP"
}
}
}
function Manage-Firewall {
param([switch]$Remove)
$title = if ($Remove) { "FIREWALL RULES REMOVAL" } else { "FIREWALL RULES CONFIGURATION" }
Add-ReportSection -Title $title -Content ""
$rulePrefix = "SolidWorks Privacy - "
if ($Remove) {
$rules = Get-NetFirewallRule -DisplayName "$rulePrefix*" -ErrorAction SilentlyContinue
if ($DryRun) {
if ($rules) {
Write-Log "[DRY RUN] Would remove $($rules.Count) firewall rule(s)" -Level "WARN"
} else {
Write-Log "[DRY RUN] No firewall rules to remove" -Level "INFO"
}
return
}
if ($rules) {
foreach ($rule in $rules) {
$rules | Remove-NetFirewallRule
Write-Log "Removed rule: $($rule.DisplayName)" -Level "CHANGE" -Category "Firewall"
}
} else {
Write-Log "No SolidWorks firewall rules found" -Level "SKIP"
}
return
}
# Find executables to block
$execsToBlock = @(
"SOLIDWORKS\swScheduler\dxttasks.exe",
"SOLIDWORKS\swScheduler\DXTTask.exe",
"SOLIDWORKS Installation Manager\sldIM.exe",
"SOLIDWORKS Installation Manager\sldDownloader.exe"
)
if (-not (Test-Path $InstallPath)) {
Write-Log "SolidWorks installation not found at: $InstallPath" -Level "WARN"
Write-Log "Firewall rules will be created when SolidWorks is installed" -Level "INFO"
return
}
foreach ($exe in $execsToBlock) {
$fullPath = Join-Path $InstallPath $exe
$exeName = Split-Path $fullPath -Leaf
$ruleName = "$rulePrefix Block $exeName"
if (-not (Test-Path $fullPath)) {
Write-Log "Executable not found: $exe" -Level "SKIP"
continue
}
$existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
if ($existing) {
Write-Log "Rule already exists: $exeName" -Level "SKIP"
continue
}
if ($DryRun) {
Write-Log "[DRY RUN] Would create block rule for: $exeName" -Level "WARN"
} else {
try {
New-NetFirewallRule `
-DisplayName $ruleName `
-Description "Blocks outbound for SolidWorks update/telemetry" `
-Direction Outbound `
-Action Block `
-Program $fullPath `
-Enabled True `
-Profile Any `
-ErrorAction Stop | Out-Null
Write-Log "Created block rule: $exeName" -Level "CHANGE" -Category "Firewall"
} catch {
Write-Log "Failed to create rule for $exeName : $_" -Level "ERROR"
}
}
}
}
function Manage-Registry {
param([switch]$Restore)
$title = if ($Restore) { "REGISTRY RESTORATION" } else { "REGISTRY MODIFICATIONS" }
Add-ReportSection -Title $title -Content ""
$swBasePath = "HKCU:\Software\SolidWorks"
if (-not (Test-Path $swBasePath)) {
Write-Log "SolidWorks registry keys not found" -Level "WARN"
Write-Log "Run this script again after launching SolidWorks" -Level "INFO"
return
}
$versions = Get-ChildItem -Path $swBasePath -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -like "SOLIDWORKS *" }
if (-not $versions) {
Write-Log "No SolidWorks version keys found" -Level "WARN"
return
}
$settings = @(
@{ Path = "Performance"; Name = "OptInStatus"; DisableValue = 0; Desc = "CEIP" },
@{ Path = "General"; Name = "Auto Check for Updates"; DisableValue = 0; Desc = "Auto Updates" },
@{ Path = "Performance"; Name = "EnableAnalytics"; DisableValue = 0; Desc = "Analytics" },
@{ Path = "Performance"; Name = "EnableTelemetry"; DisableValue = 0; Desc = "Telemetry" }
)
foreach ($version in $versions) {
Write-Log "Processing: $($version.PSChildName)" -Level "INFO"
foreach ($setting in $settings) {
$regPath = Join-Path $version.PSPath $setting.Path
if (-not (Test-Path $regPath)) {
Write-Log " Path not found: $($setting.Path)" -Level "SKIP"
continue
}
$props = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue
$currentValue = $props.PSObject.Properties[$setting.Name].Value
if ($Restore) {
# Restore to enabled (1)
if ($DryRun) {
Write-Log "[DRY RUN] Would restore $($setting.Desc) to enabled" -Level "WARN"
} else {
try {
Set-ItemProperty -Path $regPath -Name $setting.Name -Value 1 -Type DWord -Force
Write-Log "Restored: $($setting.Desc) = 1 (enabled)" -Level "CHANGE" -Category "Registry"
} catch {
Write-Log "Failed to restore $($setting.Desc): $_" -Level "ERROR"
}
}
} else {
# Disable
if ($null -ne $currentValue -and $currentValue -eq $setting.DisableValue) {
Write-Log " $($setting.Desc): Already disabled" -Level "SKIP"
continue
}
if ($DryRun) {
Write-Log "[DRY RUN] Would disable $($setting.Desc) (current: $currentValue)" -Level "WARN"
} else {
try {
Set-ItemProperty -Path $regPath -Name $setting.Name -Value $setting.DisableValue -Type DWord -Force
Write-Log "Disabled: $($setting.Desc) (was: $currentValue -> now: $($setting.DisableValue))" -Level "CHANGE" -Category "Registry"
} catch {
Write-Log "Failed to disable $($setting.Desc): $_" -Level "ERROR"
}
}
}
}
}
}
# Main execution
if (-not (Test-IsAdmin)) {
Write-Host "[ERROR] This script requires Administrator privileges." -ForegroundColor Red
Write-Host "Please right-click PowerShell and select 'Run as Administrator'" -ForegroundColor Yellow
exit 1
}
Initialize-Report
if ($DryRun) {
Write-Host ""
Write-Host "*** DRY RUN MODE - No changes will be made ***" -ForegroundColor Yellow
Write-Host ""
}
# Capture initial state
Get-SystemState
if ($Undo) {
Add-ReportSection -Title "REMOVING PRIVACY LOCKDOWN" -Content ""
if (-not $DryRun) {
Write-Host ""
$confirm = Read-Host "Are you sure you want to remove privacy protections? (y/N)"
if ($confirm -ne "y" -and $confirm -ne "Y") {
Write-Log "Operation cancelled by user" -Level "WARN"
Save-Report
exit 0
}
}
Manage-Registry -Restore
Manage-Firewall -Remove
Manage-Services -Restore
Remove-HostsFileBlock
} else {
Add-ReportSection -Title "APPLYING PRIVACY LOCKDOWN" -Content ""
if (-not $DryRun) {
Write-Host ""
Write-Host "This will configure:" -ForegroundColor White
Write-Host " - Block telemetry domains in hosts file" -ForegroundColor Gray
Write-Host " - Disable update/background services" -ForegroundColor Gray
Write-Host " - Create firewall block rules" -ForegroundColor Gray
Write-Host " - Disable telemetry in registry" -ForegroundColor Gray
Write-Host ""
Write-Host "Licensing will remain functional." -ForegroundColor Green
Write-Host ""
$confirm = Read-Host "Proceed? (Y/n)"
if ($confirm -eq "n" -or $confirm -eq "N") {
Write-Log "Operation cancelled by user" -Level "WARN"
Save-Report
exit 0
}
}
Apply-HostsFileBlock
Manage-Services
Manage-Firewall
Manage-Registry
}
Save-Report
if ($DryRun) {
Write-Host ""
Write-Host "*** DRY RUN COMPLETE - No changes were made ***" -ForegroundColor Yellow
Write-Host "Review the report above. Run without -DryRun to apply changes." -ForegroundColor Yellow
}