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:
24
.claude/settings.local.json
Normal file
24
.claude/settings.local.json
Normal 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)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
NX Licenses/SiemensLicenseServer_v5.1.0.0_Lnx64_x86-64.bin
Normal file
BIN
NX Licenses/SiemensLicenseServer_v5.1.0.0_Lnx64_x86-64.bin
Normal file
Binary file not shown.
BIN
Solidworks Licenses/LICENSE_DETAILS_LKO4139897.pdf
Normal file
BIN
Solidworks Licenses/LICENSE_DETAILS_LKO4139897.pdf
Normal file
Binary file not shown.
296
Solidworks Licenses/PRIVACY-LOCKDOWN-README.md
Normal file
296
Solidworks Licenses/PRIVACY-LOCKDOWN-README.md
Normal 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
|
||||||
BIN
Solidworks Licenses/install_guide.pdf
Normal file
BIN
Solidworks Licenses/install_guide.pdf
Normal file
Binary file not shown.
4187
Solidworks Licenses/install_guide.txt
Normal file
4187
Solidworks Licenses/install_guide.txt
Normal file
File diff suppressed because it is too large
Load Diff
696
Solidworks Licenses/scripts/00-install-privacy-lockdown.ps1
Normal file
696
Solidworks Licenses/scripts/00-install-privacy-lockdown.ps1
Normal 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
|
||||||
|
}
|
||||||
177
Solidworks Licenses/scripts/01-block-telemetry-hosts.ps1
Normal file
177
Solidworks Licenses/scripts/01-block-telemetry-hosts.ps1
Normal 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
|
||||||
233
Solidworks Licenses/scripts/02-disable-services.ps1
Normal file
233
Solidworks Licenses/scripts/02-disable-services.ps1
Normal 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
|
||||||
264
Solidworks Licenses/scripts/03-configure-firewall.ps1
Normal file
264
Solidworks Licenses/scripts/03-configure-firewall.ps1
Normal 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
|
||||||
334
Solidworks Licenses/scripts/04-disable-telemetry-registry.ps1
Normal file
334
Solidworks Licenses/scripts/04-disable-telemetry-registry.ps1
Normal 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
|
||||||
281
Solidworks Licenses/scripts/05-verify-lockdown.ps1
Normal file
281
Solidworks Licenses/scripts/05-verify-lockdown.ps1
Normal 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
|
||||||
@@ -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
|
||||||
|
================================================================================
|
||||||
@@ -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
|
||||||
|
================================================================================
|
||||||
127
Solidworks Licenses/solidworks-privacy-lockdown.md
Normal file
127
Solidworks Licenses/solidworks-privacy-lockdown.md
Normal 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
|
||||||
@@ -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) |
|
||||||
|
|||||||
1019
docs/MEGA-PLAN-BRAIN-SYSTEM.md
Normal file
1019
docs/MEGA-PLAN-BRAIN-SYSTEM.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user