off_telemetry_ps5_win7+.ps1 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. <#
  2. .SYNOPSIS
  3. Improved comprehensive script to disable telemetry in Microsoft development tools
  4. .DESCRIPTION
  5. =================================================================================
  6. Based on off_telemetry_ps5.ps1 but without "emojis" for OS win7-8.1
  7. P.S. Replace to text : [INFO], [SKIP]..
  8. =================================================================================
  9. This script safely disables telemetry, crash reporting, and data collection for:
  10. - Visual Studio 2015-2022 (only if installed)
  11. - Visual Studio Code (only if installed)
  12. - .NET CLI
  13. - NuGet
  14. - Various Visual Studio services
  15. .NOTES
  16. Must be run as Administrator
  17. Improved safety - only modifies existing registry paths
  18. Compatible with PowerShell 5.x
  19. Includes comprehensive backup and restore functionality
  20. .PARAMETER CreateBackup
  21. Creates registry backup before making changes
  22. .PARAMETER RestoreBackup
  23. Restores registry from backup file
  24. .PARAMETER BackupPath
  25. Path for backup file (default: Desktop)
  26. .EXAMPLE
  27. .\off_telemetry_ps5.ps1 -CreateBackup
  28. .\off_telemetry_ps5.ps1 -RestoreBackup -BackupPath "C:\Backup\registry_backup.reg"
  29. #>
  30. param(
  31. [switch]$CreateBackup,
  32. [switch]$RestoreBackup,
  33. [string]$BackupPath = "$env:USERPROFILE\Desktop\telemetry_backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').reg"
  34. )
  35. $serviceProcessed = $false
  36. # Color scheme for consistent output
  37. $Colors = @{
  38. Title = 'Cyan'
  39. Section = 'Yellow'
  40. Success = 'Green'
  41. Info = 'Blue'
  42. Warning = 'Yellow'
  43. Error = 'Red'
  44. Gray = 'Gray'
  45. }
  46. Write-Host "======================================================" -ForegroundColor $Colors.Title
  47. Write-Host " by EXLOUD" -ForegroundColor $Colors.Title
  48. Write-Host "======================================================" -ForegroundColor $Colors.Title
  49. # =======================================================
  50. # BACKUP AND RESTORE FUNCTIONS
  51. # =======================================================
  52. function New-RegistryBackup {
  53. param([string]$BackupFile)
  54. Write-Host "`n--- Creating Registry Backup ---" -ForegroundColor $Colors.Section
  55. try {
  56. $backupKeys = @(
  57. "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VSCommon",
  58. "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VSCommon",
  59. "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\VisualStudio",
  60. "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio"
  61. )
  62. $backupResult = $true
  63. foreach ($key in $backupKeys) {
  64. $regFile = $BackupFile -replace '\.reg$', "_$($key -replace '[\\:]', '_').reg"
  65. $null = & reg export $key $regFile /y 2>$null
  66. if ($LASTEXITCODE -eq 0) {
  67. Write-Host "[OK] Backed up: $key" -ForegroundColor $Colors.Success
  68. } else {
  69. Write-Host "[INFO] Key not found (skipped): $key" -ForegroundColor $Colors.Gray
  70. }
  71. }
  72. Write-Host "[OK] Registry backup completed" -ForegroundColor $Colors.Success
  73. return $backupResult
  74. }
  75. catch {
  76. Write-Host "[ERROR] Failed to create backup: $_" -ForegroundColor $Colors.Error
  77. return $false
  78. }
  79. }
  80. function Restore-RegistryBackup {
  81. param([string]$BackupFile)
  82. Write-Host "`n--- Restoring Registry Backup ---" -ForegroundColor $Colors.Section
  83. if (!(Test-Path $BackupFile)) {
  84. Write-Host "[ERROR] Backup file not found: $BackupFile" -ForegroundColor $Colors.Error
  85. return $false
  86. }
  87. try {
  88. $null = & reg import $BackupFile
  89. if ($LASTEXITCODE -eq 0) {
  90. Write-Host "[OK] Registry restored from: $BackupFile" -ForegroundColor $Colors.Success
  91. return $true
  92. } else {
  93. Write-Host "[ERROR] Failed to restore registry" -ForegroundColor $Colors.Error
  94. return $false
  95. }
  96. }
  97. catch {
  98. Write-Host "[ERROR] Error restoring backup: $_" -ForegroundColor $Colors.Error
  99. return $false
  100. }
  101. }
  102. # =======================================================
  103. # SAFE REGISTRY FUNCTIONS
  104. # =======================================================
  105. function Set-SafeRegistryValue {
  106. param(
  107. [string]$Path,
  108. [string]$Name,
  109. [object]$Value,
  110. [string]$Type = 'DWORD',
  111. [switch]$CreatePath
  112. )
  113. try {
  114. # Check if path exists
  115. if (!(Test-Path $Path)) {
  116. if ($CreatePath) {
  117. $null = New-Item -Path $Path -Force
  118. Write-Host "[INFO] Created registry path: $Path" -ForegroundColor $Colors.Info
  119. } else {
  120. Write-Host "[SKIP] Registry path not found, skipping: $Path" -ForegroundColor $Colors.Gray
  121. return $false
  122. }
  123. } else {
  124. Write-Host "[INFO] Found registry path: $Path" -ForegroundColor $Colors.Info
  125. }
  126. # Check current value
  127. $currentValue = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
  128. if ($currentValue -and $currentValue.$Name -eq $Value) {
  129. Write-Host "[OK] $Name already set to $Value" -ForegroundColor $Colors.Success
  130. return $true
  131. }
  132. # Set new value
  133. $null = New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType $Type -Force -ErrorAction Stop
  134. Write-Host "[OK] Set $Name to $Value in $Path" -ForegroundColor $Colors.Success
  135. return $true
  136. }
  137. catch {
  138. Write-Host "[ERROR] Failed to set $Name in $Path : $_" -ForegroundColor $Colors.Error
  139. return $false
  140. }
  141. }
  142. function Remove-TelemetryDirectory {
  143. param([string]$Path)
  144. if (Test-Path $Path) {
  145. try {
  146. $itemCount = (Get-ChildItem -Path $Path -Recurse -ErrorAction SilentlyContinue | Measure-Object).Count
  147. if ($itemCount -gt 0) {
  148. Remove-Item -Path $Path -Recurse -Force -ErrorAction Stop
  149. Write-Host "[OK] Removed telemetry directory: $Path ($itemCount items)" -ForegroundColor $Colors.Success
  150. } else {
  151. Write-Host "[INFO] Telemetry directory already empty: $Path" -ForegroundColor $Colors.Info
  152. }
  153. }
  154. catch {
  155. Write-Host "[ERROR] Failed to remove: $Path - $_" -ForegroundColor $Colors.Error
  156. }
  157. } else {
  158. Write-Host "[SKIP] Telemetry directory not found: $Path" -ForegroundColor $Colors.Gray
  159. }
  160. }
  161. function Set-SafeEnvironmentVariable {
  162. param(
  163. [string]$Name,
  164. [string]$Value,
  165. [string]$Target = 'User'
  166. )
  167. try {
  168. $currentValue = [Environment]::GetEnvironmentVariable($Name, $Target)
  169. if ($currentValue -eq $Value) {
  170. Write-Host "[OK] $Name already set to $Value" -ForegroundColor $Colors.Success
  171. } else {
  172. [Environment]::SetEnvironmentVariable($Name, $Value, $Target)
  173. Write-Host "[OK] Set $Name to $Value" -ForegroundColor $Colors.Success
  174. }
  175. return $true
  176. }
  177. catch {
  178. Write-Host "[ERROR] Failed to set environment variable $Name : $_" -ForegroundColor $Colors.Error
  179. return $false
  180. }
  181. }
  182. # =======================================================
  183. # MAIN SCRIPT LOGIC
  184. # =======================================================
  185. # Handle backup/restore operations
  186. if ($RestoreBackup) {
  187. $null = Restore-RegistryBackup -BackupFile $BackupPath
  188. Write-Host "`nRestore operation completed. Press Enter to exit..." -ForegroundColor $Colors.Info
  189. $null = Read-Host
  190. exit
  191. }
  192. if ($CreateBackup) {
  193. $null = New-RegistryBackup -BackupFile $BackupPath
  194. Write-Host "`nBackup created at: $BackupPath" -ForegroundColor $Colors.Info
  195. Write-Host "You can restore with: .\off_telemetry_ps5.ps1 -RestoreBackup -BackupPath '$BackupPath'" -ForegroundColor $Colors.Info
  196. $continue = Read-Host "`nContinue with telemetry disable? (y/n)"
  197. if ($continue -ne 'y' -and $continue -ne 'Y') {
  198. exit
  199. }
  200. }
  201. # =======================================================
  202. # DETECT INSTALLED VISUAL STUDIO VERSIONS
  203. # =======================================================
  204. Write-Host "`n--- Detecting Installed Visual Studio Versions ---" -ForegroundColor $Colors.Section
  205. $vsVersions = @{
  206. "14.0" = "Visual Studio 2015"
  207. "15.0" = "Visual Studio 2017"
  208. "16.0" = "Visual Studio 2019"
  209. "17.0" = "Visual Studio 2022"
  210. }
  211. $installedVersions = @()
  212. foreach ($version in $vsVersions.Keys) {
  213. $vsName = $vsVersions[$version]
  214. # Check multiple detection methods
  215. $detected = $false
  216. # Method 1: Registry SQM paths
  217. $paths = @(
  218. "HKLM:\SOFTWARE\Microsoft\VSCommon\$version",
  219. "HKLM:\SOFTWARE\Wow6432Node\Microsoft\VSCommon\$version"
  220. )
  221. foreach ($path in $paths) {
  222. if (Test-Path $path) {
  223. $detected = $true
  224. break
  225. }
  226. }
  227. # Method 2: Installation paths
  228. if (!$detected) {
  229. $installPaths = @(
  230. "${env:ProgramFiles}\Microsoft Visual Studio\*\*\Common7\IDE\devenv.exe",
  231. "${env:ProgramFiles(x86)}\Microsoft Visual Studio\*\*\Common7\IDE\devenv.exe",
  232. "${env:ProgramFiles(x86)}\Microsoft Visual Studio $version\*\Common7\IDE\devenv.exe"
  233. )
  234. foreach ($installPath in $installPaths) {
  235. if (Get-ChildItem -Path $installPath -ErrorAction SilentlyContinue) {
  236. $detected = $true
  237. break
  238. }
  239. }
  240. }
  241. if ($detected) {
  242. Write-Host "[OK] Detected: $vsName (version $version)" -ForegroundColor $Colors.Success
  243. $installedVersions += $version
  244. } else {
  245. Write-Host "[SKIP] Not found: $vsName (version $version)" -ForegroundColor $Colors.Gray
  246. }
  247. }
  248. if ($installedVersions.Count -eq 0) {
  249. Write-Host "[INFO] No Visual Studio installations detected" -ForegroundColor $Colors.Info
  250. }
  251. # =======================================================
  252. # VISUAL STUDIO TELEMETRY DISABLE (EXISTING INSTALLATIONS ONLY)
  253. # =======================================================
  254. Write-Host "`n--- Disabling Visual Studio Telemetry (Detected Installations) ---" -ForegroundColor $Colors.Section
  255. foreach ($version in $installedVersions) {
  256. $vsName = $vsVersions[$version]
  257. Write-Host "`n--- Processing $vsName (version $version) ---" -ForegroundColor $Colors.Info
  258. # Process both architectures
  259. $regPaths = @()
  260. if ([Environment]::Is64BitOperatingSystem) {
  261. $regPaths += "HKLM:\SOFTWARE\Wow6432Node\Microsoft\VSCommon\$version\SQM"
  262. }
  263. $regPaths += "HKLM:\SOFTWARE\Microsoft\VSCommon\$version\SQM"
  264. foreach ($regPath in $regPaths) {
  265. $null = Set-SafeRegistryValue -Path $regPath -Name "OptIn" -Value 0 -Type 'DWORD'
  266. }
  267. # Additional paths for this version
  268. $additionalPaths = @(
  269. "HKCU:\Software\Microsoft\VisualStudio\$version\General"
  270. )
  271. foreach ($path in $additionalPaths) {
  272. $null = Set-SafeRegistryValue -Path $path -Name "EnableSQM" -Value 0 -Type 'DWORD'
  273. }
  274. }
  275. # =======================================================
  276. # VISUAL STUDIO POLICY SETTINGS (CONSERVATIVE APPROACH)
  277. # =======================================================
  278. Write-Host "`n--- Checking Visual Studio Policy Settings ---" -ForegroundColor $Colors.Section
  279. # Only create policy paths if at least one VS version is installed
  280. if ($installedVersions.Count -gt 0) {
  281. Write-Host "[INFO] Visual Studio detected, configuring policies..." -ForegroundColor $Colors.Info
  282. # Policy paths (create only if VS is installed)
  283. $policyPaths = @{
  284. "HKLM:\SOFTWARE\Policies\Microsoft\VisualStudio\Feedback" = @{
  285. "DisableFeedbackDialog" = 1
  286. "DisableEmailInput" = 1
  287. "DisableScreenshotCapture" = 1
  288. }
  289. "HKLM:\SOFTWARE\Policies\Microsoft\VisualStudio\SQM" = @{
  290. "OptIn" = 0
  291. }
  292. "HKCU:\Software\Microsoft\VisualStudio\Telemetry" = @{
  293. "TurnOffSwitch" = 1
  294. }
  295. }
  296. foreach ($path in $policyPaths.Keys) {
  297. $settings = $policyPaths[$path]
  298. foreach ($setting in $settings.GetEnumerator()) {
  299. $null = Set-SafeRegistryValue -Path $path -Name $setting.Key -Value $setting.Value -Type 'DWORD' -CreatePath
  300. }
  301. }
  302. } else {
  303. Write-Host "[SKIP] No Visual Studio detected, skipping policy configuration" -ForegroundColor $Colors.Gray
  304. }
  305. # =======================================================
  306. # EXPERIENCE IMPROVEMENT PROGRAM
  307. # =======================================================
  308. Write-Host "`n--- Disabling Customer Experience Improvement Program ---" -ForegroundColor $Colors.Section
  309. $experiencePaths = @(
  310. "HKLM:\SOFTWARE\Microsoft\SQMClient",
  311. "HKLM:\SOFTWARE\Wow6432Node\Microsoft\SQMClient"
  312. )
  313. foreach ($path in $experiencePaths) {
  314. $null = Set-SafeRegistryValue -Path $path -Name "CEIPEnable" -Value 0 -Type 'DWORD'
  315. }
  316. # =======================================================
  317. # TELEMETRY DIRECTORIES CLEANUP
  318. # =======================================================
  319. Write-Host "`n--- Cleaning Telemetry Directories ---" -ForegroundColor $Colors.Section
  320. $telemetryDirs = @(
  321. "$env:APPDATA\vstelemetry",
  322. "$env:LOCALAPPDATA\Microsoft\VSApplicationInsights",
  323. "$env:PROGRAMDATA\Microsoft\VSApplicationInsights",
  324. "$env:TEMP\Microsoft\VSApplicationInsights",
  325. "$env:TEMP\VSFaultInfo",
  326. "$env:TEMP\VSFeedbackIntelliCodeLogs",
  327. "$env:TEMP\VSFeedbackPerfWatsonData",
  328. "$env:TEMP\VSFeedbackVSRTCLogs",
  329. "$env:TEMP\VSRemoteControl",
  330. "$env:TEMP\VSTelem",
  331. "$env:TEMP\VSTelem.Out"
  332. )
  333. foreach ($dir in $telemetryDirs) {
  334. Remove-TelemetryDirectory -Path $dir
  335. }
  336. # =======================================================
  337. # .NET AND NUGET TELEMETRY DISABLE
  338. # =======================================================
  339. Write-Host "`n--- Disabling .NET and NuGet Telemetry ---" -ForegroundColor $Colors.Section
  340. $null = Set-SafeEnvironmentVariable -Name 'DOTNET_CLI_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  341. $null = Set-SafeEnvironmentVariable -Name 'NUGET_TELEMETRY_OPTOUT' -Value 'true' -Target 'User'
  342. # =======================================================
  343. # VISUAL STUDIO STANDARD COLLECTOR SERVICE
  344. # =======================================================
  345. Write-Host "`n--- Managing VS Standard Collector Service ---" -ForegroundColor $Colors.Section
  346. $serviceName = 'VSStandardCollectorService150'
  347. $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
  348. if ($service) {
  349. Write-Host "[INFO] Found service: $serviceName" -ForegroundColor $Colors.Info
  350. # Stop service if running
  351. if ($service.Status -eq 'Running') {
  352. try {
  353. Stop-Service -Name $serviceName -Force -ErrorAction Stop
  354. Write-Host "[OK] Stopped $serviceName" -ForegroundColor $Colors.Success
  355. }
  356. catch {
  357. Write-Host "[ERROR] Could not stop $serviceName : $_" -ForegroundColor $Colors.Error
  358. }
  359. } else {
  360. Write-Host "[INFO] Service $serviceName already stopped (Status: $($service.Status))" -ForegroundColor $Colors.Info
  361. }
  362. # Disable service
  363. if ($service.StartType -eq 'Disabled') {
  364. Write-Host "[OK] $serviceName already disabled" -ForegroundColor $Colors.Success
  365. } else {
  366. try {
  367. Set-Service -Name $serviceName -StartupType Disabled -Confirm:$false -ErrorAction Stop
  368. Write-Host "[OK] Disabled $serviceName" -ForegroundColor $Colors.Success
  369. }
  370. catch {
  371. Write-Host "[ERROR] Could not disable $serviceName : $_" -ForegroundColor $Colors.Error
  372. }
  373. }
  374. } else {
  375. Write-Host "[SKIP] $serviceName not found (not installed)" -ForegroundColor $Colors.Gray
  376. }
  377. $serviceProcessed = ($null -ne $service)
  378. # =======================================================
  379. # VISUAL STUDIO CODE SETTINGS
  380. # =======================================================
  381. Write-Host "`n--- Configuring Visual Studio Code Settings ---" -ForegroundColor $Colors.Section
  382. $vscodeSettings = "$env:APPDATA\Code\User\settings.json"
  383. $vscodeUserDir = "$env:APPDATA\Code\User"
  384. $vscodeDetected = $false
  385. if (!(Test-Path "$env:APPDATA\Code")) {
  386. Write-Host "[SKIP] Visual Studio Code not detected" -ForegroundColor $Colors.Gray
  387. } else {
  388. Write-Host "[INFO] Visual Studio Code detected" -ForegroundColor $Colors.Info
  389. $vscodeDetected = $true
  390. # Create User directory if needed
  391. if (!(Test-Path $vscodeUserDir)) {
  392. try {
  393. $null = New-Item -Path $vscodeUserDir -ItemType Directory -Force
  394. Write-Host "[INFO] Created VS Code User directory" -ForegroundColor $Colors.Info
  395. } catch {
  396. Write-Host "[ERROR] Failed to create VS Code User directory: $_" -ForegroundColor $Colors.Error
  397. }
  398. }
  399. # Privacy settings
  400. $privacyConfig = @{
  401. "telemetry.enableTelemetry" = $false
  402. "telemetry.enableCrashReporter" = $false
  403. "workbench.enableExperiments" = $false
  404. "update.mode" = "manual"
  405. "update.showReleaseNotes" = $false
  406. "extensions.autoCheckUpdates" = $false
  407. "extensions.showRecommendationsOnlyOnDemand" = $true
  408. "git.autofetch" = $false
  409. "npm.fetchOnlinePackageInfo" = $false
  410. }
  411. try {
  412. # Load existing settings
  413. $settings = @{}
  414. if (Test-Path $vscodeSettings) {
  415. $content = Get-Content $vscodeSettings -Raw -ErrorAction SilentlyContinue
  416. if ($content -and $content.Trim()) {
  417. try {
  418. # Use PowerShell's built-in JSON cmdlets
  419. $settingsObj = $content | ConvertFrom-Json
  420. # Convert PSCustomObject to hashtable for easier manipulation
  421. $settings = @{}
  422. $settingsObj.PSObject.Properties | ForEach-Object {
  423. $settings[$_.Name] = $_.Value
  424. }
  425. Write-Host "[INFO] Found existing VS Code settings file" -ForegroundColor $Colors.Info
  426. }
  427. catch {
  428. Write-Host "> Could not parse existing settings, creating new ones" -ForegroundColor $Colors.Warning
  429. $settings = @{}
  430. }
  431. }
  432. }
  433. # Update settings
  434. $changesMade = $false
  435. foreach ($key in $privacyConfig.Keys) {
  436. $value = $privacyConfig[$key]
  437. if ($settings.ContainsKey($key) -and $settings[$key] -eq $value) {
  438. Write-Host "[OK] $key already set to $value" -ForegroundColor $Colors.Success
  439. } else {
  440. $settings[$key] = $value
  441. Write-Host "[OK] Updated $key to $value" -ForegroundColor $Colors.Success
  442. $changesMade = $true
  443. }
  444. }
  445. # Save settings if changes were made
  446. if ($changesMade -or !(Test-Path $vscodeSettings)) {
  447. $json = $settings | ConvertTo-Json -Depth 10
  448. $json | Out-File -FilePath $vscodeSettings -Encoding UTF8
  449. Write-Host "[OK] Saved VS Code privacy settings" -ForegroundColor $Colors.Success
  450. } else {
  451. Write-Host "[INFO] No changes needed for VS Code settings" -ForegroundColor $Colors.Info
  452. }
  453. }
  454. catch {
  455. Write-Host "[ERROR] Failed to update VS Code settings: $_" -ForegroundColor $Colors.Error
  456. }
  457. }
  458. # =======================================================
  459. # POWERSHELL TELEMETRY [off] FOR PS 7.x
  460. # =======================================================
  461. # Write-Host "`n--- Disabling PowerShell Telemetry ---" -ForegroundColor $Colors.Section
  462. # $null = Set-SafeEnvironmentVariable -Name 'POWERSHELL_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  463. # =======================================================
  464. # SUMMARY
  465. # =======================================================
  466. Write-Host "`n========================================" -ForegroundColor $Colors.Title
  467. Write-Host "TELEMETRY DISABLE COMPLETE" -ForegroundColor $Colors.Title
  468. Write-Host "========================================" -ForegroundColor $Colors.Title
  469. Write-Host "`nProcessed telemetry settings for:" -ForegroundColor White
  470. # Visual Studio versions with status colors
  471. if ($installedVersions.Count -gt 0) {
  472. foreach ($version in $installedVersions) {
  473. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  474. Write-Host "$($vsVersions[$version]) (detected)" -ForegroundColor $Colors.Success
  475. }
  476. } else {
  477. Write-Host "[SKIP] " -NoNewline -ForegroundColor $Colors.Gray
  478. Write-Host "No Visual Studio versions detected" -ForegroundColor $Colors.Gray
  479. }
  480. # Visual Studio Code with status colors
  481. if ($vscodeDetected) {
  482. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  483. Write-Host "Visual Studio Code (detected)" -ForegroundColor $Colors.Success
  484. } else {
  485. Write-Host "[SKIP] " -NoNewline -ForegroundColor $Colors.Gray
  486. Write-Host "Visual Studio Code (not found)" -ForegroundColor $Colors.Gray
  487. }
  488. # Other components with status indicators
  489. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  490. Write-Host ".NET CLI" -ForegroundColor $Colors.Success
  491. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  492. Write-Host "NuGet" -ForegroundColor $Colors.Success
  493. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  494. Write-Host "Settings Synchronization" -ForegroundColor $Colors.Success
  495. # VS Standard Collector Service status
  496. if ($serviceProcessed) {
  497. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  498. Write-Host "VS Standard Collector Service (processed)" -ForegroundColor $Colors.Success
  499. } else {
  500. Write-Host "[SKIP] " -NoNewline -ForegroundColor $Colors.Gray
  501. Write-Host "VS Standard Collector Service (not found)" -ForegroundColor $Colors.Gray
  502. }
  503. # Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  504. # Write-Host "PowerShell" -ForegroundColor $Colors.Success
  505. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  506. Write-Host "Customer Experience Improvement Program" -ForegroundColor $Colors.Success
  507. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success
  508. Write-Host "Telemetry Directories Cleanup" -ForegroundColor $Colors.Success
  509. # =======================================================
  510. # ADDITIONAL FEATURES AND ENVIRONMENT VARIABLES
  511. # =======================================================
  512. Write-Host "`n--- Optional: Additional Features and Environment Variables ---" -ForegroundColor $Colors.Section
  513. Write-Host "This will perform additional configuration:" -ForegroundColor $Colors.Info
  514. Write-Host "> Disable Visual Studio Settings Synchronization" -ForegroundColor $Colors.Info
  515. Write-Host "> Disable Live Share" -ForegroundColor $Colors.Info
  516. Write-Host "> Disable IntelliCode" -ForegroundColor $Colors.Info
  517. Write-Host "> Disable CodeLens" -ForegroundColor $Colors.Info
  518. Write-Host "> Set additional environment variables :" -ForegroundColor $Colors.Info
  519. Write-Host " - INTELLICODE_TELEMETRY_OPTOUT" -ForegroundColor $Colors.Info
  520. Write-Host " - LIVESHARE_TELEMETRY_OPTOUT" -ForegroundColor $Colors.Info
  521. Write-Host " - VSSDK_TELEMETRY_OPTOUT" -ForegroundColor $Colors.Info
  522. $enableAdditional = Read-Host "`nEnable additional configuration? (y/n)"
  523. if ($enableAdditional -eq 'y' -or $enableAdditional -eq 'Y' -or $enableAdditional -eq 'yes' -or $enableAdditional -eq 'Yes' -or $enableAdditional -eq 'YES') {
  524. # =======================================================
  525. # VISUAL STUDIO ADDITIONAL FEATURES DISABLE
  526. # =======================================================
  527. Write-Host "`n--- Disabling Additional Visual Studio Features ---" -ForegroundColor $Colors.Section
  528. if ($installedVersions.Count -gt 0) {
  529. foreach ($version in $installedVersions) {
  530. $vsName = $vsVersions[$version]
  531. Write-Host "`n--- Processing Additional Features for $vsName (version $version) ---" -ForegroundColor $Colors.Info
  532. # =======================================================
  533. # SETTINGS SYNCHRONIZATION
  534. # =======================================================
  535. Write-Host "[INFO] Disabling Settings Synchronization..." -ForegroundColor $Colors.Info
  536. $settingsPaths = @(
  537. "HKCU:\Software\Microsoft\VisualStudio\$version\Settings",
  538. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\Settings"
  539. )
  540. foreach ($path in $settingsPaths) {
  541. $null = Set-SafeRegistryValue -Path $path -Name "SyncSettings" -Value 0 -Type 'DWORD' -CreatePath
  542. $null = Set-SafeRegistryValue -Path $path -Name "EnableRoaming" -Value 0 -Type 'DWORD' -CreatePath
  543. $null = Set-SafeRegistryValue -Path $path -Name "EnableSync" -Value 0 -Type 'DWORD' -CreatePath
  544. $null = Set-SafeRegistryValue -Path $path -Name "DisableSync" -Value 1 -Type 'DWORD' -CreatePath
  545. }
  546. # Additional settings sync paths
  547. $syncPath = "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\ConnectedServices"
  548. $null = Set-SafeRegistryValue -Path $syncPath -Name "Provider.Enabled" -Value 0 -Type 'DWORD' -CreatePath
  549. # =======================================================
  550. # LIVE SHARE
  551. # =======================================================
  552. Write-Host "[INFO] Disabling Live Share..." -ForegroundColor $Colors.Info
  553. $liveSharePaths = @(
  554. "HKCU:\Software\Microsoft\VisualStudio\$version\LiveShare",
  555. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\LiveShare"
  556. )
  557. foreach ($path in $liveSharePaths) {
  558. $null = Set-SafeRegistryValue -Path $path -Name "Enabled" -Value 0 -Type 'DWORD' -CreatePath
  559. $null = Set-SafeRegistryValue -Path $path -Name "EnableTelemetry" -Value 0 -Type 'DWORD' -CreatePath
  560. $null = Set-SafeRegistryValue -Path $path -Name "DisableTelemetry" -Value 1 -Type 'DWORD' -CreatePath
  561. $null = Set-SafeRegistryValue -Path $path -Name "OptedIn" -Value 0 -Type 'DWORD' -CreatePath
  562. }
  563. # Live Share telemetry
  564. $liveShareTelemetryPath = "HKCU:\Software\Microsoft\VisualStudio\$version\LiveShare\Telemetry"
  565. $null = Set-SafeRegistryValue -Path $liveShareTelemetryPath -Name "Enabled" -Value 0 -Type 'DWORD' -CreatePath
  566. $null = Set-SafeRegistryValue -Path $liveShareTelemetryPath -Name "OptOut" -Value 1 -Type 'DWORD' -CreatePath
  567. # =======================================================
  568. # INTELLICODE
  569. # =======================================================
  570. Write-Host "[INFO] Disabling IntelliCode..." -ForegroundColor $Colors.Info
  571. $intelliCodePaths = @(
  572. "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliCode",
  573. "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliSense\IntelliCode",
  574. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\IntelliCode"
  575. )
  576. foreach ($path in $intelliCodePaths) {
  577. $null = Set-SafeRegistryValue -Path $path -Name "DisableTelemetry" -Value 1 -Type 'DWORD' -CreatePath
  578. $null = Set-SafeRegistryValue -Path $path -Name "EnableTelemetry" -Value 0 -Type 'DWORD' -CreatePath
  579. $null = Set-SafeRegistryValue -Path $path -Name "OptedIn" -Value 0 -Type 'DWORD' -CreatePath
  580. $null = Set-SafeRegistryValue -Path $path -Name "Enabled" -Value 0 -Type 'DWORD' -CreatePath
  581. $null = Set-SafeRegistryValue -Path $path -Name "ModelDownloadEnabled" -Value 0 -Type 'DWORD' -CreatePath
  582. }
  583. # IntelliCode privacy settings
  584. $intelliCodePrivacyPath = "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliCode\Privacy"
  585. $null = Set-SafeRegistryValue -Path $intelliCodePrivacyPath -Name "TelemetryOptOut" -Value 1 -Type 'DWORD' -CreatePath
  586. $null = Set-SafeRegistryValue -Path $intelliCodePrivacyPath -Name "DataCollection" -Value 0 -Type 'DWORD' -CreatePath
  587. $null = Set-SafeRegistryValue -Path $intelliCodePrivacyPath -Name "UsageDataOptOut" -Value 1 -Type 'DWORD' -CreatePath
  588. # =======================================================
  589. # CODELENS
  590. # =======================================================
  591. Write-Host "[INFO] Disabling CodeLens..." -ForegroundColor $Colors.Info
  592. $codeLensPaths = @(
  593. "HKCU:\Software\Microsoft\VisualStudio\$version\CodeLens",
  594. "HKCU:\Software\Microsoft\VisualStudio\$version\TextEditor\CodeLens",
  595. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\CodeLens"
  596. )
  597. foreach ($path in $codeLensPaths) {
  598. $null = Set-SafeRegistryValue -Path $path -Name "Disabled" -Value 1 -Type 'DWORD' -CreatePath
  599. $null = Set-SafeRegistryValue -Path $path -Name "ShowAuthorCodeLens" -Value 0 -Type 'DWORD' -CreatePath
  600. $null = Set-SafeRegistryValue -Path $path -Name "ShowReferencesCodeLens" -Value 0 -Type 'DWORD' -CreatePath
  601. $null = Set-SafeRegistryValue -Path $path -Name "ShowTestCodeLens" -Value 0 -Type 'DWORD' -CreatePath
  602. $null = Set-SafeRegistryValue -Path $path -Name "Enabled" -Value 0 -Type 'DWORD' -CreatePath
  603. }
  604. # CodeLens telemetry
  605. $codeLensTelemetryPath = "HKCU:\Software\Microsoft\VisualStudio\$version\CodeLens\Telemetry"
  606. $null = Set-SafeRegistryValue -Path $codeLensTelemetryPath -Name "Enabled" -Value 0 -Type 'DWORD' -CreatePath
  607. $null = Set-SafeRegistryValue -Path $codeLensTelemetryPath -Name "OptOut" -Value 1 -Type 'DWORD' -CreatePath
  608. }
  609. } else {
  610. Write-Host "[SKIP] No Visual Studio installations detected, skipping additional features" -ForegroundColor $Colors.Gray
  611. }
  612. # =======================================================
  613. # ADDITIONAL ENVIRONMENT VARIABLES
  614. # =======================================================
  615. Write-Host "`n--- Setting Additional Environment Variables ---" -ForegroundColor $Colors.Section
  616. $null = Set-SafeEnvironmentVariable -Name 'INTELLICODE_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  617. $null = Set-SafeEnvironmentVariable -Name 'LIVESHARE_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  618. $null = Set-SafeEnvironmentVariable -Name 'VSSDK_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  619. Write-Host "`n[OK] Additional configuration completed" -ForegroundColor $Colors.Success
  620. } else {
  621. Write-Host "[SKIP] Skipping additional configuration" -ForegroundColor $Colors.Info
  622. }
  623. Write-Host "`nLegend:" -ForegroundColor White
  624. Write-Host "[OK] " -NoNewline -ForegroundColor $Colors.Success; Write-Host "Action completed successfully"
  625. Write-Host "[INFO] " -NoNewline -ForegroundColor $Colors.Info; Write-Host "Information or preparatory action"
  626. Write-Host "[SKIP] " -NoNewline -ForegroundColor $Colors.Gray; Write-Host "Component not found, skipped"
  627. Write-Host "[ERROR] " -NoNewline -ForegroundColor $Colors.Error; Write-Host "Error occurred"
  628. if (!$CreateBackup) {
  629. Write-Host "`nTip: Run with -CreateBackup parameter to create registry backup first" -ForegroundColor $Colors.Warning
  630. }
  631. Write-Host "`nRestart may be required for all changes to take effect." -ForegroundColor $Colors.Warning
  632. Write-Host "Press Enter to exit..." -ForegroundColor White
  633. $null = Read-Host