off_telemetry_ps7.ps1 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. using namespace System.Collections.Generic
  2. <#
  3. .SYNOPSIS
  4. Enhanced comprehensive script to disable telemetry in Microsoft development tools with backup/restore functionality
  5. .DESCRIPTION
  6. This script disables telemetry, crash reporting, and data collection for:
  7. - Visual Studio 2015-2022 (only if installed)
  8. - Visual Studio Code (only if installed)
  9. - Visual Studio Background Download ( OFF automatic component downloads)
  10. - .NET CLI
  11. - NuGet
  12. - Various Visual Studio services
  13. .NOTES
  14. Must be run as Administrator
  15. Only modifies existing registry paths - does not create new ones
  16. Requires PowerShell 7.0+
  17. Includes comprehensive backup and restore functionality
  18. .PARAMETER CreateBackup
  19. Creates registry backup before making changes
  20. .PARAMETER RestoreBackup
  21. Restores registry from backup file
  22. .PARAMETER BackupPath
  23. Path for backup file (default: Desktop with timestamp)
  24. .PARAMETER DisableBackgroundDownload
  25. Specifically disable Visual Studio Background Download feature
  26. .EXAMPLE
  27. .\off_telemetry_ps7.ps1 -CreateBackup
  28. .\off_telemetry_ps7.ps1 -RestoreBackup -BackupPath "C:\Backup\registry_backup.reg"
  29. .\off_telemetry_ps7.ps1 -CreateBackup -BackupPath "C:\MyBackups\telemetry_backup.reg"
  30. .\off_telemetry_ps7.ps1 -DisableBackgroundDownload
  31. #>
  32. param(
  33. [switch]$CreateBackup,
  34. [switch]$RestoreBackup,
  35. [string]$BackupPath = "$env:USERPROFILE\Desktop\telemetry_backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').reg",
  36. [switch]$DisableBackgroundDownload
  37. )
  38. # Color scheme for consistent output
  39. $Colors = @{
  40. Title = 'Cyan'
  41. Section = 'Yellow'
  42. Success = 'Green'
  43. Info = 'Blue'
  44. Warning = 'Yellow'
  45. Error = 'Red'
  46. Gray = 'Gray'
  47. White = 'White'
  48. }
  49. Write-Host "======================================================" -ForegroundColor $Colors.Title
  50. Write-Host ""
  51. Write-Host " ███████╗██╗ ██╗██╗ ██████╗ ██╗ ██╗██████╗ " -ForegroundColor $Colors.Title
  52. Write-Host " ██╔════╝╚██╗██╔╝██║ ██╔═══██╗██║ ██║██╔══██╗" -ForegroundColor $Colors.Title
  53. Write-Host " █████╗ ╚███╔╝ ██║ ██║ ██║██║ ██║██║ ██║" -ForegroundColor $Colors.Title
  54. Write-Host " ██╔══╝ ██╔██╗ ██║ ██║ ██║██║ ██║██║ ██║" -ForegroundColor $Colors.Title
  55. Write-Host " ███████╗██╔╝ ██╗███████╗╚██████╔╝╚██████╔╝██████╔╝" -ForegroundColor $Colors.Title
  56. Write-Host " ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝" -ForegroundColor $Colors.Title
  57. Write-Host ""
  58. Write-Host " Present" -ForegroundColor $Colors.Gray
  59. Write-Host " Visual Studio Telemetry Disable Tool" -ForegroundColor $Colors.Gray
  60. Write-Host ""
  61. Write-Host "======================================================" -ForegroundColor $Colors.Title
  62. # =======================================================
  63. # BACKUP AND RESTORE FUNCTIONS
  64. # =======================================================
  65. function New-RegistryBackup {
  66. <#
  67. .SYNOPSIS
  68. Creates backup of telemetry-related registry keys
  69. .PARAMETER BackupFile
  70. Path where backup file will be created
  71. #>
  72. param([string]$BackupFile)
  73. Write-Host "`n--- Creating Registry Backup ---" -ForegroundColor $Colors.Section
  74. try {
  75. # Ensure backup directory exists
  76. $backupDir = Split-Path -Path $BackupFile -Parent
  77. if (!(Test-Path $backupDir)) {
  78. New-Item -Path $backupDir -ItemType Directory -Force | Out-Null
  79. Write-Host "→ Created backup directory: $backupDir" -ForegroundColor $Colors.Info
  80. }
  81. # Registry keys to backup
  82. $backupKeys = [ordered]@{
  83. "VSCommon_x64" = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VSCommon"
  84. "VSCommon_x86" = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VSCommon"
  85. "VSPolicies" = "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\VisualStudio"
  86. "VSUser" = "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio"
  87. "SQMClient_x64" = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SQMClient"
  88. "SQMClient_x86" = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\SQMClient"
  89. "VSSetup_x64" = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\Setup"
  90. "VSSetup_x86" = "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\Setup"
  91. }
  92. $backupCount = 0
  93. $backupContent = @()
  94. # Add header to backup file
  95. $backupContent += "Windows Registry Editor Version 5.00"
  96. $backupContent += ""
  97. $backupContent += "; Telemetry Registry Backup created on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
  98. $backupContent += "; Generated by Enhanced Telemetry Manager for PowerShell 7.0+"
  99. $backupContent += ""
  100. foreach ($keyInfo in $backupKeys.GetEnumerator()) {
  101. $keyName = $keyInfo.Key
  102. $keyPath = $keyInfo.Value
  103. Write-Host "→ Checking registry key: $keyName" -ForegroundColor $Colors.Info
  104. # Use reg.exe to export individual keys
  105. $tempFile = [System.IO.Path]::GetTempFileName() + ".reg"
  106. try {
  107. $process = Start-Process -FilePath "reg.exe" -ArgumentList @("export", $keyPath, $tempFile, "/y") -Wait -PassThru -NoNewWindow -RedirectStandardOutput $null -RedirectStandardError $null
  108. if ($process.ExitCode -eq 0 -and (Test-Path $tempFile)) {
  109. $keyContent = Get-Content -Path $tempFile -Encoding Unicode | Where-Object { $_ -notmatch "^Windows Registry Editor" -and $_ -ne "" }
  110. if ($keyContent) {
  111. $backupContent += ""
  112. $backupContent += "; === $keyName ==="
  113. $backupContent += $keyContent
  114. $backupCount++
  115. Write-Host "✓ Backed up: $keyName" -ForegroundColor $Colors.Success
  116. } else {
  117. Write-Host "→ Key exists but is empty: $keyName" -ForegroundColor $Colors.Gray
  118. }
  119. } else {
  120. Write-Host "→ Key not found (will be skipped): $keyName" -ForegroundColor $Colors.Gray
  121. }
  122. }
  123. finally {
  124. if (Test-Path $tempFile) {
  125. Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue
  126. }
  127. }
  128. }
  129. # Save consolidated backup file
  130. if ($backupCount -gt 0) {
  131. $backupContent | Out-File -FilePath $BackupFile -Encoding Unicode -Force
  132. Write-Host "✓ Registry backup completed: $BackupFile" -ForegroundColor $Colors.Success
  133. Write-Host "→ Backed up $backupCount registry sections" -ForegroundColor $Colors.Info
  134. return $true
  135. } else {
  136. Write-Host "→ No registry keys found to backup" -ForegroundColor $Colors.Warning
  137. return $false
  138. }
  139. }
  140. catch {
  141. Write-Host "✗ Failed to create backup: $_" -ForegroundColor $Colors.Error
  142. return $false
  143. }
  144. }
  145. function Restore-RegistryBackup {
  146. <#
  147. .SYNOPSIS
  148. Restores registry from backup file
  149. .PARAMETER BackupFile
  150. Path to backup file to restore from
  151. #>
  152. param([string]$BackupFile)
  153. Write-Host "`n--- Restoring Registry Backup ---" -ForegroundColor $Colors.Section
  154. if (!(Test-Path $BackupFile)) {
  155. Write-Host "✗ Backup file not found: $BackupFile" -ForegroundColor $Colors.Error
  156. return $false
  157. }
  158. try {
  159. Write-Host "→ Validating backup file format..." -ForegroundColor $Colors.Info
  160. # Validate backup file
  161. $content = Get-Content -Path $BackupFile -TotalCount 5
  162. if ($content[0] -notmatch "Windows Registry Editor") {
  163. Write-Host "✗ Invalid backup file format" -ForegroundColor $Colors.Error
  164. return $false
  165. }
  166. Write-Host "→ Importing registry backup..." -ForegroundColor $Colors.Info
  167. $process = Start-Process -FilePath "reg.exe" -ArgumentList @("import", $BackupFile) -Wait -PassThru -NoNewWindow
  168. if ($process.ExitCode -eq 0) {
  169. Write-Host "✓ Registry restored successfully from: $BackupFile" -ForegroundColor $Colors.Success
  170. Write-Host "→ Restart may be required for changes to take effect" -ForegroundColor $Colors.Warning
  171. return $true
  172. } else {
  173. Write-Host "✗ Failed to restore registry (Exit code: $($process.ExitCode))" -ForegroundColor $Colors.Error
  174. return $false
  175. }
  176. }
  177. catch {
  178. Write-Host "✗ Error restoring backup: $_" -ForegroundColor $Colors.Error
  179. return $false
  180. }
  181. }
  182. # =======================================================
  183. # ENHANCED REGISTRY FUNCTIONS
  184. # =======================================================
  185. function Set-RegistryValue {
  186. param(
  187. [string]$Path,
  188. [string]$Name,
  189. [object]$Value,
  190. [Microsoft.Win32.RegistryValueKind]$Type = [Microsoft.Win32.RegistryValueKind]::DWord
  191. )
  192. try {
  193. if (!(Test-Path $Path)) {
  194. Write-Host "Registry path not found, skipping: $Path" -ForegroundColor $Colors.Gray
  195. return $false
  196. }
  197. $currentValue = Get-ItemProperty -Path $Path -Name $Name -ErrorAction SilentlyContinue
  198. if ($null -ne $currentValue -and $currentValue.$Name -eq $Value) {
  199. Write-Host "✓ $Name already set to $Value in $Path" -ForegroundColor $Colors.Success
  200. return $true
  201. }
  202. $null = Set-ItemProperty -Path $Path -Name $Name -Value $Value -Type $Type -Force -ErrorAction Stop
  203. Write-Host "✓ Set $Name to $Value in $Path" -ForegroundColor $Colors.Success
  204. return $true
  205. }
  206. catch {
  207. Write-Host "✗ Failed to set $Name in $Path : $_" -ForegroundColor $Colors.Error
  208. return $false
  209. }
  210. }
  211. function Remove-TelemetryDirectory {
  212. param([string]$Path)
  213. if (Test-Path $Path) {
  214. try {
  215. $itemCount = (Get-ChildItem -Path $Path -Recurse -ErrorAction SilentlyContinue | Measure-Object).Count
  216. if ($itemCount -gt 0) {
  217. Remove-Item -Path $Path -Recurse -Force -Verbose:$false -ErrorAction Stop
  218. Write-Host "✓ Removed telemetry directory: $Path ($itemCount items)" -ForegroundColor $Colors.Success
  219. } else {
  220. Write-Host "→ Telemetry directory already empty: $Path" -ForegroundColor $Colors.Info
  221. }
  222. }
  223. catch {
  224. Write-Host "✗ Failed to remove: $Path - $_" -ForegroundColor $Colors.Error
  225. }
  226. } else {
  227. Write-Host "→ Telemetry directory not found: $Path" -ForegroundColor $Colors.Gray
  228. }
  229. }
  230. function Disable-BackgroundDownloadTasks {
  231. Write-Host "→ Checking for Visual Studio BackgroundDownload scheduled tasks..." -ForegroundColor $Colors.Info
  232. try {
  233. $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object {
  234. $_.TaskName -like "*BackgroundDownload*" -or
  235. ($_.TaskPath -like "*VisualStudio*" -and $_.TaskName -like "*BackgroundDownload*")
  236. }
  237. if ($tasks) {
  238. foreach ($task in $tasks) {
  239. Write-Host "→ Found task: $($task.TaskName) at $($task.TaskPath)" -ForegroundColor $Colors.Info
  240. if ($task.State -eq "Ready") {
  241. try {
  242. Disable-ScheduledTask -TaskName $task.TaskName -TaskPath $task.TaskPath -Confirm:$false -ErrorAction Stop
  243. Write-Host "✓ Disabled task: $($task.TaskName)" -ForegroundColor $Colors.Success
  244. }
  245. catch {
  246. Write-Host "✗ Could not disable task $($task.TaskName): $_" -ForegroundColor $Colors.Error
  247. }
  248. } else {
  249. Write-Host "✓ Task already disabled: $($task.TaskName)" -ForegroundColor $Colors.Success
  250. }
  251. }
  252. return $true
  253. } else {
  254. Write-Host "→ No Visual Studio BackgroundDownload tasks found" -ForegroundColor $Colors.Gray
  255. return $false
  256. }
  257. } catch {
  258. Write-Host "✗ Error checking scheduled tasks: $_" -ForegroundColor $Colors.Error
  259. return $false
  260. }
  261. }
  262. function Stop-BackgroundDownloadProcesses {
  263. Write-Host "→ Checking for running BackgroundDownload processes..." -ForegroundColor $Colors.Info
  264. try {
  265. $processes = Get-Process -Name "BackgroundDownload" -ErrorAction SilentlyContinue
  266. if ($processes) {
  267. foreach ($process in $processes) {
  268. try {
  269. Stop-Process -Id $process.Id -Force -ErrorAction Stop
  270. Write-Host "✓ Stopped process: BackgroundDownload.exe (PID: $($process.Id))" -ForegroundColor $Colors.Success
  271. }
  272. catch {
  273. Write-Host "✗ Could not stop process PID $($process.Id): $_" -ForegroundColor $Colors.Error
  274. }
  275. }
  276. return $true
  277. } else {
  278. Write-Host "→ No BackgroundDownload processes currently running" -ForegroundColor $Colors.Gray
  279. return $false
  280. }
  281. } catch {
  282. Write-Host "✗ Error checking processes: $_" -ForegroundColor $Colors.Error
  283. return $false
  284. }
  285. }
  286. function Remove-BackgroundDownloadTempFolders {
  287. Write-Host "→ Cleaning BackgroundDownload temporary folders..." -ForegroundColor $Colors.Info
  288. try {
  289. $tempPaths = @(
  290. "$env:TEMP",
  291. "$env:LOCALAPPDATA\Temp"
  292. )
  293. $foldersRemoved = 0
  294. foreach ($tempPath in $tempPaths) {
  295. if (Test-Path $tempPath) {
  296. $folders = Get-ChildItem -Path $tempPath -Directory -ErrorAction SilentlyContinue |
  297. Where-Object { $_.Name -match "^[a-zA-Z0-9]{8}\." }
  298. foreach ($folder in $folders) {
  299. $bgDownloadPath = Join-Path $folder.FullName "resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service\BackgroundDownload.exe"
  300. if (Test-Path $bgDownloadPath) {
  301. try {
  302. Remove-Item -Path $folder.FullName -Recurse -Force -ErrorAction Stop
  303. Write-Host "✓ Removed temp folder: $($folder.Name)" -ForegroundColor $Colors.Success
  304. $foldersRemoved++
  305. }
  306. catch {
  307. Write-Host "✗ Could not remove folder $($folder.Name): $_" -ForegroundColor $Colors.Error
  308. }
  309. }
  310. }
  311. }
  312. }
  313. if ($foldersRemoved -eq 0) {
  314. Write-Host "→ No BackgroundDownload temp folders found" -ForegroundColor $Colors.Gray
  315. }
  316. return $foldersRemoved -gt 0
  317. } catch {
  318. Write-Host "✗ Error cleaning temp folders: $_" -ForegroundColor $Colors.Error
  319. return $false
  320. }
  321. }
  322. function Set-EnvironmentVariableIfNeeded {
  323. param(
  324. [string]$Name,
  325. [string]$Value,
  326. [string]$Target = 'User'
  327. )
  328. try {
  329. $currentValue = [Environment]::GetEnvironmentVariable($Name, $Target)
  330. if ($currentValue -eq $Value) {
  331. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  332. Write-Host "$Name " -NoNewline -ForegroundColor $Colors.Info
  333. Write-Host "already set to " -NoNewline -ForegroundColor $Colors.White
  334. Write-Host "$Value" -ForegroundColor $Colors.Success
  335. } else {
  336. [Environment]::SetEnvironmentVariable($Name, $Value, $Target)
  337. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  338. Write-Host "Set " -NoNewline -ForegroundColor $Colors.White
  339. Write-Host "$Name " -NoNewline -ForegroundColor $Colors.Info
  340. Write-Host "to " -NoNewline -ForegroundColor $Colors.White
  341. Write-Host "$Value" -ForegroundColor $Colors.Success
  342. }
  343. return $true
  344. }
  345. catch {
  346. Write-Host "✗ Failed to set environment variable $Name : $_" -ForegroundColor $Colors.Error
  347. return $false
  348. }
  349. }
  350. # =======================================================
  351. # MAIN SCRIPT LOGIC - HANDLE BACKUP/RESTORE OPERATIONS
  352. # =======================================================
  353. # Handle restore operation first
  354. if ($RestoreBackup) {
  355. $restored = Restore-RegistryBackup -BackupFile $BackupPath
  356. if ($restored) {
  357. Write-Host "`n✓ Restore operation completed successfully!" -ForegroundColor $Colors.Success
  358. Write-Host "→ Your telemetry settings have been restored from backup" -ForegroundColor $Colors.Info
  359. } else {
  360. Write-Host "`n✗ Restore operation failed!" -ForegroundColor $Colors.Error
  361. }
  362. Write-Host "`nPress Enter to exit..." -ForegroundColor $Colors.White
  363. Read-Host
  364. exit
  365. }
  366. # Handle backup creation
  367. if ($CreateBackup) {
  368. $backupCreated = New-RegistryBackup -BackupFile $BackupPath
  369. if ($backupCreated) {
  370. Write-Host "`n✓ Backup created successfully at: $BackupPath" -ForegroundColor $Colors.Success
  371. Write-Host "→ You can restore with: .\off_telemetry_ps7.ps1 -RestoreBackup -BackupPath '$BackupPath'" -ForegroundColor $Colors.Info
  372. } else {
  373. Write-Host "`n→ Backup creation completed (no existing telemetry settings found)" -ForegroundColor $Colors.Warning
  374. }
  375. Write-Host "`nOptions:" -ForegroundColor $Colors.White
  376. Write-Host "1. Continue with telemetry disable (recommended)" -ForegroundColor $Colors.Info
  377. Write-Host "2. Exit and run backup restore later" -ForegroundColor $Colors.Info
  378. $choice = Read-Host "`nContinue with telemetry disable? (y/n)"
  379. if ($choice -ne 'y' -and $choice -ne 'Y' -and $choice -ne '1') {
  380. Write-Host "Exiting. Run the script again without -CreateBackup to disable telemetry." -ForegroundColor $Colors.Info
  381. exit
  382. }
  383. Write-Host ""
  384. }
  385. # =======================================================
  386. # VISUAL STUDIO VERSIONS DETECTION AND PROCESSING
  387. # =======================================================
  388. Write-Host "--- Checking and Disabling Visual Studio Telemetry (Existing Paths Only) ---" -ForegroundColor $Colors.Section
  389. # Visual Studio versions to check
  390. $vsVersions = @{
  391. "14.0" = "Visual Studio 2015"
  392. "15.0" = "Visual Studio 2017"
  393. "16.0" = "Visual Studio 2019"
  394. "17.0" = "Visual Studio 2022"
  395. }
  396. # Track which versions are actually installed
  397. $installedVersions = @()
  398. foreach ($version in $vsVersions.Keys) {
  399. $vsName = $vsVersions[$version]
  400. Write-Host "`n--- Checking $vsName (version $version) ---" -ForegroundColor $Colors.Info
  401. $foundVersion = $false
  402. # Check 64-bit paths
  403. if ([Environment]::Is64BitOperatingSystem) {
  404. $path64 = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\VSCommon\$version\SQM"
  405. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  406. Write-Host "Checking 64-bit path for " -NoNewline -ForegroundColor $Colors.White
  407. Write-Host "$vsName" -ForegroundColor $Colors.Info
  408. $result64 = Set-RegistryValue -Path $path64 -Name "OptIn" -Value 0
  409. if ($result64) {
  410. $foundVersion = $true
  411. }
  412. }
  413. # Check 32-bit paths
  414. $path32 = "HKLM:\SOFTWARE\Microsoft\VSCommon\$version\SQM"
  415. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  416. Write-Host "Checking 32-bit path for " -NoNewline -ForegroundColor $Colors.White
  417. Write-Host "$vsName" -ForegroundColor $Colors.Info
  418. $result32 = Set-RegistryValue -Path $path32 -Name "OptIn" -Value 0
  419. if ($result32) {
  420. $foundVersion = $true
  421. }
  422. # Track if this version was found
  423. if ($foundVersion) {
  424. $installedVersions += $version
  425. Write-Host "✓ Found $vsName installation" -ForegroundColor $Colors.Success
  426. }
  427. }
  428. # =======================================================
  429. # VISUAL STUDIO POLICY SETTINGS (Only if they exist)
  430. # =======================================================
  431. Write-Host "`n--- Checking Visual Studio Policy Settings ---" -ForegroundColor $Colors.Section
  432. # Base policy paths
  433. $policyBase = "HKLM:\SOFTWARE\Policies\Microsoft\VisualStudio"
  434. $feedbackPath = "$policyBase\Feedback"
  435. $sqmPath = "$policyBase\SQM"
  436. $telemetryPath = "HKCU:\Software\Microsoft\VisualStudio\Telemetry"
  437. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  438. Write-Host "Checking Visual Studio Policy paths..." -ForegroundColor $Colors.White
  439. # Feedback settings
  440. Set-RegistryValue -Path $feedbackPath -Name "DisableFeedbackDialog" -Value 1
  441. Set-RegistryValue -Path $feedbackPath -Name "DisableEmailInput" -Value 1
  442. Set-RegistryValue -Path $feedbackPath -Name "DisableScreenshotCapture" -Value 1
  443. # SQM and telemetry settings
  444. Set-RegistryValue -Path $sqmPath -Name "OptIn" -Value 0
  445. Set-RegistryValue -Path $telemetryPath -Name "TurnOffSwitch" -Value 1
  446. # =======================================================
  447. # ADDITIONAL VISUAL STUDIO REGISTRY PATHS
  448. # =======================================================
  449. Write-Host "`n--- Checking Additional Visual Studio Registry Paths ---" -ForegroundColor $Colors.Section
  450. # Additional paths that might exist
  451. $additionalPaths = @(
  452. "HKCU:\Software\Microsoft\VisualStudio\14.0\General",
  453. "HKCU:\Software\Microsoft\VisualStudio\15.0\General",
  454. "HKCU:\Software\Microsoft\VisualStudio\16.0\General",
  455. "HKCU:\Software\Microsoft\VisualStudio\17.0\General"
  456. )
  457. foreach ($path in $additionalPaths) {
  458. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  459. Write-Host "Checking additional path..." -ForegroundColor $Colors.White
  460. Set-RegistryValue -Path $path -Name "EnableSQM" -Value 0
  461. }
  462. # Check Experience Improvement Program paths
  463. $experiencePaths = @(
  464. "HKLM:\SOFTWARE\Microsoft\SQMClient",
  465. "HKLM:\SOFTWARE\Wow6432Node\Microsoft\SQMClient"
  466. )
  467. foreach ($path in $experiencePaths) {
  468. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  469. Write-Host "Checking SQM Client path..." -ForegroundColor $Colors.White
  470. Set-RegistryValue -Path $path -Name "CEIPEnable" -Value 0
  471. }
  472. # =======================================================
  473. # TELEMETRY DIRECTORIES CLEANUP
  474. # =======================================================
  475. Write-Host "`n--- Checking Telemetry Directories ---" -ForegroundColor $Colors.Section
  476. $telemetryDirs = @(
  477. "$env:APPDATA\vstelemetry",
  478. "$env:LOCALAPPDATA\Microsoft\VSApplicationInsights",
  479. "$env:PROGRAMDATA\Microsoft\VSApplicationInsights",
  480. "$env:TEMP\Microsoft\VSApplicationInsights",
  481. "$env:TEMP\VSFaultInfo",
  482. "$env:TEMP\VSFeedbackIntelliCodeLogs",
  483. "$env:TEMP\VSFeedbackPerfWatsonData",
  484. "$env:TEMP\VSFeedbackVSRTCLogs",
  485. "$env:TEMP\VSRemoteControl",
  486. "$env:TEMP\VSTelem",
  487. "$env:TEMP\VSTelem.Out"
  488. )
  489. foreach ($dir in $telemetryDirs) {
  490. Remove-TelemetryDirectory -Path $dir
  491. }
  492. # =======================================================
  493. # .NET AND NUGET TELEMETRY DISABLE
  494. # =======================================================
  495. Write-Host "`n--- Disabling .NET and NuGet Telemetry ---" -ForegroundColor $Colors.Section
  496. # Check and set .NET CLI telemetry
  497. Set-EnvironmentVariableIfNeeded -Name 'DOTNET_CLI_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  498. # Check and set NuGet telemetry
  499. Set-EnvironmentVariableIfNeeded -Name 'NUGET_TELEMETRY_OPTOUT' -Value 'true' -Target 'User'
  500. # =======================================================
  501. # VISUAL STUDIO STANDARD COLLECTOR SERVICE
  502. # =======================================================
  503. Write-Host "`n--- Managing VS Standard Collector Service ---" -ForegroundColor $Colors.Section
  504. $serviceName = 'VSStandardCollectorService150'
  505. $service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
  506. if ($service) {
  507. Write-Host "→ Found service: $serviceName" -ForegroundColor $Colors.Info
  508. # Check and stop service if running
  509. if ($service.Status -eq 'Running') {
  510. try {
  511. Stop-Service -Name $serviceName -Force -ErrorAction Stop
  512. Write-Host "✓ Stopped $serviceName" -ForegroundColor $Colors.Success
  513. }
  514. catch {
  515. Write-Host "✗ Could not stop $serviceName : $_" -ForegroundColor $Colors.Error
  516. }
  517. } else {
  518. Write-Host "→ Service $serviceName is already stopped (Status: $($service.Status))" -ForegroundColor $Colors.Info
  519. }
  520. # Check and disable service
  521. if ($service.StartType -eq 'Disabled') {
  522. Write-Host "✓ $serviceName already disabled" -ForegroundColor $Colors.Success
  523. } else {
  524. try {
  525. Set-Service -Name $serviceName -StartupType Disabled -Confirm:$false -ErrorAction Stop
  526. Write-Host "✓ Disabled $serviceName" -ForegroundColor $Colors.Success
  527. }
  528. catch {
  529. Write-Host "✗ Could not disable $serviceName : $_" -ForegroundColor $Colors.Error
  530. }
  531. }
  532. } else {
  533. Write-Host "→ $serviceName not found (already removed or not installed)" -ForegroundColor $Colors.Gray
  534. }
  535. # =======================================================
  536. # VISUAL STUDIO CODE SETTINGS
  537. # =======================================================
  538. Write-Host "`n--- Configuring Visual Studio Code Settings ---" -ForegroundColor $Colors.Section
  539. $vscodeSettings = "$env:APPDATA\Code\User\settings.json"
  540. $vscodeUserDir = "$env:APPDATA\Code\User"
  541. $vscodeDetected = $false
  542. if (!(Test-Path "$env:APPDATA\Code")) {
  543. Write-Host "→ Visual Studio Code not detected" -ForegroundColor $Colors.Gray
  544. } else {
  545. Write-Host "→ Visual Studio Code detected" -ForegroundColor $Colors.Info
  546. $vscodeDetected = $true
  547. # Create User directory if needed
  548. if (!(Test-Path $vscodeUserDir)) {
  549. try {
  550. $null = New-Item -Path $vscodeUserDir -ItemType Directory -Force
  551. Write-Host "→ Created VS Code User directory" -ForegroundColor $Colors.Info
  552. } catch {
  553. Write-Host "✗ Failed to create VS Code User directory: $_" -ForegroundColor $Colors.Error
  554. }
  555. }
  556. # Privacy settings
  557. $privacyConfig = @{
  558. "telemetry.enableTelemetry" = $false
  559. "telemetry.enableCrashReporter" = $false
  560. "workbench.enableExperiments" = $false
  561. "update.mode" = "manual"
  562. "update.showReleaseNotes" = $false
  563. "extensions.autoCheckUpdates" = $false
  564. "extensions.showRecommendationsOnlyOnDemand" = $true
  565. "git.autofetch" = $false
  566. "npm.fetchOnlinePackageInfo" = $false
  567. }
  568. try {
  569. # Load existing settings
  570. $settings = @{}
  571. if (Test-Path $vscodeSettings) {
  572. $content = Get-Content $vscodeSettings -Raw -ErrorAction SilentlyContinue
  573. if ($content -and $content.Trim()) {
  574. try {
  575. # Use PowerShell's built-in JSON cmdlets
  576. $settingsObj = $content | ConvertFrom-Json
  577. # Convert PSCustomObject to hashtable for easier manipulation
  578. $settings = @{}
  579. $settingsObj.PSObject.Properties | ForEach-Object {
  580. $settings[$_.Name] = $_.Value
  581. }
  582. Write-Host "→ Found existing VS Code settings file" -ForegroundColor $Colors.Info
  583. }
  584. catch {
  585. Write-Host "→ Could not parse existing settings, creating new ones" -ForegroundColor $Colors.Warning
  586. $settings = @{}
  587. }
  588. }
  589. }
  590. # Update settings
  591. $changesMade = $false
  592. foreach ($key in $privacyConfig.Keys) {
  593. $value = $privacyConfig[$key]
  594. if ($settings.ContainsKey($key) -and $settings[$key] -eq $value) {
  595. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  596. Write-Host "$key " -NoNewline -ForegroundColor $Colors.Info
  597. Write-Host "already set to " -NoNewline -ForegroundColor $Colors.White
  598. Write-Host "$value" -ForegroundColor $Colors.Success
  599. } else {
  600. $settings[$key] = $value
  601. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  602. Write-Host "Updated " -NoNewline -ForegroundColor $Colors.White
  603. Write-Host "$key " -NoNewline -ForegroundColor $Colors.Info
  604. Write-Host "to " -NoNewline -ForegroundColor $Colors.White
  605. Write-Host "$value" -ForegroundColor $Colors.Success
  606. $changesMade = $true
  607. }
  608. }
  609. # Save settings if changes were made
  610. if ($changesMade -or !(Test-Path $vscodeSettings)) {
  611. $json = $settings | ConvertTo-Json -Depth 10
  612. $json | Out-File -FilePath $vscodeSettings -Encoding UTF8
  613. Write-Host "✓ Saved VS Code privacy settings" -ForegroundColor $Colors.Success
  614. } else {
  615. Write-Host "→ No changes needed for VS Code settings" -ForegroundColor $Colors.Info
  616. }
  617. }
  618. catch {
  619. Write-Host "✗ Failed to update VS Code settings: $_" -ForegroundColor $Colors.Error
  620. }
  621. }
  622. # =======================================================
  623. # VISUAL STUDIO BACKGROUND DOWNLOAD DISABLE
  624. # =======================================================
  625. Write-Host "`n--- Disabling Visual Studio Background Download ---" -ForegroundColor $Colors.Section
  626. $backgroundDownloadProcessed = $false
  627. # Check if any Visual Studio versions are installed before proceeding
  628. if ($installedVersions.Count -gt 0) {
  629. Write-Host "→ Visual Studio detected, processing BackgroundDownload settings..." -ForegroundColor $Colors.Info
  630. # 1. Disable scheduled tasks
  631. $tasksProcessed = Disable-BackgroundDownloadTasks
  632. # 2. Set registry keys to disable background downloads
  633. Write-Host "→ Setting registry keys to disable background downloads..." -ForegroundColor $Colors.Info
  634. $regPaths = @(
  635. "HKLM:\SOFTWARE\Microsoft\VisualStudio\Setup",
  636. "HKLM:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\Setup"
  637. )
  638. $regKeysSet = $false
  639. foreach ($regPath in $regPaths) {
  640. # Check if this registry path should exist (based on architecture)
  641. $shouldProcess = $true
  642. if ($regPath -like "*Wow6432Node*" -and ![Environment]::Is64BitOperatingSystem) {
  643. $shouldProcess = $false
  644. }
  645. if ($shouldProcess) {
  646. # Create the registry path if it doesn't exist (since we're configuring VS Setup)
  647. if (!(Test-Path $regPath)) {
  648. try {
  649. $null = New-Item -Path $regPath -Force -ErrorAction Stop
  650. Write-Host "→ Created registry path: $regPath" -ForegroundColor $Colors.Info
  651. }
  652. catch {
  653. Write-Host "✗ Could not create registry path $regPath : $_" -ForegroundColor $Colors.Error
  654. continue
  655. }
  656. }
  657. # Set the registry values
  658. $regSettings = @{
  659. "BackgroundDownloadDisabled" = 1
  660. "DisableBackgroundDownloads" = 1
  661. "DisableAutomaticUpdates" = 1
  662. }
  663. foreach ($setting in $regSettings.GetEnumerator()) {
  664. $success = Set-RegistryValue -Path $regPath -Name $setting.Key -Value $setting.Value -Type 'DWord'
  665. if ($success) {
  666. $regKeysSet = $true
  667. }
  668. }
  669. }
  670. }
  671. # 3. Stop running processes
  672. $processesProcessed = Stop-BackgroundDownloadProcesses
  673. # 4. Clean temporary folders
  674. $tempFoldersProcessed = Remove-BackgroundDownloadTempFolders
  675. # 5. Verification
  676. Write-Host "→ Verifying BackgroundDownload configuration..." -ForegroundColor $Colors.Info
  677. try {
  678. $verificationSuccess = $false
  679. # Check registry settings
  680. foreach ($regPath in $regPaths) {
  681. if (Test-Path $regPath) {
  682. $regValues = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue
  683. if ($regValues -and $regValues.BackgroundDownloadDisabled -eq 1) {
  684. Write-Host "✓ Registry verification: BackgroundDownloadDisabled = 1 in $regPath" -ForegroundColor $Colors.Success
  685. $verificationSuccess = $true
  686. }
  687. }
  688. }
  689. if (!$verificationSuccess) {
  690. Write-Host "→ Could not verify registry settings" -ForegroundColor $Colors.Warning
  691. }
  692. } catch {
  693. Write-Host "→ Verification error: $_" -ForegroundColor $Colors.Warning
  694. }
  695. # Set processed flag if any operation was successful
  696. $backgroundDownloadProcessed = $tasksProcessed -or $regKeysSet -or $processesProcessed -or $tempFoldersProcessed
  697. } else {
  698. Write-Host "→ No Visual Studio installations detected, skipping BackgroundDownload configuration" -ForegroundColor $Colors.Gray
  699. }
  700. # =======================================================
  701. # ADDITIONAL POWERSHELL 7 TELEMETRY CHECKS
  702. # =======================================================
  703. Write-Host "`n--- PowerShell 7 Telemetry Checks ---" -ForegroundColor $Colors.Section
  704. # Check if PowerShell telemetry is disabled
  705. try {
  706. $psDataCollection = [Microsoft.PowerShell.Telemetry.ApplicationInsightsTelemetry]::Enabled -eq $false
  707. if ($psDataCollection) {
  708. Write-Host "✓ PowerShell telemetry already disabled" -ForegroundColor $Colors.Success
  709. } else {
  710. Write-Host "→ PowerShell telemetry status:" -ForegroundColor $Colors.Info
  711. }
  712. } catch {
  713. Write-Host "→ Could not check PowerShell telemetry status" -ForegroundColor $Colors.Gray
  714. }
  715. # Check PowerShell environment variables
  716. Set-EnvironmentVariableIfNeeded -Name 'POWERSHELL_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  717. # =======================================================
  718. # SUMMARY
  719. # =======================================================
  720. Write-Host "`n========================================" -ForegroundColor $Colors.Title
  721. Write-Host "TELEMETRY DISABLE COMPLETE" -ForegroundColor $Colors.Title
  722. Write-Host "========================================" -ForegroundColor $Colors.Title
  723. Write-Host "`nProcessed telemetry settings for:" -ForegroundColor $Colors.White
  724. # Visual Studio versions with status colors
  725. if ($installedVersions.Count -gt 0) {
  726. foreach ($version in $installedVersions) {
  727. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  728. Write-Host "$($vsVersions[$version]) " -NoNewline -ForegroundColor $Colors.Info
  729. Write-Host "(detected and processed)" -ForegroundColor $Colors.Success
  730. }
  731. } else {
  732. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  733. Write-Host "No Visual Studio versions detected" -ForegroundColor $Colors.Gray
  734. }
  735. # Visual Studio Code with status colors
  736. if ($vscodeDetected) {
  737. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  738. Write-Host "Visual Studio Code " -NoNewline -ForegroundColor $Colors.Info
  739. Write-Host "(detected and configured)" -ForegroundColor $Colors.Success
  740. } else {
  741. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  742. Write-Host "Visual Studio Code " -NoNewline -ForegroundColor $Colors.Info
  743. Write-Host "(not found)" -ForegroundColor $Colors.Gray
  744. }
  745. # .NET CLI status
  746. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  747. Write-Host ".NET CLI " -NoNewline -ForegroundColor $Colors.Info
  748. Write-Host "(telemetry disabled)" -ForegroundColor $Colors.Success
  749. # NuGet status
  750. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  751. Write-Host "NuGet " -NoNewline -ForegroundColor $Colors.Info
  752. Write-Host "(telemetry disabled)" -ForegroundColor $Colors.Success
  753. # VS Standard Collector Service status
  754. if ($null -ne $service) {
  755. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  756. Write-Host "VS Standard Collector Service " -NoNewline -ForegroundColor $Colors.Info
  757. Write-Host "(processed)" -ForegroundColor $Colors.Success
  758. } else {
  759. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  760. Write-Host "VS Standard Collector Service " -NoNewline -ForegroundColor $Colors.Info
  761. Write-Host "(not found)" -ForegroundColor $Colors.Gray
  762. }
  763. # PowerShell 7 status
  764. $psTelemetryOptOut = [Environment]::GetEnvironmentVariable('POWERSHELL_TELEMETRY_OPTOUT', 'User')
  765. if ($psTelemetryOptOut -eq '1') {
  766. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  767. Write-Host "PowerShell 7 telemetry " -NoNewline -ForegroundColor $Colors.Info
  768. Write-Host "(opt-out configured via environment variable)" -ForegroundColor $Colors.Success
  769. } else {
  770. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  771. Write-Host "PowerShell 7 telemetry " -NoNewline -ForegroundColor $Colors.Info
  772. Write-Host "(opt-out not configured; current value: $($psTelemetryOptOut ?? 'not set'))" -ForegroundColor $Colors.Gray
  773. }
  774. # Visual Studio Background Download status
  775. if ($backgroundDownloadProcessed) {
  776. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  777. Write-Host "Visual Studio Background Download " -NoNewline -ForegroundColor $Colors.Info
  778. Write-Host "(disabled)" -ForegroundColor $Colors.Success
  779. } else {
  780. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  781. Write-Host "Visual Studio Background Download " -NoNewline -ForegroundColor $Colors.Info
  782. Write-Host "(not processed)" -ForegroundColor $Colors.Gray
  783. }
  784. # Customer Experience Improvement Program status
  785. $experienceDisabled = $true
  786. foreach ($path in $experiencePaths) {
  787. $value = Get-ItemProperty -Path $path -Name "CEIPEnable" -ErrorAction SilentlyContinue
  788. if ($value -and $value.CEIPEnable -ne 0) {
  789. $experienceDisabled = $false
  790. break
  791. }
  792. }
  793. if ($experienceDisabled) {
  794. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  795. Write-Host "Customer Experience Improvement Program " -NoNewline -ForegroundColor $Colors.Info
  796. Write-Host "(disabled)" -ForegroundColor $Colors.Success
  797. } else {
  798. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray
  799. Write-Host "Customer Experience Improvement Program " -NoNewline -ForegroundColor $Colors.Info
  800. Write-Host "(not fully disabled)" -ForegroundColor $Colors.Gray
  801. }
  802. # Telemetry Directories Cleanup status
  803. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success
  804. Write-Host "Telemetry Directories Cleanup " -NoNewline -ForegroundColor $Colors.Info
  805. Write-Host "(processed)" -ForegroundColor $Colors.Success
  806. # =======================================================
  807. # ADDITIONAL FEATURES AND ENVIRONMENT VARIABLES
  808. # =======================================================
  809. Write-Host "`n--- Optional: Additional Features and Environment Variables ---" -ForegroundColor $Colors.Section
  810. Write-Host "This will perform additional configuration:" -ForegroundColor $Colors.Info
  811. Write-Host "• Disable Visual Studio Settings Synchronization" -ForegroundColor $Colors.Info
  812. Write-Host "• Disable Live Share" -ForegroundColor $Colors.Info
  813. Write-Host "• Disable IntelliCode" -ForegroundColor $Colors.Info
  814. Write-Host "• Disable CodeLens" -ForegroundColor $Colors.Info
  815. Write-Host "• Set additional environment variables (INTELLICODE_TELEMETRY_OPTOUT, LIVESHARE_TELEMETRY_OPTOUT, VSSDK_TELEMETRY_OPTOUT)" -ForegroundColor $Colors.Info
  816. $enableAdditional = Read-Host "`nEnable additional configuration? (y/n)"
  817. if ($enableAdditional -eq 'y' -or $enableAdditional -eq 'Y' -or $enableAdditional -eq 'yes' -or $enableAdditional -eq 'Yes' -or $enableAdditional -eq 'YES') {
  818. # =======================================================
  819. # VISUAL STUDIO ADDITIONAL FEATURES DISABLE
  820. # =======================================================
  821. Write-Host "`n--- Disabling Additional Visual Studio Features ---" -ForegroundColor $Colors.Section
  822. if ($installedVersions.Count -gt 0) {
  823. foreach ($version in $installedVersions) {
  824. $vsName = $vsVersions[$version]
  825. Write-Host "`n--- Processing Additional Features for $vsName (version $version) ---" -ForegroundColor $Colors.Info
  826. # =======================================================
  827. # SETTINGS SYNCHRONIZATION
  828. # =======================================================
  829. Write-Host "→ Disabling Settings Synchronization..." -ForegroundColor $Colors.Info
  830. $settingsPaths = @(
  831. "HKCU:\Software\Microsoft\VisualStudio\$version\Settings",
  832. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\Settings"
  833. )
  834. foreach ($path in $settingsPaths) {
  835. Set-RegistryValue -Path $path -Name "SyncSettings" -Value 0
  836. Set-RegistryValue -Path $path -Name "EnableRoaming" -Value 0
  837. Set-RegistryValue -Path $path -Name "EnableSync" -Value 0
  838. Set-RegistryValue -Path $path -Name "DisableSync" -Value 1
  839. }
  840. # Additional settings sync paths
  841. $syncPath = "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\ConnectedServices"
  842. Set-RegistryValue -Path $syncPath -Name "Provider.Enabled" -Value 0
  843. # =======================================================
  844. # LIVE SHARE
  845. # =======================================================
  846. Write-Host "→ Disabling Live Share..." -ForegroundColor $Colors.Info
  847. $liveSharePaths = @(
  848. "HKCU:\Software\Microsoft\VisualStudio\$version\LiveShare",
  849. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\LiveShare"
  850. )
  851. foreach ($path in $liveSharePaths) {
  852. Set-RegistryValue -Path $path -Name "Enabled" -Value 0
  853. Set-RegistryValue -Path $path -Name "EnableTelemetry" -Value 0
  854. Set-RegistryValue -Path $path -Name "DisableTelemetry" -Value 1
  855. Set-RegistryValue -Path $path -Name "OptedIn" -Value 0
  856. }
  857. # Live Share telemetry
  858. $liveShareTelemetryPath = "HKCU:\Software\Microsoft\VisualStudio\$version\LiveShare\Telemetry"
  859. Set-RegistryValue -Path $liveShareTelemetryPath -Name "Enabled" -Value 0
  860. Set-RegistryValue -Path $liveShareTelemetryPath -Name "OptOut" -Value 1
  861. # =======================================================
  862. # INTELLICODE
  863. # =======================================================
  864. Write-Host "→ Disabling IntelliCode..." -ForegroundColor $Colors.Info
  865. $intelliCodePaths = @(
  866. "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliCode",
  867. "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliSense\IntelliCode",
  868. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\IntelliCode"
  869. )
  870. foreach ($path in $intelliCodePaths) {
  871. Set-RegistryValue -Path $path -Name "DisableTelemetry" -Value 1
  872. Set-RegistryValue -Path $path -Name "EnableTelemetry" -Value 0
  873. Set-RegistryValue -Path $path -Name "OptedIn" -Value 0
  874. Set-RegistryValue -Path $path -Name "Enabled" -Value 0
  875. Set-RegistryValue -Path $path -Name "ModelDownloadEnabled" -Value 0
  876. }
  877. # IntelliCode privacy settings
  878. $intelliCodePrivacyPath = "HKCU:\Software\Microsoft\VisualStudio\$version\IntelliCode\Privacy"
  879. Set-RegistryValue -Path $intelliCodePrivacyPath -Name "TelemetryOptOut" -Value 1
  880. Set-RegistryValue -Path $intelliCodePrivacyPath -Name "DataCollection" -Value 0
  881. Set-RegistryValue -Path $intelliCodePrivacyPath -Name "UsageDataOptOut" -Value 1
  882. # =======================================================
  883. # CODELENS
  884. # =======================================================
  885. Write-Host "→ Disabling CodeLens..." -ForegroundColor $Colors.Info
  886. $codeLensPaths = @(
  887. "HKCU:\Software\Microsoft\VisualStudio\$version\CodeLens",
  888. "HKCU:\Software\Microsoft\VisualStudio\$version\TextEditor\CodeLens",
  889. "HKCU:\Software\Microsoft\VisualStudio\$version\ApplicationPrivateSettings\Microsoft\VisualStudio\CodeLens"
  890. )
  891. foreach ($path in $codeLensPaths) {
  892. Set-RegistryValue -Path $path -Name "Disabled" -Value 1
  893. Set-RegistryValue -Path $path -Name "ShowAuthorCodeLens" -Value 0
  894. Set-RegistryValue -Path $path -Name "ShowReferencesCodeLens" -Value 0
  895. Set-RegistryValue -Path $path -Name "ShowTestCodeLens" -Value 0
  896. Set-RegistryValue -Path $path -Name "Enabled" -Value 0
  897. }
  898. # CodeLens telemetry
  899. $codeLensTelemetryPath = "HKCU:\Software\Microsoft\VisualStudio\$version\CodeLens\Telemetry"
  900. Set-RegistryValue -Path $codeLensTelemetryPath -Name "Enabled" -Value 0
  901. Set-RegistryValue -Path $codeLensTelemetryPath -Name "OptOut" -Value 1
  902. }
  903. } else {
  904. Write-Host "→ No Visual Studio installations detected, skipping additional features" -ForegroundColor $Colors.Gray
  905. }
  906. # =======================================================
  907. # ADDITIONAL ENVIRONMENT VARIABLES
  908. # =======================================================
  909. Write-Host "`n--- Setting Additional Environment Variables ---" -ForegroundColor $Colors.Section
  910. Set-EnvironmentVariableIfNeeded -Name 'INTELLICODE_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  911. Set-EnvironmentVariableIfNeeded -Name 'LIVESHARE_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  912. Set-EnvironmentVariableIfNeeded -Name 'VSSDK_TELEMETRY_OPTOUT' -Value '1' -Target 'User'
  913. Write-Host "`n✓ Additional configuration completed" -ForegroundColor $Colors.Success
  914. } else {
  915. Write-Host "→ Skipping additional configuration" -ForegroundColor $Colors.Info
  916. }
  917. Write-Host "`nLegend:" -ForegroundColor $Colors.White
  918. Write-Host "✓ " -NoNewline -ForegroundColor $Colors.Success; Write-Host "Action completed successfully" -ForegroundColor $Colors.Gray
  919. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info; Write-Host "Information or preparatory action" -ForegroundColor $Colors.Gray
  920. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Gray; Write-Host "Component not found or not processed" -ForegroundColor $Colors.Gray
  921. Write-Host "✗ " -NoNewline -ForegroundColor $Colors.Error; Write-Host "Error occurred" -ForegroundColor $Colors.Gray
  922. Write-Host "`nUsage Examples:" -ForegroundColor $Colors.White
  923. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  924. Write-Host "Create backup first: " -NoNewline -ForegroundColor $Colors.White
  925. Write-Host ".\off_telemetry_ps7.ps1 -CreateBackup" -ForegroundColor $Colors.Info
  926. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  927. Write-Host "Restore from backup: " -NoNewline -ForegroundColor $Colors.White
  928. Write-Host ".\off_telemetry_ps7.ps1 -RestoreBackup -BackupPath 'path\to\backup.reg'" -ForegroundColor $Colors.Info
  929. Write-Host "→ " -NoNewline -ForegroundColor $Colors.Info
  930. Write-Host "Run without backup: " -NoNewline -ForegroundColor $Colors.White
  931. Write-Host ".\off_telemetry_ps7.ps1" -ForegroundColor $Colors.Info
  932. if (!$CreateBackup) {
  933. Write-Host "`n⚠ " -NoNewline -ForegroundColor $Colors.Warning
  934. Write-Host "Tip: Run with -CreateBackup parameter to create registry backup first" -ForegroundColor $Colors.Warning
  935. }
  936. Write-Host "`n⚠ " -NoNewline -ForegroundColor $Colors.Warning
  937. Write-Host "Restart may be required for all changes to take effect." -ForegroundColor $Colors.Warning
  938. Write-Host "`nPress Enter to exit..." -ForegroundColor $Colors.White
  939. $null = Read-Host