Public/Reset-SACLicensing.ps1
|
function Reset-SACLicensing { <# .SYNOPSIS Wipes Autodesk licensing data to force a clean re-authentication. .DESCRIPTION Clears the Autodesk CLM (Central Licensing Manager), AdskLicensing service data, per-user SSO token cache, and optionally Autodesk-specific FlexNet stubs. Restarts the AdskLicensing service after the wipe. This resolves common issues like: - "Autodesk keeps asking for activation" - "License not found" after account changes - Stuck multi-seat license reservations .PARAMETER SkipServiceRestart Switch. Do not restart the AdskLicensing service after clearing data. .PARAMETER IncludeFlexNet Switch. Also remove Autodesk-specific files (adsk*) from C:\ProgramData\FLEXnet\. Off by default since FLEXnet is a shared directory used by other software. .PARAMETER Silent Switch. Bypasses the confirmation prompt for RMM/headless execution. .EXAMPLE # Interactive: full licensing reset with service restart Reset-SACLicensing .EXAMPLE # RMM: silent reset including FlexNet stubs Reset-SACLicensing -IncludeFlexNet -Silent #> [CmdletBinding()] param ( [switch]$SkipServiceRestart, [switch]$IncludeFlexNet, [switch]$Silent ) $StopWatch = [System.Diagnostics.Stopwatch]::StartNew() $script:SACFailures = @() $ToDate = Get-Date -Format 'yyyyMMdd_HHmmss' $BaseTemp = if (Test-Path "C:\temp") { "C:\temp" } else { $env:TEMP } $LogDir = Join-Path $BaseTemp "AutodeskLicenseReset_$ToDate" New-Item -ItemType Directory -Path $LogDir -Force -ErrorAction SilentlyContinue | Out-Null $DebugLog = "$LogDir\LicenseResetDebug.log" $TranscriptLog = "$LogDir\LicenseResetTranscript.log" Start-Transcript -Path $TranscriptLog -Append -Force | Out-Null # --- Helper Functions (Centralized) --- function Remove-TargetPath { param ([string]$Path, [string]$Label) if (Test-Path $Path) { try { Remove-Item $Path -Recurse -Force -ErrorAction Stop Write-SACMsg "Cleared: $Label" "Success" return "OK" } catch { Write-SACQuietLog "Failed to remove $Path : $($_.Exception.Message)" $script:SACFailures += [PSCustomObject]@{ Component=$Label; Reason=$_.Exception.Message } return "FAILED" } } else { Write-SACQuietLog "Not found (skipped): $Path" return "NOT FOUND" } } if (-not (Test-SACRemoteSession)) { Clear-Host } Write-SACMsg "==========================================" "Info" Write-SACMsg " SAC LICENSING RESET INITIALIZED" "Info" Write-SACMsg " Debug Log: $DebugLog" "Info" Write-SACMsg "==========================================" "Info" if (Test-SACInteractive -Silent $Silent) { Write-SACMsg "Checking for running Autodesk applications..." "Info" $Running = Get-Process | Where-Object { try { ($_.Path -match "Autodesk") -or ($_.Description -match "Autodesk") -or ($_.Company -match "Autodesk") } catch { $false } } if ($Running) { Write-Host "`n[!] WARNING: The following Autodesk processes are still running:" -ForegroundColor Red $Running | Select-Object -Property Name, Description -Unique | ForEach-Object { Write-Host " - $($_.Name) ($($_.Description))" -ForegroundColor Yellow } Write-Host "`nPlease close all Autodesk applications before resetting licensing.`n" -ForegroundColor Red Stop-Transcript | Out-Null return } Write-Host "`n[!] CRITICAL: This will wipe all Autodesk licensing tokens and force re-authentication." -ForegroundColor Yellow Write-Host " Users will be logged out of all Autodesk products on this machine." -ForegroundColor Yellow if ($IncludeFlexNet) { Write-Host " [!] FLEXNET STUBS WILL BE REMOVED." -ForegroundColor Red } Write-Host "" $resp = Read-Host " Type 'LICENSING' to confirm" if ($resp -ne "LICENSING") { Write-SACMsg "Aborted by user." "Warning" Stop-Transcript | Out-Null return } } else { Write-SACMsg "Running in silent/non-interactive mode." "Info" } # --- Stop licensing and access services before wipe --- $ServicesToStop = @("AdskLicensing", "AdskAccessService", "AGSService", "Autodesk Genuine Service") foreach ($svcName in $ServicesToStop) { $svc = Get-Service -Name $svcName -ErrorAction SilentlyContinue if ($svc -and $svc.Status -eq "Running") { Write-SACMsg "Stopping $svcName service..." "Info" try { Stop-Service -Name $svcName -Force -ErrorAction Stop Write-SACMsg "$svcName service stopped." "Success" } catch { Write-SACQuietLog "Failed to stop ${svcName}: $($_.Exception.Message)" Write-SACMsg "Warning: Could not stop $svcName service. Files may be locked." "Warning" } } } # --- System-wide licensing paths --- $SystemTargets = @( @{ Path = "$($env:ProgramData)\Autodesk\CLM"; Label = "ProgramData CLM" }, @{ Path = "$($env:ProgramData)\Autodesk\AdskLicensing"; Label = "ProgramData AdskLicensing" }, @{ Path = "HKLM:\SOFTWARE\Autodesk\CLM"; Label = "Registry HKLM CLM" }, @{ Path = "HKLM:\SOFTWARE\Wow6432Node\Autodesk\CLM"; Label = "Registry HKLM CLM (WOW64)" } ) foreach ($target in $SystemTargets) { Remove-TargetPath -Path $target.Path -Label $target.Label | Out-Null } # --- Per-user licensing token paths --- $UserProfiles = Get-ChildItem -Path "C:\Users" -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -notmatch "^(Public|Default|Default User|All Users)$" } foreach ($profile in $UserProfiles) { $userName = $profile.Name $UserTargets = @( @{ Path = "$($profile.FullName)\AppData\Roaming\Autodesk\CLM"; Label = "[$userName] Roaming CLM cache" }, @{ Path = "$($profile.FullName)\AppData\Local\Autodesk\Web Services"; Label = "[$userName] Local Web Services (SSO tokens)" }, @{ Path = "$($profile.FullName)\AppData\Local\Autodesk\Autodesk Desktop App"; Label = "[$userName] Desktop App manager cache" } ) foreach ($target in $UserTargets) { Remove-TargetPath -Path $target.Path -Label $target.Label | Out-Null } } # --- Optional: FlexNet Autodesk stubs --- if ($IncludeFlexNet) { Write-SACMsg "Scanning FLEXnet for Autodesk-specific stubs..." "Info" $FlexNetDir = "C:\ProgramData\FLEXnet" if (Test-Path $FlexNetDir) { $adskFiles = Get-ChildItem -Path $FlexNetDir -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "^adsk" } foreach ($f in $adskFiles) { try { Remove-Item $f.FullName -Force -ErrorAction Stop Write-SACMsg "Removed FLEXnet stub: $($f.Name)" "Success" } catch { Write-SACQuietLog "Failed to remove FLEXnet file $($f.FullName): $($_.Exception.Message)" $script:SACFailures += [PSCustomObject]@{ Component="FLEXnet: $($f.Name)"; Reason=$_.Exception.Message } } } if ($adskFiles.Count -eq 0) { Write-SACMsg "No Autodesk FLEXnet stubs found." "Info" } } else { Write-SACMsg "FLEXnet directory not found - skipping." "Info" } } # --- Restart licensing service --- if (-not $SkipServiceRestart) { $LicService = Get-Service -Name "AdskLicensing" -ErrorAction SilentlyContinue if ($LicService) { Write-SACMsg "Restarting AdskLicensing service..." "Info" try { Start-Service -Name "AdskLicensing" -ErrorAction Stop Write-SACMsg "AdskLicensing service restarted successfully." "Success" } catch { Write-SACQuietLog "Failed to restart AdskLicensing: $($_.Exception.Message)" Write-SACMsg "AdskLicensing could not be restarted. You may need to reboot." "Warning" } } else { Write-SACMsg "AdskLicensing service not present on this machine - skipping restart." "Info" } } $StopWatch.Stop() $ElapsedTime = "{0:mm} min {0:ss} sec" -f $StopWatch.Elapsed Write-SACMsg "==========================================" "Info" Write-SACMsg " LICENSING RESET COMPLETED in $ElapsedTime" "Success" Write-SACMsg "==========================================" "Info" if ($script:SACFailures.Count -gt 0) { Write-Host "`n[!] FAILURES DETECTED:" -ForegroundColor Red Write-Host " (Note: These items may have been forcibly evicted/removed despite errors)" -ForegroundColor Gray foreach ($fail in $script:SACFailures) { Write-Host " - $($fail.Component)" -ForegroundColor Yellow Write-Host " Reason: $($fail.Reason)" -ForegroundColor DarkGray } Write-Host "`nPlease review the Debug Log: $DebugLog`n" -ForegroundColor Red } else { Write-Host "`n[*] All operations completed successfully.`n" -ForegroundColor Green } # Persist outcome so the interactive menu can show a status badge on return $AttentionFile = Join-Path $LogDir "AttentionItems.txt" if ($script:SACFailures.Count -gt 0) { $content = @( "AUTODESK LICENSING RESET - ITEMS REQUIRING ATTENTION", "Timestamp: $(Get-Date)", "Log Directory: $LogDir", "Note: Despite the errors below, these components may have been forcibly", "evicted or surgically removed from the system by the SAC engine.", "----------------------------------------------------------", "" ) foreach ($fail in $script:SACFailures) { $content += "[!] $($fail.Component)" $content += " Reason: $($fail.Reason)" $content += "" } $content | Out-File -FilePath $AttentionFile -Encoding utf8 } $script:SACLastRunStatus = [PSCustomObject]@{ Operation = 'Licensing Reset' Criticals = $script:SACFailures.Count Warnings = 0 Elapsed = $ElapsedTime LogDir = $LogDir AttentionItems = if ($script:SACFailures.Count -gt 0) { $AttentionFile } else { $null } } Stop-Transcript | Out-Null return $script:SACLastRunStatus } |