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>
This commit is contained in:
2025-12-25 11:56:23 -05:00
parent 222c604203
commit 57bcfa4a9a
17 changed files with 8162 additions and 43 deletions

View File

@@ -0,0 +1,24 @@
{
"permissions": {
"allow": [
"Bash(ping:*)",
"Bash(powershell:*)",
"Bash(ssh root@dalidou:*)",
"Bash(ssh:*)",
"Bash(scp:*)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" status)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" log --oneline -5)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" diff \"NX Licenses/License_Ugslmd.txt\")",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" add \"NX Licenses/License_Ugslmd.txt\")",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" commit -m \"$(cat <<''EOF''\nUpdate NX license file to version 2512 (expires Mar 2026)\n\n- Updated license from v2506 to v2512\n- Set SERVER hostname to dalidou with COMPOSITE ID\n- New license valid until March 2026\n- Also upgraded license server on dalidou from v5.0 to v5.1\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n)\")",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" push)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" remote -v)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" push http://Antoine:a380f5fe06e06d1e847aeac8d7d1b383e7693946@192.168.86.50:3000/Antoine/SERVtomaste.git main)",
"Bash(git config:*)",
"Bash(dir:*)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" log --oneline -3)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" diff docs/DALIDOU-SERVER.md)",
"Bash(git -C \"C:\\Users\\antoi\\SERVtomaste\" add -A)"
]
}
}

Binary file not shown.

View File

@@ -0,0 +1,296 @@
# SolidWorks Privacy Lockdown
**Author:** Atomaste Solution
**Purpose:** Block telemetry while preserving license transfer functionality
## Overview
This solution blocks all telemetry, analytics, and unnecessary communications from SolidWorks to Dassault Systèmes servers while preserving the ability to:
- Activate licenses
- Deactivate licenses
- Transfer licenses between machines
## Quick Start
### Preview Changes (Dry Run - RECOMMENDED FIRST)
```powershell
# Open PowerShell as Administrator, then run:
cd "C:\Users\antoi\SERVtomaste\Solidworks Licenses\scripts"
.\00-install-privacy-lockdown.ps1 -DryRun
```
This shows exactly what would be changed **without modifying anything**. A report is generated.
### Install (Apply All Protections)
```powershell
.\00-install-privacy-lockdown.ps1
```
### Uninstall (Remove All Protections)
```powershell
.\00-install-privacy-lockdown.ps1 -Undo
```
### Verify Status
```powershell
.\05-verify-lockdown.ps1 -Detailed
```
## Reports
Every run generates a detailed report in `scripts/reports/`:
```
scripts/reports/
└── lockdown-report_2024-01-15_14-30-00.txt
```
### Report Contents
- **System State Before**: What was present before any changes
- **Changes Made**: Every modification with before/after values
- **Summary**: Count of changes by category (hosts, services, firewall, registry)
### Example Report Output
```
================================================================================
SOLIDWORKS PRIVACY LOCKDOWN REPORT
Generated: 2024-01-15 14:30:00
Computer: WORKSTATION-01
User: Antoine
Mode: INSTALL
================================================================================
SYSTEM STATE BEFORE CHANGES
[BEFORE] Hosts file: No SolidWorks block found
[BEFORE] Services: No SolidWorks services found
[BEFORE] Firewall: No SolidWorks Privacy rules found
HOSTS FILE MODIFICATIONS
[CHANGE] BLOCKED: telemetry.solidworks.com -> 127.0.0.1
[CHANGE] BLOCKED: analytics.3ds.com -> 127.0.0.1
...
CHANGES SUMMARY
HOSTS FILE CHANGES (18)
SERVICES CHANGES (0)
FIREWALL CHANGES (0)
REGISTRY CHANGES (0)
TOTAL CHANGES: 18
================================================================================
```
## What Gets Blocked
### Domains (via hosts file)
| Domain | Purpose | Status |
|--------|---------|--------|
| telemetry.solidworks.com | Telemetry | BLOCKED |
| analytics.3ds.com | Analytics | BLOCKED |
| collect.3ds.com | Data collection | BLOCKED |
| update.solidworks.com | Auto-updates | BLOCKED |
| api.3ds.com | 3DEXPERIENCE API | BLOCKED |
| swym.3ds.com | Social/community | BLOCKED |
| sentry.io | Error tracking | BLOCKED |
| o136956.ingest.sentry.io | Error tracking | BLOCKED |
### Services Disabled
- SOLIDWORKS Update Publisher Service
- SolidWorks Background Downloader
- Any 3DEXPERIENCE background services
### Firewall Rules
- Block outbound for: Update executables, Task schedulers, Downloaders
- Allow outbound for: SLDWORKS.exe (main app), License wizard
### Registry Settings
- Customer Experience Improvement Program: Disabled
- Auto Check for Updates: Disabled
- Send Usage Statistics: Disabled
- 3DEXPERIENCE Integration: Disabled
- Background Downloader: Disabled
## What Remains Accessible (Licensing)
| Domain | Purpose | Status |
|--------|---------|--------|
| activation.solidworks.com | License activation | ALLOWED |
| license.solidworks.com | License server | ALLOWED |
| licensing.solidworks.com | License management | ALLOWED |
## Scripts Reference
| Script | Purpose |
|--------|---------|
| `00-install-privacy-lockdown.ps1` | Master installer (runs all scripts) |
| `01-block-telemetry-hosts.ps1` | Modifies hosts file |
| `02-disable-services.ps1` | Disables Windows services |
| `03-configure-firewall.ps1` | Creates firewall rules |
| `04-disable-telemetry-registry.ps1` | Modifies registry settings |
| `05-verify-lockdown.ps1` | Verifies lockdown status |
## Individual Script Usage
Each script supports:
- `-Undo` : Reverse the changes
- `-ListOnly` : Preview changes without applying (where applicable)
### Examples
```powershell
# Preview what hosts file changes would be made
.\01-block-telemetry-hosts.ps1 -Undo # to remove
.\01-block-telemetry-hosts.ps1 # to apply
# List services without modifying
.\02-disable-services.ps1 -ListOnly
# Preview firewall rules
.\03-configure-firewall.ps1 -ListOnly
# Check current registry settings
.\04-disable-telemetry-registry.ps1 -ListOnly
```
## Troubleshooting
### License Activation Fails
1. Verify licensing domains are accessible:
```powershell
nslookup activation.solidworks.com
nslookup license.solidworks.com
```
2. Temporarily remove hosts file block:
```powershell
.\01-block-telemetry-hosts.ps1 -Undo
```
3. Complete license operation, then re-apply:
```powershell
.\01-block-telemetry-hosts.ps1
```
### SolidWorks Won't Launch
1. Run verification:
```powershell
.\05-verify-lockdown.ps1 -Detailed
```
2. Check if any critical service was disabled:
```powershell
.\02-disable-services.ps1 -ListOnly
```
3. Restore all settings:
```powershell
.\00-install-privacy-lockdown.ps1 -Undo
```
### Re-run After First SolidWorks Launch
Some registry settings only appear after SolidWorks runs for the first time. After initial launch:
```powershell
.\04-disable-telemetry-registry.ps1
```
## Backup Locations
| Component | Backup Location |
|-----------|-----------------|
| Hosts file | `C:\Windows\System32\drivers\etc\hosts.backup.solidworks` |
| Services | `%USERPROFILE%\solidworks-services-backup.json` |
| Registry | `%USERPROFILE%\solidworks-registry-backup.reg` |
## Reverting Changes
### Complete Removal
```powershell
.\00-install-privacy-lockdown.ps1 -Undo
```
### Individual Components
```powershell
.\01-block-telemetry-hosts.ps1 -Undo # Remove hosts entries
.\02-disable-services.ps1 -Undo # Restore services
.\03-configure-firewall.ps1 -Undo # Remove firewall rules
.\04-disable-telemetry-registry.ps1 -Undo # Restore registry
```
## Testing License Transfer
After applying the lockdown, verify license operations work:
1. **In SolidWorks:** Help > Transfer License > Deactivate
2. Wait for confirmation
3. Help > Transfer License > Activate on new machine
If this fails, the hosts file may be blocking a required domain. Check verification script output.
## Installation Log - ANTOINETHINKPAD
**Date:** 2025-12-23 20:18:01
**Computer:** ANTOINETHINKPAD
**SolidWorks Version:** SOLIDWORKS 2026
### Changes Applied (22 total)
#### Hosts File (18 domains blocked)
```
127.0.0.1 api.3ds.com
127.0.0.1 www.3ds.com
127.0.0.1 swym.3ds.com
127.0.0.1 iam.3ds.com
127.0.0.1 cas.3ds.com
127.0.0.1 eu1-ds-iam.3dexperience.3ds.com
127.0.0.1 eu1-ds.3dexperience.3ds.com
127.0.0.1 update.solidworks.com
127.0.0.1 www.solidworks.com
127.0.0.1 sentry.io
127.0.0.1 o136956.ingest.sentry.io
127.0.0.1 telemetry.solidworks.com
127.0.0.1 analytics.3ds.com
127.0.0.1 collect.3ds.com
127.0.0.1 ifwe.3ds.com
127.0.0.1 eu1-ifwe.3dexperience.3ds.com
127.0.0.1 passport.3ds.com
127.0.0.1 3dswym.3ds.com
```
#### Services
- **SolidWorks Licensing Service** - Preserved (Manual startup) - required for licensing
#### Registry (4 settings disabled)
- CEIP (Customer Experience Improvement Program) → 0
- Auto Check for Updates → 0
- Analytics → 0
- Telemetry → 0
#### Backups Created
- Hosts file: `C:\Windows\System32\drivers\etc\hosts.backup.solidworks.2025-12-23_20-18-01`
- Services: `C:\Users\antoi\solidworks-services-backup.json`
#### Full Report
See: `scripts/reports/lockdown-report_2025-12-23_20-18-01.txt`
## Notes
- All changes persist across reboots
- No third-party software required
- Uses only native Windows features (hosts, services, firewall, registry)
- Administrator privileges required for all operations
- Changes are fully reversible

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,696 @@
#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
}

View File

@@ -0,0 +1,177 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Blocks SolidWorks telemetry domains via hosts file while preserving licensing.
.DESCRIPTION
This script modifies the Windows hosts file to block telemetry/analytics
domains from Dassault Systèmes/SolidWorks while keeping licensing servers
accessible for license activation/deactivation.
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
Creates backup of hosts file before modification
#>
param(
[switch]$Undo # Use -Undo to restore the original hosts file
)
$hostsPath = "C:\Windows\System32\drivers\etc\hosts"
$backupPath = "C:\Windows\System32\drivers\etc\hosts.backup.solidworks"
$markerStart = "# === SOLIDWORKS TELEMETRY BLOCK START ==="
$markerEnd = "# === SOLIDWORKS TELEMETRY BLOCK END ==="
# Telemetry domains to block
$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"
)
# Licensing domains - DO NOT BLOCK
$licensingDomains = @(
"activation.solidworks.com",
"license.solidworks.com",
"licensing.solidworks.com"
)
function Test-IsAdmin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Backup-HostsFile {
if (-not (Test-Path $backupPath)) {
Copy-Item -Path $hostsPath -Destination $backupPath -Force
Write-Host "[OK] Backup created: $backupPath" -ForegroundColor Green
} else {
Write-Host "[INFO] Backup already exists: $backupPath" -ForegroundColor Yellow
}
}
function Remove-SolidWorksBlock {
$content = Get-Content $hostsPath -Raw
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-Host "[OK] SolidWorks telemetry block removed from hosts file" -ForegroundColor Green
return $true
}
return $false
}
function Add-SolidWorksBlock {
$content = Get-Content $hostsPath -Raw
# Check if block already exists
if ($content -match [regex]::Escape($markerStart)) {
Write-Host "[INFO] SolidWorks telemetry block already exists. Updating..." -ForegroundColor Yellow
Remove-SolidWorksBlock | Out-Null
$content = Get-Content $hostsPath -Raw
}
# Build the block
$blockContent = @()
$blockContent += ""
$blockContent += $markerStart
$blockContent += "# Blocks telemetry/analytics while preserving licensing"
$blockContent += "# Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$blockContent += "#"
$blockContent += "# PRESERVED (licensing - NOT blocked):"
foreach ($domain in $licensingDomains) {
$blockContent += "# - $domain"
}
$blockContent += "#"
$blockContent += "# BLOCKED (telemetry/analytics):"
foreach ($domain in $blockDomains) {
$blockContent += "127.0.0.1 $domain"
}
$blockContent += $markerEnd
Add-Content -Path $hostsPath -Value ($blockContent -join "`r`n") -Force
Write-Host "[OK] SolidWorks telemetry domains blocked" -ForegroundColor Green
}
function Show-Status {
Write-Host "`n=== HOSTS FILE STATUS ===" -ForegroundColor Cyan
$content = Get-Content $hostsPath -Raw
if ($content -match [regex]::Escape($markerStart)) {
Write-Host "[ACTIVE] SolidWorks telemetry block is in place" -ForegroundColor Green
} else {
Write-Host "[INACTIVE] SolidWorks telemetry block not found" -ForegroundColor Yellow
}
Write-Host "`nBlocked domains:" -ForegroundColor White
foreach ($domain in $blockDomains) {
$blocked = $content -match "127\.0\.0\.1\s+$([regex]::Escape($domain))"
if ($blocked) {
Write-Host " [X] $domain" -ForegroundColor Red
} else {
Write-Host " [ ] $domain" -ForegroundColor Gray
}
}
Write-Host "`nLicensing domains (should be accessible):" -ForegroundColor White
foreach ($domain in $licensingDomains) {
try {
$result = Resolve-DnsName -Name $domain -ErrorAction SilentlyContinue
if ($result) {
Write-Host " [OK] $domain - Reachable" -ForegroundColor Green
} else {
Write-Host " [??] $domain - DNS resolution failed" -ForegroundColor Yellow
}
} catch {
Write-Host " [!!] $domain - Cannot resolve" -ForegroundColor Red
}
}
}
# Main execution
if (-not (Test-IsAdmin)) {
Write-Host "[ERROR] This script requires Administrator privileges." -ForegroundColor Red
Write-Host "Please run PowerShell as Administrator and try again." -ForegroundColor Yellow
exit 1
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " SolidWorks Telemetry Blocker" -ForegroundColor Cyan
Write-Host " Atomaste Solution" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
if ($Undo) {
Write-Host "`n[ACTION] Removing telemetry block..." -ForegroundColor Yellow
if (Remove-SolidWorksBlock) {
Write-Host "[OK] Telemetry block removed successfully" -ForegroundColor Green
} else {
Write-Host "[INFO] No telemetry block found to remove" -ForegroundColor Yellow
}
} else {
Write-Host "`n[ACTION] Adding telemetry block..." -ForegroundColor Yellow
Backup-HostsFile
Add-SolidWorksBlock
}
Show-Status
Write-Host "`n[DONE] Script completed." -ForegroundColor Green

View File

@@ -0,0 +1,233 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Disables non-essential SolidWorks background services.
.DESCRIPTION
Identifies and disables SolidWorks update and background services
that are not required for core functionality or licensing.
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
Saves original service states before modification
#>
param(
[switch]$Undo, # Restore original service states
[switch]$ListOnly # Only list services, don't modify
)
$stateFile = "$env:USERPROFILE\solidworks-services-backup.json"
# Services to disable (update/background services)
$servicesToDisable = @(
"SOLIDWORKS Update Publisher Service",
"SolidWorks Background Downloader",
"SOLIDWORKS Flexnet Server",
"3DExperience*"
)
# Services to KEEP enabled (required for licensing)
$servicesToKeep = @(
"SolidNetWork License Manager",
"SOLIDWORKS SolidNetWork License Manager"
)
function Test-IsAdmin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Get-SolidWorksServices {
$allServices = @()
# Find all SOLIDWORKS-related services
$swServices = Get-Service -DisplayName "*SOLIDWORKS*" -ErrorAction SilentlyContinue
$dsServices = Get-Service -DisplayName "*3DEXPERIENCE*" -ErrorAction SilentlyContinue
$dassaultServices = Get-Service -DisplayName "*Dassault*" -ErrorAction SilentlyContinue
if ($swServices) { $allServices += $swServices }
if ($dsServices) { $allServices += $dsServices }
if ($dassaultServices) { $allServices += $dassaultServices }
return $allServices | Sort-Object -Property DisplayName -Unique
}
function Save-ServiceStates {
param([array]$Services)
$states = @{}
foreach ($svc in $Services) {
$states[$svc.Name] = @{
DisplayName = $svc.DisplayName
Status = $svc.Status.ToString()
StartType = $svc.StartType.ToString()
}
}
$states | ConvertTo-Json -Depth 3 | Set-Content -Path $stateFile -Force
Write-Host "[OK] Service states saved to: $stateFile" -ForegroundColor Green
}
function Restore-ServiceStates {
if (-not (Test-Path $stateFile)) {
Write-Host "[ERROR] No backup file found: $stateFile" -ForegroundColor Red
return $false
}
$states = Get-Content -Path $stateFile -Raw | ConvertFrom-Json
foreach ($serviceName in $states.PSObject.Properties.Name) {
$originalState = $states.$serviceName
try {
$svc = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if ($svc) {
Set-Service -Name $serviceName -StartupType $originalState.StartType -ErrorAction Stop
Write-Host "[OK] Restored $($originalState.DisplayName) to $($originalState.StartType)" -ForegroundColor Green
}
} catch {
Write-Host "[WARN] Could not restore $serviceName : $_" -ForegroundColor Yellow
}
}
return $true
}
function Test-ShouldDisable {
param([string]$DisplayName)
# Check if it's a service to keep
foreach ($keep in $servicesToKeep) {
if ($DisplayName -like "*$keep*") {
return $false
}
}
# Check if it matches services to disable
foreach ($disable in $servicesToDisable) {
if ($DisplayName -like "*$disable*") {
return $true
}
}
# Default: check if it contains "update", "background", "download"
if ($DisplayName -match "update|background|download|telemetry") {
return $true
}
return $false
}
function Show-Services {
$services = Get-SolidWorksServices
Write-Host "`n=== SOLIDWORKS RELATED SERVICES ===" -ForegroundColor Cyan
if ($services.Count -eq 0) {
Write-Host "[INFO] No SOLIDWORKS services found on this system" -ForegroundColor Yellow
return @()
}
Write-Host "`nFound $($services.Count) service(s):" -ForegroundColor White
foreach ($svc in $services) {
$shouldDisable = Test-ShouldDisable -DisplayName $svc.DisplayName
$statusColor = switch ($svc.Status) {
"Running" { "Green" }
"Stopped" { "Gray" }
default { "Yellow" }
}
$startTypeColor = switch ($svc.StartType) {
"Disabled" { "Red" }
"Manual" { "Yellow" }
"Automatic" { "Green" }
default { "White" }
}
Write-Host ""
Write-Host " $($svc.DisplayName)" -ForegroundColor White
Write-Host " Name: $($svc.Name)" -ForegroundColor Gray
Write-Host " Status: " -NoNewline; Write-Host "$($svc.Status)" -ForegroundColor $statusColor
Write-Host " StartType: " -NoNewline; Write-Host "$($svc.StartType)" -ForegroundColor $startTypeColor
if ($shouldDisable) {
Write-Host " Recommendation: " -NoNewline
Write-Host "DISABLE (update/telemetry service)" -ForegroundColor Red
} else {
Write-Host " Recommendation: " -NoNewline
Write-Host "KEEP (may be required)" -ForegroundColor Green
}
}
return $services
}
function Disable-TelemetryServices {
$services = Get-SolidWorksServices
if ($services.Count -eq 0) {
Write-Host "[INFO] No SOLIDWORKS services to disable" -ForegroundColor Yellow
return
}
# Save current states first
Save-ServiceStates -Services $services
$disabled = 0
$kept = 0
foreach ($svc in $services) {
$shouldDisable = Test-ShouldDisable -DisplayName $svc.DisplayName
if ($shouldDisable) {
try {
# Stop service if running
if ($svc.Status -eq "Running") {
Stop-Service -Name $svc.Name -Force -ErrorAction Stop
Write-Host "[OK] Stopped: $($svc.DisplayName)" -ForegroundColor Yellow
}
# Disable service
Set-Service -Name $svc.Name -StartupType Disabled -ErrorAction Stop
Write-Host "[OK] Disabled: $($svc.DisplayName)" -ForegroundColor Green
$disabled++
} catch {
Write-Host "[ERROR] Failed to disable $($svc.DisplayName): $_" -ForegroundColor Red
}
} else {
Write-Host "[KEEP] Preserved: $($svc.DisplayName)" -ForegroundColor Cyan
$kept++
}
}
Write-Host "`n[SUMMARY] Disabled: $disabled | Kept: $kept" -ForegroundColor White
}
# Main execution
if (-not (Test-IsAdmin)) {
Write-Host "[ERROR] This script requires Administrator privileges." -ForegroundColor Red
exit 1
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " SolidWorks Service Manager" -ForegroundColor Cyan
Write-Host " Atomaste Solution" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
if ($ListOnly) {
Show-Services
Write-Host "`n[INFO] Use without -ListOnly to apply changes" -ForegroundColor Yellow
} elseif ($Undo) {
Write-Host "`n[ACTION] Restoring original service states..." -ForegroundColor Yellow
Restore-ServiceStates
} else {
Write-Host "`n[ACTION] Scanning and disabling update/telemetry services..." -ForegroundColor Yellow
Show-Services
Write-Host ""
Disable-TelemetryServices
}
Write-Host "`n[DONE] Script completed." -ForegroundColor Green

View File

@@ -0,0 +1,264 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Configures Windows Firewall rules to block SolidWorks telemetry executables.
.DESCRIPTION
Creates outbound firewall rules to block update and telemetry executables
while allowing the main SOLIDWORKS application to communicate with
licensing servers.
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
Windows Firewall must be enabled
#>
param(
[switch]$Undo, # Remove all SOLIDWORKS firewall rules
[switch]$ListOnly, # Only list executables, don't create rules
[string]$InstallPath = "C:\Program Files\SOLIDWORKS Corp"
)
$rulePrefix = "SolidWorks Privacy - "
# Executables to BLOCK (update/telemetry)
$execsToBlock = @(
"SOLIDWORKS\swScheduler\dxttasks.exe",
"SOLIDWORKS\swScheduler\DXTTask.exe",
"SOLIDWORKS Installation Manager\sldIM.exe",
"SOLIDWORKS Installation Manager\sldDownloader.exe",
"SOLIDWORKS\swPDFPrinterHost.exe",
"SOLIDWORKS\swScheduler\TaskScheduler.exe",
"SOLIDWORKS\swScheduler\dxtTaskSvc.exe"
)
# Executables to ALLOW (main app - needs licensing access)
$execsToAllow = @(
"SOLIDWORKS\SLDWORKS.exe",
"SOLIDWORKS\swlmwiz.exe" # License wizard
)
# Additional executables to search for
$searchPatterns = @(
"*Update*.exe",
"*Downloader*.exe",
"*Telemetry*.exe",
"*Analytics*.exe",
"*3DEXPERIENCE*.exe"
)
function Test-IsAdmin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Find-SolidWorksExecutables {
param([string]$Path)
$results = @{
ToBlock = @()
ToAllow = @()
Other = @()
}
if (-not (Test-Path $Path)) {
Write-Host "[WARN] SolidWorks installation not found at: $Path" -ForegroundColor Yellow
return $results
}
Write-Host "[INFO] Scanning: $Path" -ForegroundColor Cyan
# Check known executables to block
foreach ($exe in $execsToBlock) {
$fullPath = Join-Path $Path $exe
if (Test-Path $fullPath) {
$results.ToBlock += $fullPath
}
}
# Check known executables to allow
foreach ($exe in $execsToAllow) {
$fullPath = Join-Path $Path $exe
if (Test-Path $fullPath) {
$results.ToAllow += $fullPath
}
}
# Search for additional update/telemetry executables
foreach ($pattern in $searchPatterns) {
$found = Get-ChildItem -Path $Path -Filter $pattern -Recurse -ErrorAction SilentlyContinue
foreach ($file in $found) {
if ($file.FullName -notin $results.ToBlock) {
$results.ToBlock += $file.FullName
}
}
}
return $results
}
function Show-Executables {
param([hashtable]$Execs)
Write-Host "`n=== EXECUTABLES TO ALLOW (licensing) ===" -ForegroundColor Green
if ($Execs.ToAllow.Count -eq 0) {
Write-Host " (none found)" -ForegroundColor Gray
} else {
foreach ($exe in $Execs.ToAllow) {
Write-Host " [ALLOW] $exe" -ForegroundColor Green
}
}
Write-Host "`n=== EXECUTABLES TO BLOCK (update/telemetry) ===" -ForegroundColor Red
if ($Execs.ToBlock.Count -eq 0) {
Write-Host " (none found)" -ForegroundColor Gray
} else {
foreach ($exe in $Execs.ToBlock) {
Write-Host " [BLOCK] $exe" -ForegroundColor Red
}
}
}
function Remove-SolidWorksRules {
$rules = Get-NetFirewallRule -DisplayName "$rulePrefix*" -ErrorAction SilentlyContinue
if ($rules) {
$count = ($rules | Measure-Object).Count
$rules | Remove-NetFirewallRule
Write-Host "[OK] Removed $count firewall rule(s)" -ForegroundColor Green
} else {
Write-Host "[INFO] No SolidWorks firewall rules found" -ForegroundColor Yellow
}
}
function New-BlockRule {
param([string]$ExePath)
$exeName = Split-Path $ExePath -Leaf
$ruleName = "$rulePrefix Block $exeName"
# Check if rule already exists
$existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "[SKIP] Rule already exists: $exeName" -ForegroundColor Yellow
return
}
try {
New-NetFirewallRule `
-DisplayName $ruleName `
-Description "Blocks outbound connections for SolidWorks update/telemetry" `
-Direction Outbound `
-Action Block `
-Program $ExePath `
-Enabled True `
-Profile Any `
-ErrorAction Stop | Out-Null
Write-Host "[OK] Created block rule: $exeName" -ForegroundColor Green
} catch {
Write-Host "[ERROR] Failed to create rule for $exeName : $_" -ForegroundColor Red
}
}
function New-AllowRule {
param([string]$ExePath)
$exeName = Split-Path $ExePath -Leaf
$ruleName = "$rulePrefix Allow $exeName"
# Check if rule already exists
$existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
if ($existing) {
Write-Host "[SKIP] Rule already exists: $exeName" -ForegroundColor Yellow
return
}
# Note: Windows Firewall cannot filter by domain easily
# We'll create an allow rule for the main app
# The hosts file handles domain-level blocking
try {
New-NetFirewallRule `
-DisplayName $ruleName `
-Description "Allows SolidWorks main app (licensing required)" `
-Direction Outbound `
-Action Allow `
-Program $ExePath `
-Enabled True `
-Profile Any `
-ErrorAction Stop | Out-Null
Write-Host "[OK] Created allow rule: $exeName" -ForegroundColor Green
} catch {
Write-Host "[ERROR] Failed to create rule for $exeName : $_" -ForegroundColor Red
}
}
function Show-CurrentRules {
$rules = Get-NetFirewallRule -DisplayName "$rulePrefix*" -ErrorAction SilentlyContinue
Write-Host "`n=== CURRENT SOLIDWORKS FIREWALL RULES ===" -ForegroundColor Cyan
if (-not $rules) {
Write-Host " (no rules configured)" -ForegroundColor Gray
return
}
foreach ($rule in $rules) {
$actionColor = if ($rule.Action -eq "Block") { "Red" } else { "Green" }
$enabledStatus = if ($rule.Enabled -eq "True") { "[ON]" } else { "[OFF]" }
Write-Host " $enabledStatus " -NoNewline
Write-Host "$($rule.Action)" -ForegroundColor $actionColor -NoNewline
Write-Host " - $($rule.DisplayName -replace $rulePrefix, '')" -ForegroundColor White
}
}
# Main execution
if (-not (Test-IsAdmin)) {
Write-Host "[ERROR] This script requires Administrator privileges." -ForegroundColor Red
exit 1
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " SolidWorks Firewall Configurator" -ForegroundColor Cyan
Write-Host " Atomaste Solution" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
if ($Undo) {
Write-Host "`n[ACTION] Removing all SolidWorks firewall rules..." -ForegroundColor Yellow
Remove-SolidWorksRules
Show-CurrentRules
} elseif ($ListOnly) {
Write-Host "`n[INFO] Scanning for executables (no changes will be made)..." -ForegroundColor Yellow
$execs = Find-SolidWorksExecutables -Path $InstallPath
Show-Executables -Execs $execs
Show-CurrentRules
Write-Host "`n[TIP] Run without -ListOnly to create firewall rules" -ForegroundColor Yellow
} else {
Write-Host "`n[ACTION] Configuring firewall rules..." -ForegroundColor Yellow
$execs = Find-SolidWorksExecutables -Path $InstallPath
Show-Executables -Execs $execs
Write-Host "`n[STEP] Creating firewall rules..." -ForegroundColor Cyan
# Create block rules for update/telemetry executables
foreach ($exe in $execs.ToBlock) {
New-BlockRule -ExePath $exe
}
# Create allow rules for main application
foreach ($exe in $execs.ToAllow) {
New-AllowRule -ExePath $exe
}
Show-CurrentRules
}
Write-Host "`n[NOTE] Domain-level blocking is handled by the hosts file." -ForegroundColor Yellow
Write-Host " Windows Firewall blocks at the executable level." -ForegroundColor Yellow
Write-Host "`n[DONE] Script completed." -ForegroundColor Green

View File

@@ -0,0 +1,334 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Disables SolidWorks in-app telemetry and update checks via registry.
.DESCRIPTION
Modifies Windows Registry to disable:
- Customer Experience Improvement Program (CEIP)
- Automatic update checks
- Anonymous usage data collection
- 3DEXPERIENCE connection prompts
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
Creates backup of registry keys before modification
#>
param(
[switch]$Undo, # Restore original registry values
[switch]$ListOnly # Only show current values, don't modify
)
$backupFile = "$env:USERPROFILE\solidworks-registry-backup.reg"
# Registry paths for SolidWorks settings
$regPaths = @{
HKCU_SW = "HKCU:\Software\SolidWorks"
HKLM_SW = "HKLM:\SOFTWARE\SolidWorks"
HKLM_SW_WOW = "HKLM:\SOFTWARE\WOW6432Node\SolidWorks"
}
# Settings to disable (0 = disabled, 1 = enabled typically)
$settingsToDisable = @(
@{
Description = "Customer Experience Improvement Program"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\Performance\CustomerExperienceImprovementProgram")
ValueName = "OptInStatus"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Check for Updates"
Paths = @(
"HKCU:\Software\SolidWorks\SOLIDWORKS *\General",
"HKLM:\SOFTWARE\SolidWorks\SOLIDWORKS *\General"
)
ValueName = "Auto Check for Updates"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Send Anonymous Usage Statistics"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\Performance")
ValueName = "Send Usage Statistics"
DisableValue = 0
EnableValue = 1
},
@{
Description = "3DEXPERIENCE Integration"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\General")
ValueName = "3DEXPERIENCE Enabled"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Show 3DEXPERIENCE Messages"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\Messages")
ValueName = "Show 3DEXPERIENCE Prompt"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Analytics Collection"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\Performance")
ValueName = "EnableAnalytics"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Telemetry"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\Performance")
ValueName = "EnableTelemetry"
DisableValue = 0
EnableValue = 1
},
@{
Description = "Background Downloader"
Paths = @("HKCU:\Software\SolidWorks\SOLIDWORKS *\General")
ValueName = "Enable Background Downloader"
DisableValue = 0
EnableValue = 1
}
)
function Test-IsAdmin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Get-ExpandedPaths {
param([string]$PathPattern)
$results = @()
# Handle wildcard in path (e.g., "SOLIDWORKS *" for version)
if ($PathPattern -match "\*") {
$parentPath = Split-Path $PathPattern -Parent
$childPattern = Split-Path $PathPattern -Leaf
if (Test-Path $parentPath) {
$children = Get-ChildItem -Path $parentPath -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -like $childPattern }
foreach ($child in $children) {
$results += $child.PSPath
}
}
} else {
if (Test-Path $PathPattern) {
$results += $PathPattern
}
}
return $results
}
function Backup-Registry {
Write-Host "[INFO] Creating registry backup..." -ForegroundColor Cyan
$regExportCmd = @"
Windows Registry Editor Version 5.00
; SolidWorks Privacy Lockdown - Registry Backup
; Created: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
;
"@
foreach ($regPath in $regPaths.Values) {
$expandedPaths = Get-ExpandedPaths -PathPattern "$regPath\*"
foreach ($path in $expandedPaths) {
try {
$key = Get-Item -Path $path -ErrorAction SilentlyContinue
if ($key) {
# Note: This is a simplified backup - for full backup use reg.exe
$regExportCmd += "; Path: $path`r`n"
}
} catch { }
}
}
Set-Content -Path $backupFile -Value $regExportCmd -Force
Write-Host "[OK] Backup reference saved to: $backupFile" -ForegroundColor Green
Write-Host "[TIP] For full backup, run: reg export 'HKCU\Software\SolidWorks' backup.reg" -ForegroundColor Yellow
}
function Get-RegistryValue {
param(
[string]$Path,
[string]$Name
)
try {
$value = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
if ($value) {
return $value.$Name
}
} catch { }
return $null
}
function Set-RegistryValue {
param(
[string]$Path,
[string]$Name,
[int]$Value
)
try {
# Create path if it doesn't exist
if (-not (Test-Path $Path)) {
New-Item -Path $Path -Force -ErrorAction SilentlyContinue | Out-Null
}
Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type DWord -Force -ErrorAction Stop
return $true
} catch {
return $false
}
}
function Show-CurrentSettings {
Write-Host "`n=== CURRENT REGISTRY SETTINGS ===" -ForegroundColor Cyan
$found = $false
foreach ($setting in $settingsToDisable) {
Write-Host "`n$($setting.Description):" -ForegroundColor White
foreach ($pathPattern in $setting.Paths) {
$expandedPaths = Get-ExpandedPaths -PathPattern $pathPattern
if ($expandedPaths.Count -eq 0) {
Write-Host " [--] Path not found: $pathPattern" -ForegroundColor Gray
continue
}
foreach ($path in $expandedPaths) {
$found = $true
$currentValue = Get-RegistryValue -Path $path -Name $setting.ValueName
$displayPath = $path -replace "Microsoft\.PowerShell\.Core\\Registry::", ""
if ($null -eq $currentValue) {
Write-Host " [??] $displayPath" -ForegroundColor Gray
Write-Host " Value '$($setting.ValueName)' not set" -ForegroundColor Gray
} elseif ($currentValue -eq $setting.DisableValue) {
Write-Host " [OK] $displayPath" -ForegroundColor Green
Write-Host " $($setting.ValueName) = $currentValue (DISABLED)" -ForegroundColor Green
} else {
Write-Host " [!!] $displayPath" -ForegroundColor Red
Write-Host " $($setting.ValueName) = $currentValue (ENABLED)" -ForegroundColor Red
}
}
}
}
if (-not $found) {
Write-Host "`n[INFO] No SolidWorks registry entries found." -ForegroundColor Yellow
Write-Host " This is normal if SolidWorks hasn't been run yet." -ForegroundColor Yellow
}
}
function Disable-TelemetrySettings {
Write-Host "`n=== DISABLING TELEMETRY SETTINGS ===" -ForegroundColor Cyan
$modified = 0
$skipped = 0
$failed = 0
foreach ($setting in $settingsToDisable) {
Write-Host "`n$($setting.Description):" -ForegroundColor White
foreach ($pathPattern in $setting.Paths) {
$expandedPaths = Get-ExpandedPaths -PathPattern $pathPattern
if ($expandedPaths.Count -eq 0) {
# Try to create the path for common settings
if ($pathPattern -match "HKCU:") {
Write-Host " [SKIP] Path doesn't exist (will be set when SW runs)" -ForegroundColor Gray
}
$skipped++
continue
}
foreach ($path in $expandedPaths) {
$displayPath = $path -replace "Microsoft\.PowerShell\.Core\\Registry::", ""
$currentValue = Get-RegistryValue -Path $path -Name $setting.ValueName
if ($currentValue -eq $setting.DisableValue) {
Write-Host " [SKIP] Already disabled: $displayPath" -ForegroundColor Gray
$skipped++
continue
}
$success = Set-RegistryValue -Path $path -Name $setting.ValueName -Value $setting.DisableValue
if ($success) {
Write-Host " [OK] Disabled: $displayPath" -ForegroundColor Green
$modified++
} else {
Write-Host " [FAIL] Could not modify: $displayPath" -ForegroundColor Red
$failed++
}
}
}
}
Write-Host "`n[SUMMARY] Modified: $modified | Skipped: $skipped | Failed: $failed" -ForegroundColor White
}
function Enable-TelemetrySettings {
Write-Host "`n=== RESTORING TELEMETRY SETTINGS ===" -ForegroundColor Cyan
foreach ($setting in $settingsToDisable) {
Write-Host "`n$($setting.Description):" -ForegroundColor White
foreach ($pathPattern in $setting.Paths) {
$expandedPaths = Get-ExpandedPaths -PathPattern $pathPattern
foreach ($path in $expandedPaths) {
$displayPath = $path -replace "Microsoft\.PowerShell\.Core\\Registry::", ""
$success = Set-RegistryValue -Path $path -Name $setting.ValueName -Value $setting.EnableValue
if ($success) {
Write-Host " [OK] Restored: $displayPath" -ForegroundColor Green
} else {
Write-Host " [FAIL] Could not restore: $displayPath" -ForegroundColor Red
}
}
}
}
}
# Main execution
if (-not (Test-IsAdmin)) {
Write-Host "[ERROR] This script requires Administrator privileges." -ForegroundColor Red
exit 1
}
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " SolidWorks Registry Configurator" -ForegroundColor Cyan
Write-Host " Atomaste Solution" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
if ($ListOnly) {
Show-CurrentSettings
Write-Host "`n[TIP] Run without -ListOnly to disable telemetry" -ForegroundColor Yellow
} elseif ($Undo) {
Write-Host "`n[ACTION] Restoring original settings..." -ForegroundColor Yellow
Enable-TelemetrySettings
Show-CurrentSettings
} else {
Write-Host "`n[ACTION] Disabling telemetry and update settings..." -ForegroundColor Yellow
Backup-Registry
Disable-TelemetrySettings
Show-CurrentSettings
}
Write-Host "`n[NOTE] Some settings may only appear after running SolidWorks." -ForegroundColor Yellow
Write-Host " Re-run this script after first launch if needed." -ForegroundColor Yellow
Write-Host "`n[DONE] Script completed." -ForegroundColor Green

View File

@@ -0,0 +1,281 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Verifies that SolidWorks privacy lockdown is properly configured.
.DESCRIPTION
Checks all components of the privacy lockdown:
- Hosts file entries
- Disabled services
- Firewall rules
- Registry settings
- Licensing server connectivity
.NOTES
Author: Atomaste Solution
Requires: Administrator privileges
#>
param(
[switch]$Detailed # Show detailed information for each check
)
$script:passed = 0
$script:failed = 0
$script:warnings = 0
function Write-Check {
param(
[string]$Name,
[string]$Status, # PASS, FAIL, WARN
[string]$Message
)
$icon = switch ($Status) {
"PASS" { "[OK]"; $color = "Green"; $script:passed++ }
"FAIL" { "[!!]"; $color = "Red"; $script:failed++ }
"WARN" { "[??]"; $color = "Yellow"; $script:warnings++ }
default { "[--]"; $color = "Gray" }
}
Write-Host " $icon " -ForegroundColor $color -NoNewline
Write-Host "$Name" -ForegroundColor White -NoNewline
if ($Message) {
Write-Host " - $Message" -ForegroundColor Gray
} else {
Write-Host ""
}
}
function Test-HostsFile {
Write-Host "`n=== HOSTS FILE CHECK ===" -ForegroundColor Cyan
$hostsPath = "C:\Windows\System32\drivers\etc\hosts"
$content = Get-Content $hostsPath -Raw -ErrorAction SilentlyContinue
$markerStart = "# === SOLIDWORKS TELEMETRY BLOCK START ==="
if ($content -match [regex]::Escape($markerStart)) {
Write-Check -Name "Telemetry block installed" -Status "PASS"
} else {
Write-Check -Name "Telemetry block installed" -Status "FAIL" -Message "Block not found in hosts file"
}
# Check specific domains
$telemetryDomains = @(
"telemetry.solidworks.com",
"analytics.3ds.com",
"collect.3ds.com",
"update.solidworks.com"
)
foreach ($domain in $telemetryDomains) {
if ($content -match "127\.0\.0\.1\s+$([regex]::Escape($domain))") {
if ($Detailed) {
Write-Check -Name " $domain" -Status "PASS" -Message "Blocked"
}
} else {
Write-Check -Name " $domain" -Status "WARN" -Message "Not blocked"
}
}
}
function Test-LicensingConnectivity {
Write-Host "`n=== LICENSING SERVER CHECK ===" -ForegroundColor Cyan
$licensingDomains = @(
"activation.solidworks.com",
"license.solidworks.com",
"licensing.solidworks.com"
)
foreach ($domain in $licensingDomains) {
try {
$dns = Resolve-DnsName -Name $domain -Type A -ErrorAction Stop -DnsOnly
if ($dns) {
Write-Check -Name "$domain" -Status "PASS" -Message "Reachable ($($dns[0].IPAddress))"
}
} catch {
Write-Check -Name "$domain" -Status "FAIL" -Message "Cannot resolve DNS"
}
}
}
function Test-Services {
Write-Host "`n=== SERVICES CHECK ===" -ForegroundColor Cyan
$services = Get-Service -DisplayName "*SOLIDWORKS*" -ErrorAction SilentlyContinue
if (-not $services -or $services.Count -eq 0) {
Write-Check -Name "SolidWorks services" -Status "PASS" -Message "No services found/installed"
return
}
foreach ($svc in $services) {
$isUpdateService = $svc.DisplayName -match "update|download|background"
if ($isUpdateService) {
if ($svc.StartType -eq "Disabled") {
Write-Check -Name $svc.DisplayName -Status "PASS" -Message "Disabled"
} else {
Write-Check -Name $svc.DisplayName -Status "WARN" -Message "Should be disabled ($($svc.StartType))"
}
} else {
if ($Detailed) {
Write-Check -Name $svc.DisplayName -Status "PASS" -Message "$($svc.StartType) (kept)"
}
}
}
}
function Test-FirewallRules {
Write-Host "`n=== FIREWALL RULES CHECK ===" -ForegroundColor Cyan
$rulePrefix = "SolidWorks Privacy - "
$rules = Get-NetFirewallRule -DisplayName "$rulePrefix*" -ErrorAction SilentlyContinue
if (-not $rules) {
Write-Check -Name "Firewall rules" -Status "WARN" -Message "No SolidWorks firewall rules found"
return
}
$blockRules = $rules | Where-Object { $_.Action -eq "Block" }
$allowRules = $rules | Where-Object { $_.Action -eq "Allow" }
Write-Check -Name "Block rules configured" -Status "PASS" -Message "$($blockRules.Count) rule(s)"
Write-Check -Name "Allow rules configured" -Status "PASS" -Message "$($allowRules.Count) rule(s)"
if ($Detailed) {
foreach ($rule in $rules) {
$status = if ($rule.Enabled -eq "True") { "Active" } else { "Disabled" }
Write-Check -Name " $($rule.DisplayName -replace $rulePrefix, '')" -Status "PASS" -Message "$($rule.Action) - $status"
}
}
}
function Test-Registry {
Write-Host "`n=== REGISTRY CHECK ===" -ForegroundColor Cyan
$regChecks = @(
@{
Name = "Customer Experience Program"
Path = "HKCU:\Software\SolidWorks\SOLIDWORKS *\Performance"
ValueName = "CustomerExperienceImprovementProgram"
ExpectedPattern = "OptInStatus"
DisabledValue = 0
}
)
# Find actual SolidWorks version paths
$swBasePath = "HKCU:\Software\SolidWorks"
if (-not (Test-Path $swBasePath)) {
Write-Check -Name "SolidWorks registry" -Status "WARN" -Message "Not found (SW may not be installed/run yet)"
return
}
$swVersions = Get-ChildItem -Path $swBasePath -ErrorAction SilentlyContinue |
Where-Object { $_.PSChildName -like "SOLIDWORKS *" }
if (-not $swVersions) {
Write-Check -Name "SolidWorks versions" -Status "WARN" -Message "No version keys found"
return
}
foreach ($version in $swVersions) {
Write-Host "`n $($version.PSChildName):" -ForegroundColor White
# Check Performance subkey
$perfPath = Join-Path $version.PSPath "Performance"
if (Test-Path $perfPath) {
$props = Get-ItemProperty -Path $perfPath -ErrorAction SilentlyContinue
if ($props.PSObject.Properties.Name -contains "OptInStatus") {
if ($props.OptInStatus -eq 0) {
Write-Check -Name " CEIP OptInStatus" -Status "PASS" -Message "Disabled"
} else {
Write-Check -Name " CEIP OptInStatus" -Status "FAIL" -Message "Enabled ($($props.OptInStatus))"
}
} else {
Write-Check -Name " CEIP OptInStatus" -Status "WARN" -Message "Not set"
}
}
# Check General subkey
$generalPath = Join-Path $version.PSPath "General"
if (Test-Path $generalPath) {
$props = Get-ItemProperty -Path $generalPath -ErrorAction SilentlyContinue
if ($props.PSObject.Properties.Name -contains "Auto Check for Updates") {
if ($props."Auto Check for Updates" -eq 0) {
Write-Check -Name " Auto Updates" -Status "PASS" -Message "Disabled"
} else {
Write-Check -Name " Auto Updates" -Status "FAIL" -Message "Enabled"
}
}
}
}
}
function Test-TelemetryConnectivity {
Write-Host "`n=== TELEMETRY BLOCK VERIFICATION ===" -ForegroundColor Cyan
$telemetryDomains = @(
"telemetry.solidworks.com",
"analytics.3ds.com"
)
foreach ($domain in $telemetryDomains) {
try {
$result = Resolve-DnsName -Name $domain -Type A -ErrorAction Stop -DnsOnly
$ip = $result[0].IPAddress
if ($ip -eq "127.0.0.1") {
Write-Check -Name "$domain" -Status "PASS" -Message "Blocked (resolves to 127.0.0.1)"
} else {
Write-Check -Name "$domain" -Status "FAIL" -Message "NOT blocked (resolves to $ip)"
}
} catch {
Write-Check -Name "$domain" -Status "WARN" -Message "Cannot resolve (may be blocked at DNS level)"
}
}
}
function Show-Summary {
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host " VERIFICATION SUMMARY" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""
Write-Host " Passed: " -NoNewline; Write-Host "$script:passed" -ForegroundColor Green
Write-Host " Failed: " -NoNewline; Write-Host "$script:failed" -ForegroundColor Red
Write-Host " Warnings: " -NoNewline; Write-Host "$script:warnings" -ForegroundColor Yellow
Write-Host ""
if ($script:failed -eq 0) {
Write-Host " [SUCCESS] Privacy lockdown is properly configured!" -ForegroundColor Green
} elseif ($script:failed -le 2) {
Write-Host " [PARTIAL] Most protections are in place, minor issues found." -ForegroundColor Yellow
} else {
Write-Host " [INCOMPLETE] Privacy lockdown needs attention." -ForegroundColor Red
}
}
# Main execution
Write-Host "========================================" -ForegroundColor Cyan
Write-Host " SolidWorks Privacy Lockdown Verifier" -ForegroundColor Cyan
Write-Host " Atomaste Solution" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "`nRunning verification checks..." -ForegroundColor White
Test-HostsFile
Test-LicensingConnectivity
Test-Services
Test-FirewallRules
Test-Registry
Test-TelemetryConnectivity
Show-Summary
Write-Host "`n[TIP] Use -Detailed for more information on each check" -ForegroundColor Gray
Write-Host "[DONE] Verification completed." -ForegroundColor Green

View File

@@ -0,0 +1,105 @@
================================================================================
SOLIDWORKS PRIVACY LOCKDOWN REPORT
Generated: 2025-12-23 20:16:56
Computer: ANTOINETHINKPAD
User: antoi
Mode: DRY RUN (preview)
================================================================================
--------------------------------------------------------------------------------
SYSTEM STATE BEFORE CHANGES
--------------------------------------------------------------------------------
[INFO] Checking hosts file...
[BEFORE] Hosts file: No SolidWorks block found
[INFO] Checking services...
[BEFORE] Service: SolidWorks Licensing Service - Status: Stopped, StartType: Manual
[INFO] Checking firewall rules...
[BEFORE] Firewall: No SolidWorks Privacy rules found
[INFO] Checking registry...
[BEFORE] Registry: Found SOLIDWORKS 2026
[BEFORE] Registry: Found SOLIDWORKS CAM
--------------------------------------------------------------------------------
APPLYING PRIVACY LOCKDOWN
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
HOSTS FILE MODIFICATIONS
--------------------------------------------------------------------------------
[INFO] Licensing domains (preserved):
[OK] ALLOW: activation.solidworks.com
[OK] ALLOW: license.solidworks.com
[OK] ALLOW: licensing.solidworks.com
[INFO]
[INFO] Telemetry domains to block:
[INFO] Would block: api.3ds.com
[INFO] Would block: www.3ds.com
[INFO] Would block: swym.3ds.com
[INFO] Would block: iam.3ds.com
[INFO] Would block: cas.3ds.com
[INFO] Would block: eu1-ds-iam.3dexperience.3ds.com
[INFO] Would block: eu1-ds.3dexperience.3ds.com
[INFO] Would block: update.solidworks.com
[INFO] Would block: www.solidworks.com
[INFO] Would block: sentry.io
[INFO] Would block: o136956.ingest.sentry.io
[INFO] Would block: telemetry.solidworks.com
[INFO] Would block: analytics.3ds.com
[INFO] Would block: collect.3ds.com
[INFO] Would block: ifwe.3ds.com
[INFO] Would block: eu1-ifwe.3dexperience.3ds.com
[INFO] Would block: passport.3ds.com
[INFO] Would block: 3dswym.3ds.com
[WARN] [DRY RUN] No changes made to hosts file
--------------------------------------------------------------------------------
SERVICES MODIFICATIONS
--------------------------------------------------------------------------------
[SKIP] Preserved: SolidWorks Licensing Service (Manual)
--------------------------------------------------------------------------------
FIREWALL RULES CONFIGURATION
--------------------------------------------------------------------------------
[SKIP] Executable not found: SOLIDWORKS\swScheduler\dxttasks.exe
[SKIP] Executable not found: SOLIDWORKS\swScheduler\DXTTask.exe
[SKIP] Executable not found: SOLIDWORKS Installation Manager\sldIM.exe
[SKIP] Executable not found: SOLIDWORKS Installation Manager\sldDownloader.exe
--------------------------------------------------------------------------------
REGISTRY MODIFICATIONS
--------------------------------------------------------------------------------
[INFO] Processing: SOLIDWORKS 2026
[WARN] [DRY RUN] Would disable CEIP (current: )
[WARN] [DRY RUN] Would disable Auto Updates (current: )
[WARN] [DRY RUN] Would disable Analytics (current: )
[WARN] [DRY RUN] Would disable Telemetry (current: )
[INFO] Processing: SOLIDWORKS CAM
[SKIP] Path not found: Performance
[SKIP] Path not found: General
[SKIP] Path not found: Performance
[SKIP] Path not found: Performance
================================================================================
CHANGES SUMMARY
================================================================================
HOSTS FILE CHANGES (0):
(no changes)
SERVICES CHANGES (0):
(no changes)
FIREWALL CHANGES (0):
(no changes)
REGISTRY CHANGES (0):
(no changes)
================================================================================
TOTAL CHANGES: 0
REPORT SAVED: C:\Users\antoi\SERVtomaste\Solidworks Licenses\scripts\reports\lockdown-report_2025-12-23_20-16-56.txt
================================================================================

View File

@@ -0,0 +1,127 @@
================================================================================
SOLIDWORKS PRIVACY LOCKDOWN REPORT
Generated: 2025-12-23 20:18:01
Computer: ANTOINETHINKPAD
User: antoi
Mode: INSTALL
================================================================================
--------------------------------------------------------------------------------
SYSTEM STATE BEFORE CHANGES
--------------------------------------------------------------------------------
[INFO] Checking hosts file...
[BEFORE] Hosts file: No SolidWorks block found
[INFO] Checking services...
[BEFORE] Service: SolidWorks Licensing Service - Status: Stopped, StartType: Manual
[INFO] Checking firewall rules...
[BEFORE] Firewall: No SolidWorks Privacy rules found
[INFO] Checking registry...
[BEFORE] Registry: Found SOLIDWORKS 2026
[BEFORE] Registry: Found SOLIDWORKS CAM
--------------------------------------------------------------------------------
APPLYING PRIVACY LOCKDOWN
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
HOSTS FILE MODIFICATIONS
--------------------------------------------------------------------------------
[INFO] Licensing domains (preserved):
[OK] ALLOW: activation.solidworks.com
[OK] ALLOW: license.solidworks.com
[OK] ALLOW: licensing.solidworks.com
[INFO]
[INFO] Telemetry domains to block:
[OK] Backup created: C:\Windows\System32\drivers\etc\hosts.backup.solidworks.2025-12-23_20-18-01
[CHANGE] BLOCKED: api.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: www.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: swym.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: iam.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: cas.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: eu1-ds-iam.3dexperience.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: eu1-ds.3dexperience.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: update.solidworks.com -> 127.0.0.1
[CHANGE] BLOCKED: www.solidworks.com -> 127.0.0.1
[CHANGE] BLOCKED: sentry.io -> 127.0.0.1
[CHANGE] BLOCKED: o136956.ingest.sentry.io -> 127.0.0.1
[CHANGE] BLOCKED: telemetry.solidworks.com -> 127.0.0.1
[CHANGE] BLOCKED: analytics.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: collect.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: ifwe.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: eu1-ifwe.3dexperience.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: passport.3ds.com -> 127.0.0.1
[CHANGE] BLOCKED: 3dswym.3ds.com -> 127.0.0.1
[OK] Hosts file updated successfully
--------------------------------------------------------------------------------
SERVICES MODIFICATIONS
--------------------------------------------------------------------------------
[OK] Service states backed up to: C:\Users\antoi\solidworks-services-backup.json
[SKIP] Preserved: SolidWorks Licensing Service (Manual)
--------------------------------------------------------------------------------
FIREWALL RULES CONFIGURATION
--------------------------------------------------------------------------------
[SKIP] Executable not found: SOLIDWORKS\swScheduler\dxttasks.exe
[SKIP] Executable not found: SOLIDWORKS\swScheduler\DXTTask.exe
[SKIP] Executable not found: SOLIDWORKS Installation Manager\sldIM.exe
[SKIP] Executable not found: SOLIDWORKS Installation Manager\sldDownloader.exe
--------------------------------------------------------------------------------
REGISTRY MODIFICATIONS
--------------------------------------------------------------------------------
[INFO] Processing: SOLIDWORKS 2026
[CHANGE] Disabled: CEIP (was: -> now: 0)
[CHANGE] Disabled: Auto Updates (was: -> now: 0)
[CHANGE] Disabled: Analytics (was: -> now: 0)
[CHANGE] Disabled: Telemetry (was: -> now: 0)
[INFO] Processing: SOLIDWORKS CAM
[SKIP] Path not found: Performance
[SKIP] Path not found: General
[SKIP] Path not found: Performance
[SKIP] Path not found: Performance
================================================================================
CHANGES SUMMARY
================================================================================
HOSTS FILE CHANGES (18):
- BLOCKED: api.3ds.com -> 127.0.0.1
- BLOCKED: www.3ds.com -> 127.0.0.1
- BLOCKED: swym.3ds.com -> 127.0.0.1
- BLOCKED: iam.3ds.com -> 127.0.0.1
- BLOCKED: cas.3ds.com -> 127.0.0.1
- BLOCKED: eu1-ds-iam.3dexperience.3ds.com -> 127.0.0.1
- BLOCKED: eu1-ds.3dexperience.3ds.com -> 127.0.0.1
- BLOCKED: update.solidworks.com -> 127.0.0.1
- BLOCKED: www.solidworks.com -> 127.0.0.1
- BLOCKED: sentry.io -> 127.0.0.1
- BLOCKED: o136956.ingest.sentry.io -> 127.0.0.1
- BLOCKED: telemetry.solidworks.com -> 127.0.0.1
- BLOCKED: analytics.3ds.com -> 127.0.0.1
- BLOCKED: collect.3ds.com -> 127.0.0.1
- BLOCKED: ifwe.3ds.com -> 127.0.0.1
- BLOCKED: eu1-ifwe.3dexperience.3ds.com -> 127.0.0.1
- BLOCKED: passport.3ds.com -> 127.0.0.1
- BLOCKED: 3dswym.3ds.com -> 127.0.0.1
SERVICES CHANGES (0):
(no changes)
FIREWALL CHANGES (0):
(no changes)
REGISTRY CHANGES (4):
- Disabled: CEIP (was: -> now: 0)
- Disabled: Auto Updates (was: -> now: 0)
- Disabled: Analytics (was: -> now: 0)
- Disabled: Telemetry (was: -> now: 0)
================================================================================
TOTAL CHANGES: 22
REPORT SAVED: C:\Users\antoi\SERVtomaste\Solidworks Licenses\scripts\reports\lockdown-report_2025-12-23_20-18-01.txt
================================================================================

View File

@@ -0,0 +1,127 @@
# SolidWorks Privacy Lockdown - Block Telemetry, Preserve Licensing
## Context
I own a perpetual SolidWorks license (~$20K CAD) from Dassault Systèmes. I use it for proprietary engineering work through my consulting company (Atomaste Solution), including development of my Atomizer optimization framework.
I want to block all telemetry, analytics, and unnecessary communications with Dassault servers while preserving the ability to transfer my license between my workstation (ThinkPad P16) and laptop as needed.
## Objective
Implement "Option 2" - block all telemetry/tracking permanently, but allow licensing servers so license activation/deactivation works seamlessly.
## System Information
- OS: Windows 11 Pro
- SolidWorks installation path: `C:\Program Files\SOLIDWORKS Corp\` (verify actual path)
- User has admin access
- Perpetual license (not subscription)
## Tasks
### 1. Identify All SolidWorks Executables
Find all executables in the SolidWorks installation that might phone home:
- Main application (SLDWORKS.exe)
- Update services
- Background schedulers
- Any 3DEXPERIENCE components
### 2. Update Hosts File
Add blocking rules to `C:\Windows\System32\drivers\etc\hosts` for telemetry domains while explicitly preserving licensing domains.
**Block these (telemetry/analytics):**
```
127.0.0.1 api.3ds.com
127.0.0.1 www.3ds.com
127.0.0.1 swym.3ds.com
127.0.0.1 iam.3ds.com
127.0.0.1 cas.3ds.com
127.0.0.1 eu1-ds-iam.3dexperience.3ds.com
127.0.0.1 eu1-ds.3dexperience.3ds.com
127.0.0.1 update.solidworks.com
127.0.0.1 www.solidworks.com
127.0.0.1 sentry.io
127.0.0.1 o136956.ingest.sentry.io
127.0.0.1 telemetry.solidworks.com
127.0.0.1 analytics.3ds.com
127.0.0.1 collect.3ds.com
```
**DO NOT block these (licensing):**
```
# activation.solidworks.com - REQUIRED for license transfer
# license.solidworks.com - REQUIRED for license transfer
# licensing.solidworks.com - REQUIRED for license transfer
```
### 3. Disable Update Services
Disable these Windows services if they exist:
- SOLIDWORKS Update Publisher Service
- Any other SW background services that aren't needed for core functionality
```powershell
Get-Service -DisplayName "*SOLIDWORKS*" | Format-Table Name, DisplayName, Status, StartType
```
Then disable non-essential ones.
### 4. Configure Firewall Rules
Create firewall rules that:
- Block outbound connections for update/telemetry executables
- Allow SLDWORKS.exe to reach licensing servers only (if possible with Windows Firewall)
If granular domain blocking per-exe isn't possible with Windows Firewall, the hosts file blocking is sufficient - just document this.
### 5. Disable In-App Telemetry
Document the registry keys or provide instructions for disabling:
- Anonymous usage data collection
- Automatic update checks
- 3DEXPERIENCE connection prompts
Registry locations to check:
```
HKEY_CURRENT_USER\Software\SolidWorks\
HKEY_LOCAL_MACHINE\SOFTWARE\SolidWorks\
```
Look for keys related to:
- Analytics
- Telemetry
- Updates
- CustomerExperience
### 6. Create Verification Script
Create a PowerShell script that verifies the lockdown is in place:
- Check hosts file entries exist
- Check services are disabled
- Check firewall rules are active
- Test that licensing domains are still reachable
### 7. Create Documentation
Provide a summary document with:
- What was blocked and why
- What was preserved and why
- How to temporarily disable blocking if needed (e.g., for troubleshooting)
- How to verify license transfer still works
## Success Criteria
1. SolidWorks launches and runs normally
2. No connections to telemetry/analytics endpoints
3. License activation/deactivation works
4. Solution persists across reboots
5. Clear documentation for future reference
## Notes
- Take a backup of hosts file before modifying
- Document original service states before disabling
- All changes should be reversible
- Test license deactivation/reactivation after implementation to confirm it works

View File

@@ -1,6 +1,6 @@
# Dalidou Home Server - Complete Documentation # Dalidou Home Server - Complete Documentation
> **Last Updated:** December 6, 2025 > **Last Updated:** December 18, 2025
> **Server Name:** dalidou > **Server Name:** dalidou
> **Owner:** Antoine Letarte > **Owner:** Antoine Letarte
@@ -25,10 +25,20 @@
## Server Overview ## Server Overview
### Hardware ### Hardware
- **Type:** Home server running Docker containers - **Type:** ThinkPad W520 home server running Docker containers
- **OS:** Linux (Debian/Ubuntu-based) - **OS:** Ubuntu Linux
- **Location:** Home network - **Location:** Home network
### Storage Drives
| Device | Model | Size | Mount Point | Purpose |
|--------|-------|------|-------------|---------|
| sda | Samsung SSD 850 | 232GB | `/` (root) | Operating system |
| sdb | Crucial BX500 SSD | 3.6TB | `/srv/storage` | Service data, Obsidian, shared files |
| sdc | WD Elements 14TB | 12.7TiB | `/mnt/hdd` | Immich photos, backups |
**Note:** sdc is connected via USB 3.0 (SuperSpeed)
### Purpose ### Purpose
Self-hosted infrastructure replacing cloud services: Self-hosted infrastructure replacing cloud services:
- Google Photos → Immich - Google Photos → Immich
@@ -383,6 +393,31 @@ docker compose up -d
## Directory Structure ## Directory Structure
### SSD Storage (`/srv/storage` - 3.6TB Crucial SSD)
```
/srv/storage/
├── docs/ ← Paperless consume folder
├── shared/ ← Filebrowser root
├── repos/ ← Gitea repositories
├── obsidian/ ← Obsidian vault (synced)
└── photos/ ← External photos (read-only in Immich)
```
### HDD Storage (`/mnt/hdd` - 14TB WD Elements)
```
/mnt/hdd/
├── immich/ ← Primary Immich storage (photos/videos)
│ ├── upload/ ← All user uploads (~535GB)
│ ├── postgres/ ← Immich database
│ ├── model-cache/ ← ML models
│ └── redis/ ← Redis cache
└── backups/
├── restic-repo/ ← Incremental backups (deduplicated)
└── system-images/ ← Weekly full system tarballs
```
### Service Configuration (`/srv/`)
``` ```
/srv/ /srv/
├── filebrowser/ ├── filebrowser/
@@ -396,10 +431,7 @@ docker compose up -d
│ │ └── lfs/ │ │ └── lfs/
│ └── postgres/ │ └── postgres/
├── immich/ ├── immich -> /srv/storage/immich ← Symlink
│ ├── upload/
│ ├── library/
│ └── postgres/
├── paperless/ ├── paperless/
│ ├── consume/ ← Drop documents here │ ├── consume/ ← Drop documents here
@@ -424,26 +456,111 @@ docker compose up -d
│ ├── bookmarks.yaml ← External links │ ├── bookmarks.yaml ← External links
│ └── docker.yaml ← Docker integration │ └── docker.yaml ← Docker integration
── storage/ ── pihole/
── shared/ ← Filebrowser root ── etc-pihole/
│ └── etc-dnsmasq.d/
└── storage/ ← Main SSD storage mount
``` ```
--- ---
## Backup Strategy ## Backup Strategy
### Critical Data Locations ### Automated Backup System (Restic + Cron)
| Priority | Data | Location | Backup Method | The server uses a dual backup approach:
|----------|------|----------|---------------| 1. **Daily incremental backups** at midnight using restic
| HIGH | Photos | `/srv/immich/` | External drive + cloud | 2. **Weekly full system images** on Sundays at 3 AM
| HIGH | Documents | `/srv/paperless/` | External drive |
| HIGH | Git repos | `/srv/gitea/` | Git push to remote | ### How Restic Backups Work (Efficiency)
| MEDIUM | Seafile | `/srv/seafile/` | External drive |
| LOW | Configs | `/srv/*/config/` | Copy to backup | Restic uses **deduplication and incremental backups**, making it very efficient:
| Aspect | Behavior |
|--------|----------|
| **First backup** | Full backup (~535GB for Immich, takes 1-2 hours) |
| **Daily backups** | Only new/changed data (typically minutes, not hours) |
| **Storage** | Deduplicated - identical files stored once |
| **CPU/Energy** | Low - only processes changes |
**Example:** If you add 20 new photos (100MB) today:
- Backup uploads ~100MB (not 535GB)
- Takes ~2-5 minutes (not hours)
- HDD spins briefly, then sleeps
This makes nightly backups energy-efficient and fast after the initial backup.
### Backup Storage
| Location | Purpose | Size |
|----------|---------|------|
| `/mnt/hdd/backups/restic-repo` | Incremental backups (versioned, deduplicated) | ~500GB+ |
| `/mnt/hdd/backups/system-images` | Weekly full system tarballs | ~50GB x 4 |
| `/mnt/hdd/immich` | Primary Immich photo storage | ~535GB |
### Backup Credentials
**Restic Repository Password:** `dalidou-backup-2025`
⚠️ **IMPORTANT:** Store this password securely (e.g., Bitwarden). Without it, backups are irrecoverable!
### What Gets Backed Up Daily
| Data | Location | Priority |
|------|----------|----------|
| Immich photos & DB | `/mnt/hdd/immich` | HIGH |
| Obsidian vault | `/srv/storage/obsidian` | HIGH |
| Documents | `/srv/storage/docs` | HIGH |
| Shared files | `/srv/storage/shared` | MEDIUM |
| Gitea repos & DB | `/srv/gitea` | HIGH |
| Paperless docs & DB | `/srv/paperless` | HIGH |
| Syncthing config | `/srv/syncthing` | LOW |
| Homepage config | `/srv/homepage` | LOW |
| Pi-hole config | `/srv/pihole` | LOW |
| Docker compose | `/home/papa` | MEDIUM |
### Backup Scripts
| Script | Schedule | Purpose |
|--------|----------|---------|
| `/usr/local/bin/backup-daily.sh` | Daily at midnight | Incremental restic backup |
| `/usr/local/bin/backup-weekly-image.sh` | Sundays 3 AM | Full system tarball |
### Retention Policy
- **Daily backups:** Keep 7 days
- **Weekly backups:** Keep 4 weeks
- **Monthly backups:** Keep 12 months
- **System images:** Keep 4 most recent
### Manual Backup Commands ### Manual Backup Commands
```bash
# Check backup status
export RESTIC_REPOSITORY=/mnt/hdd/backups/restic-repo
export RESTIC_PASSWORD='dalidou-backup-2025'
restic snapshots
# Run manual backup
/usr/local/bin/backup-daily.sh
# Restore a file from backup
restic restore latest --target /tmp/restore --include /srv/storage/obsidian
# List files in a snapshot
restic ls latest
# Check backup integrity
restic check
# View backup logs
tail -100 /var/log/backup-daily.log
tail -100 /var/log/backup-weekly.log
```
### Legacy Manual Backup Commands
```bash ```bash
# Backup Immich # Backup Immich
tar -czvf immich-backup-$(date +%Y%m%d).tar.gz /srv/immich/ tar -czvf immich-backup-$(date +%Y%m%d).tar.gz /srv/immich/
@@ -498,43 +615,138 @@ sudo systemctl restart docker
## Disaster Recovery ## Disaster Recovery
### If Server Fails - Rebuild Steps ### What You Need to Recover
1. **Install fresh Linux (Debian/Ubuntu)** 1. **The 14TB WD Elements HDD** (contains all backups and Immich photos)
2. **Any new Linux machine** (Ubuntu 22.04+ recommended)
3. **The restic password:** `dalidou-backup-2025`
### Complete Recovery Steps
#### Step 1: Install Fresh Ubuntu
Install Ubuntu Server or Desktop on the new machine.
#### Step 2: Install Required Software
2. **Install Docker:**
```bash ```bash
# Install Docker
curl -fsSL https://get.docker.com | sh curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER sudo usermod -aG docker $USER
``` newgrp docker
3. **Restore /srv from backup:** # Install restic
```bash sudo apt update && sudo apt install -y restic
sudo mkdir /srv
sudo tar -xzvf backup.tar.gz -C /
```
4. **Start each service:** # Install Tailscale (for remote access)
```bash
cd /srv/gitea && docker compose up -d
cd /srv/immich && docker compose up -d
cd /srv/paperless && docker compose up -d
cd /srv/seafile && docker compose up -d
# etc.
```
5. **Install Tailscale:**
```bash
curl -fsSL https://tailscale.com/install.sh | sh curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
``` ```
### Key Files to Backup #### Step 3: Connect and Mount the 14TB HDD
- All of `/srv/` ```bash
- `/etc/caddy/Caddyfile` (if using Caddy) # Find the drive
- Docker compose files (already in /srv/) lsblk
- This documentation!
# Create mount point and mount (replace sdX with actual device)
sudo mkdir -p /mnt/hdd
sudo mount /dev/sdX1 /mnt/hdd
# Add to fstab for auto-mount (get UUID first)
sudo blkid /dev/sdX1
# Add line to /etc/fstab:
# UUID=<your-uuid> /mnt/hdd ext4 defaults,nofail 0 2
```
#### Step 4: Restore from Restic Backup
```bash
# Set up restic environment
export RESTIC_REPOSITORY=/mnt/hdd/backups/restic-repo
export RESTIC_PASSWORD='dalidou-backup-2025'
# List available backups
restic snapshots
# Restore everything to root filesystem
sudo -E restic restore latest --target /
# This restores:
# - /mnt/hdd/immich (Immich photos & database)
# - /srv/storage/obsidian (Obsidian vault)
# - /srv/storage/docs (Documents)
# - /srv/gitea (Git repositories)
# - /srv/paperless (Paperless documents)
# - /srv/homepage, /srv/pihole, /srv/syncthing (configs)
# - /home/papa (docker-compose.yml)
```
#### Step 5: Create Required Directories
```bash
sudo mkdir -p /srv/storage
# Mount SSD if you have one, or create directories
```
#### Step 6: Start All Services
```bash
cd /home/papa
docker compose up -d
# Verify all containers are running
docker ps
```
#### Step 7: Configure Tailscale
```bash
sudo tailscale up
# Follow the link to authenticate
```
#### Step 8: Verify Services
- Immich: http://localhost:2283
- Gitea: http://localhost:3000
- Paperless: http://localhost:8082
- Homepage: http://localhost:3001
### Recovery Time Estimate
| Step | Time |
|------|------|
| Install Ubuntu | 15-30 min |
| Install Docker/restic | 5 min |
| Mount HDD | 2 min |
| Restore from backup | 30-60 min (depends on data size) |
| Start services | 5 min |
| **Total** | **~1-2 hours** |
### Key Files in Backup
| Location | Contents |
|----------|----------|
| `/mnt/hdd/immich` | All photos, videos, thumbnails, postgres DB |
| `/srv/storage/obsidian` | Obsidian vault |
| `/srv/gitea` | Git repositories and database |
| `/srv/paperless` | Scanned documents and database |
| `/home/papa/docker-compose.yml` | All service definitions |
### Alternative: Weekly System Image Recovery
If you prefer a full system restore (slower but includes OS configs):
```bash
# Mount the HDD
sudo mount /dev/sdX1 /mnt/hdd
# List available images
ls -la /mnt/hdd/backups/system-images/
# Extract to new system
sudo tar -xzvf /mnt/hdd/backups/system-images/system-image-YYYYMMDD.tar.gz -C /
```
--- ---
@@ -584,6 +796,40 @@ docker exec -it <postgres_container> psql -U <user> -d <database>
docker exec <postgres_container> pg_isready docker exec <postgres_container> pg_isready
``` ```
### DNS Resolution Issues
If external domains fail to resolve (e.g., `api.anthropic.com`, `google.com`):
```bash
# Check current DNS config
cat /etc/resolv.conf
# Test DNS resolution
ping -4 google.com
# If using Tailscale MagicDNS and it's failing:
# Option 1: Disable Tailscale DNS management
tailscale set --accept-dns=false
# Option 2: Add fallback DNS to systemd-resolved
cat > /etc/systemd/resolved.conf.d/fix-dns.conf << 'EOF'
[Resolve]
DNS=8.8.8.8 1.1.1.1
FallbackDNS=8.8.4.4 1.0.0.1
EOF
systemctl restart systemd-resolved
# Switch to systemd-resolved
rm /etc/resolv.conf
ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
```
**Current DNS Configuration (as of Dec 2025):**
- Tailscale DNS disabled (`--accept-dns=false`)
- Using systemd-resolved with Google (8.8.8.8) and Cloudflare (1.1.1.1) DNS
---
### Reset Service Password ### Reset Service Password
**Filebrowser:** **Filebrowser:**
@@ -643,3 +889,6 @@ df -h /srv
| 2025-11-27 | Added Seafile setup | | 2025-11-27 | Added Seafile setup |
| 2025-11-27 | Added Git LFS for CAD versioning | | 2025-11-27 | Added Git LFS for CAD versioning |
| 2025-12-06 | Added Homepage dashboard documentation | | 2025-12-06 | Added Homepage dashboard documentation |
| 2025-12-18 | Added 14TB WD Elements HDD for Immich storage and backups |
| 2025-12-18 | Configured automated backup system (restic daily + weekly images) |
| 2025-12-18 | Fixed DNS resolution issues (Tailscale MagicDNS → systemd-resolved) |

File diff suppressed because it is too large Load Diff