<# Clean-Autodesk-AppDataPurge.ps1 - 목표: AppData(로컬/로컬로우/로밍)의 Autodesk/AutoCAD 등 잔재는 전부 삭제, 도면/프로젝트가 있을 수 있는 Documents\Autodesk 는 보존. - 기능: 프로세스/서비스/스케줄러 정리, Uninstall 무인실행, Program Files/ProgramData 정리, 모든 사용자 AppData 정리(보존 제외 없음), 레지스트리/앱목록(Uninstall) 정리 - 사용: 시뮬레이션: powershell -ExecutionPolicy Bypass -File .\Clean-Autodesk-AppDataPurge.ps1 -WhatIf 실제실행 : powershell -ExecutionPolicy Bypass -File .\Clean-Autodesk-AppDataPurge.ps1 #> [CmdletBinding(SupportsShouldProcess)] param( [switch]$WhatIf ) # ----- 관리자 체크 ----- function Assert-Admin { $id=[Security.Principal.WindowsIdentity]::GetCurrent() $p=New-Object Security.Principal.WindowsPrincipal($id) if(-not $p.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)){ Write-Error "❌ 관리자 PowerShell로 다시 실행하세요." ; exit 1 } } Assert-Admin $ErrorActionPreference='Continue' $Host.UI.RawUI.WindowTitle="Autodesk Cleaner (AppData Purge, Docs Preserve)" Write-Host "Autodesk 정리 시작 (AppData=삭제, Documents\\Autodesk=보존)" -ForegroundColor Yellow # ----- 복원 지점(가능하면) ----- try { if($PSCmdlet.ShouldProcess("System","Create Restore Point")){ Checkpoint-Computer -Description "Pre-Autodesk-AppDataPurge" -RestorePointType "MODIFY_SETTINGS" | Out-Null } } catch { Write-Warning "복원지점 생성 실패: $($_.Exception.Message)" } # ----- 유틸 ----- function Stop-Kill($rx){ Get-Process -ErrorAction SilentlyContinue | Where-Object { $_.Name -match $rx } | ForEach-Object { try{ if($PSCmdlet.ShouldProcess($_.Name,"Stop-Process -Force")){ Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue } }catch{} } } function Remove-PathForce([string]$Path){ if(-not (Test-Path -LiteralPath $Path)){ return } try{ if($PSCmdlet.ShouldProcess($Path,"Remove-Item -Recurse -Force")){ try{ Get-ChildItem -LiteralPath $Path -Recurse -Force -ErrorAction SilentlyContinue | % { $_.Attributes='Normal' } }catch{} if(-not $WhatIf){ Remove-Item -LiteralPath $Path -Recurse -Force -ErrorAction SilentlyContinue } } } catch { Write-Warning "경로 삭제 실패: $Path -> $($_.Exception.Message)" } } function Remove-RegForce([string]$Key){ try{ if(Test-Path $Key){ if($PSCmdlet.ShouldProcess($Key,"Remove-Item (Reg) -Recurse -Force")){ if(-not $WhatIf){ Remove-Item $Key -Recurse -Force -ErrorAction SilentlyContinue } } } } catch { Write-Warning "레지스트리 삭제 실패: $Key -> $($_.Exception.Message)" } } function Start-SilentUninstall([string]$DisplayName,[string]$UninstallString){ if([string]::IsNullOrWhiteSpace($UninstallString)){ return $false } $un=$UninstallString.Trim(); $exe=$null; $args=$null if($un -match '^\s*"(.*?)"\s*(.*)$'){ $exe=$Matches[1]; $args=$Matches[2] } elseif($un -match '^\S+\s+'){ $parts=$un -split '\s+',2; $exe=$parts[0]; $args=($parts.Count -gt 1)?$parts[1]:$null } else{ $exe=$un; $args=$null } $attempts=@() if($exe -match '(?i)msiexec'){ $exe='msiexec.exe'; $attempts=@("$args /qn /norestart","$args /quiet /norestart") } else{ $attempts=@("$args","$args /S","$args /silent","$args /quiet","$args /VERYSILENT") } Write-Host (" - 언인스톨: {0}" -f $DisplayName) foreach($a in $attempts){ try{ if($PSCmdlet.ShouldProcess("$exe $a","Start-Process -Wait (silent)")){ if(-not $WhatIf){ Start-Process -FilePath $exe -ArgumentList $a -Wait -WindowStyle Hidden -ErrorAction SilentlyContinue } } } catch {} } return $true } # 모든 사용자(HKU) $AllHKUs = @(Get-ChildItem Registry::HKEY_USERS -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name) # ----- 1) 프로세스 ----- Write-Host "[1/8] 프로세스 종료..." -ForegroundColor Cyan $procRx='(?i)adsk|autodesk|genuine|adl(m|icensing)|desktop\s*app|accoreconsole|acad|revit|3ds(max)?|maya|inventor|navisworks|fusion|civil|advance\s*steel|recap' Stop-Kill $procRx # ----- 2) 서비스 ----- Write-Host "[2/8] 서비스 정지/비활성/삭제..." -ForegroundColor Cyan $svc = Get-Service -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '(?i)adsk|autodesk|genuine|licens|flex|desktop|clm|adlm' -or ($_.DisplayName -and $_.DisplayName -match '(?i)Autodesk|Genuine|Licens|FLEXnet|CLM|AdLM') } foreach($s in $svc){ try{ if($PSCmdlet.ShouldProcess($s.Name,"Stop/Disable/Delete")){ Stop-Service $s.Name -Force -ErrorAction SilentlyContinue Set-Service $s.Name -StartupType Disabled -ErrorAction SilentlyContinue & sc.exe delete "$($s.Name)" | Out-Null } } catch {} } Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services" -ErrorAction SilentlyContinue | ` Where-Object { $_.PSChildName -match '(?i)adsk|autodesk|licens|flex|clm|adlm' } | ` ForEach-Object { Remove-RegForce $_.PsPath } # ----- 3) 작업 스케줄러 ----- Write-Host "[3/8] 작업 스케줄러 정리..." -ForegroundColor Cyan try{ Get-ScheduledTask -ErrorAction SilentlyContinue | ` Where-Object { $_.TaskName -match '(?i)adsk|autodesk|genuine|desktop|licens|update' } | ` ForEach-Object { try{ if($PSCmdlet.ShouldProcess($_.TaskName,"Unregister-ScheduledTask")) { Unregister-ScheduledTask -TaskName $_.TaskName -TaskPath $_.TaskPath -Confirm:$false -ErrorAction SilentlyContinue } } catch {} } } catch {} # ----- 4) Uninstall 실행 (HKLM/HKCU/HKU) ----- Write-Host "[4/8] 레지스트리 기반 언인스톨..." -ForegroundColor Cyan $UninstallRoots = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" ) foreach($root in $UninstallRoots){ if(Test-Path $root){ Get-ChildItem $root -ErrorAction SilentlyContinue | ForEach-Object { $p = Get-ItemProperty $_.PsPath -ErrorAction SilentlyContinue $dn = "$($p.DisplayName)"; $pub="$($p.Publisher)"; $us="$($p.UninstallString)" if([string]::IsNullOrWhiteSpace($dn)){ return } if($dn -match '(?i)Autodesk|Revit|AutoCAD|Fusion|3ds\s*Max|Maya|Inventor|Navisworks|Civil\s*3D|Advance\s*Steel|AEC|Adsk' -or $pub -match '(?i)Autodesk'){ Start-SilentUninstall $dn $us | Out-Null } } } } foreach($hku in $AllHKUs){ $u = "Registry::${hku}\Software\Microsoft\Windows\CurrentVersion\Uninstall" if(Test-Path $u){ Get-ChildItem $u -ErrorAction SilentlyContinue | ForEach-Object { $p = Get-ItemProperty $_.PsPath -ErrorAction SilentlyContinue $dn="$($p.DisplayName)"; $pub="$($p.Publisher)"; $us="$($p.UninstallString)" if([string]::IsNullOrWhiteSpace($dn)){ return } if($dn -match '(?i)Autodesk|AutoCAD|Revit|Fusion|3ds|Maya' -or $pub -match '(?i)Autodesk'){ Start-SilentUninstall $dn $us | Out-Null } } } } # (선택) winget — 출력 포맷 이슈가 있을 수 있어 best-effort로만 시도 try{ if(Get-Command winget.exe -ErrorAction SilentlyContinue){ foreach($name in @("Autodesk","AutoCAD","Revit","Fusion","3ds Max","Maya","Inventor","Navisworks","Civil 3D","Advance Steel")){ try{ winget uninstall --source winget --silent --accept-package-agreements --accept-source-agreements --name "$name" | Out-Null } catch {} } } } catch {} # ----- 5) Program Files / ProgramData ----- Write-Host "[5/8] 프로그램 폴더 정리..." -ForegroundColor Cyan $ProgPaths = @( "$Env:ProgramFiles\Autodesk", "$Env:ProgramFiles(x86)\Autodesk", "$Env:ProgramFiles\Common Files\Autodesk Shared", "C:\ProgramData\Autodesk", "C:\ProgramData\FLEXnet", "C:\ProgramData\Autodesk\AdLM", "C:\ProgramData\Autodesk\CLM", "C:\ProgramData\Autodesk\AdskLicensingService" ) foreach($p in $ProgPaths){ Remove-PathForce $p } # ----- 6) 모든 사용자 AppData 정리(문서 보존) ----- Write-Host "[6/8] 모든 사용자 AppData 정리 (Documents\\Autodesk 보존)..." -ForegroundColor Cyan $Profiles = Get-ChildItem "C:\Users" -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notin @('Public','Default','Default User','All Users') } foreach($u in $Profiles){ $base=$u.FullName $AppDataTargets = @( Join-Path $base "AppData\Local\Autodesk", Join-Path $base "AppData\Local\Temp\Autodesk", Join-Path $base "AppData\Roaming\Autodesk", # AutoCAD 하위 명시(버전별 폴더명 포함) Join-Path $base "AppData\Roaming\Autodesk\AutoCAD*", Join-Path $base "AppData\Local\Autodesk\AutoCAD*" ) foreach($t in $AppDataTargets){ Remove-PathForce $t } # ⚠ Documents\Autodesk 는 보존 (아래 줄은 일부러 주석) # Remove-PathForce (Join-Path $base "Documents\Autodesk") } # ----- 7) 레지스트리/Uninstall 표시 정리 ----- Write-Host "[7/8] 레지스트리 및 '프로그램 추가/제거' 표시 정리..." -ForegroundColor Cyan $RegTargets = @( "HKLM:\SOFTWARE\Autodesk", "HKLM:\SOFTWARE\WOW6432Node\Autodesk" ) foreach($r in $RegTargets){ Remove-RegForce $r } # HKCU/HKU는 설정 보존 목적이면 스킵해도 되지만, AppData를 지웠으니 표시는 지움 foreach($r in @("HKCU:\SOFTWARE\Autodesk","HKCU:\SOFTWARE\AppDataLow\Software\Autodesk")){ Remove-RegForce $r } foreach($hku in $AllHKUs){ Remove-RegForce ("Registry::${hku}\Software\Autodesk") Remove-RegForce ("Registry::${hku}\Software\AppDataLow\Software\Autodesk") } # 앱 목록(Uninstall 키) 직접 제거 $AllUninstallRoots = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall", "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" ) foreach($root in $AllUninstallRoots){ if(Test-Path $root){ Get-ChildItem $root -ErrorAction SilentlyContinue | Where-Object { $p = Get-ItemProperty $_.PsPath -ErrorAction SilentlyContinue $p -and ($p.DisplayName -match '(?i)Autodesk|AutoCAD|Revit|Fusion|3ds|Maya|Inventor|Navisworks|Civil\s*3D|Advance\s*Steel') } | ForEach-Object { Remove-RegForce $_.PsPath } } } foreach($hku in $AllHKUs){ $u = "Registry::${hku}\Software\Microsoft\Windows\CurrentVersion\Uninstall" if(Test-Path $u){ Get-ChildItem $u -ErrorAction SilentlyContinue | Where-Object { $p=Get-ItemProperty $_.PsPath -ErrorAction SilentlyContinue $p -and ($p.DisplayName -match '(?i)Autodesk|AutoCAD|Revit|Fusion|3ds|Maya') } | ForEach-Object { Remove-RegForce $_.PsPath } } } # ----- 8) 환경변수/Temp ----- Write-Host "[8/8] 환경변수/Temp 정리..." -ForegroundColor Cyan [System.Environment]::GetEnvironmentVariables("Machine").Keys | ForEach-Object { if($_ -match '(?i)Autodesk|ADSK'){ if($PSCmdlet.ShouldProcess("Machine ENV:$_","Unset")){ if(-not $WhatIf){ [Environment]::SetEnvironmentVariable($_,$null,"Machine") } } } } [System.Environment]::GetEnvironmentVariables("User").Keys | ForEach-Object { if($_ -match '(?i)Autodesk|ADSK'){ if($PSCmdlet.ShouldProcess("User ENV:$_","Unset")){ if(-not $WhatIf){ [Environment]::SetEnvironmentVariable($_,$null,"User") } } } } try{ if($PSCmdlet.ShouldProcess("$env:TEMP\*","Temp purge")){ if(-not $WhatIf){ Get-ChildItem "$env:TEMP" -Recurse -Force -ErrorAction SilentlyContinue | Where-Object { $_.Name -match '(?i)Autodesk|Adsk' } | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue } } } catch {} Write-Host "`n✅ 완료: Autodesk 정리 (AppData 삭제 / Documents 보존)" -ForegroundColor Green Write-Host ℹ️ 재부팅 후 [설정→앱] 목록 확인. 남아있으면 한 번 더 실행." -ForegroundColor Green