diff --git a/Uninstall-AteraAgent.ps1 b/Uninstall-AteraAgent.ps1 new file mode 100644 index 0000000..f3629b6 --- /dev/null +++ b/Uninstall-AteraAgent.ps1 @@ -0,0 +1,118 @@ +Function SourceTools +{ . $([Scriptblock]::Create((New-Object Net.WebClient).DownloadString('https://dev.emberkom.com/emberkom/management-scripts/raw/branch/master/Tools.ps1'))) } +. SourceTools + +Function Get-UninstallCodes ([string]$DisplayName) { + 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' | ForEach-Object { + Get-ChildItem -Path $_ -ErrorAction SilentlyContinue | ForEach-Object { + If ( $(Get-ItemProperty -Path $_.PSPath -Name 'DisplayName' -ErrorAction SilentlyContinue) -and ($(Get-ItemPropertyValue -Path $_.PSPath -Name 'DisplayName' -ErrorAction SilentlyContinue) -eq $DisplayName) ) { + $str = (Get-ItemPropertyValue -Path $_.PSPath -Name 'UninstallString') + $code = $str.Substring(($str.Length - 37),36) + LogMsg " - ${code}" + $UninstallCodes.Add($code) | Out-Null + } + } + } +} + +Function Get-ProductKeys ([string]$ProductName) { + Get-ChildItem -Path 'HKCR:Installer\Products' | ForEach-Object { + If ( $(Get-ItemProperty -Path $_.PSPath -Name 'ProductName' -ErrorAction SilentlyContinue) -and ($(Get-ItemPropertyValue -Path $_.PSPath -Name 'ProductName' -ErrorAction SilentlyContinue) -eq $ProductName) ) { + $prod = $_.PSPath.Substring($_.PSPath.Length - 32) + LogMsg " - ${prod}" + $ProductKeys.Add($prod) | Out-Null + } + } +} + +Function Get-ServiceStatus ([string]$Name) { (Get-Service -Name $Name -ErrorAction SilentlyContinue).Status } + +Function Stop-RunningService ([string]$Name) { + If ( $(Get-ServiceStatus -Name $Name) -eq "Running" ) { LogMsg "Stopping : ${Name} service" ; Stop-Service -Name $Name -Force } +} + +Function Remove-StoppedService ([string]$Name) { + $s = (Get-ServiceStatus -Name $Name) + If ( $s ) { + If ( $s -eq "Stopped" ) { + LogMsg "Deleting : ${Name} service" + Start-Process "sc.exe" -ArgumentList "delete ${Name}" -Wait + } + } Else { LogMsg "Not Found: ${Name} service" } +} + +Function Stop-RunningProcess ([string]$Name) { + $p = (Get-Process -Name $_ -ErrorAction SilentlyContinue) + If ( $p ) { LogMsg "Stopping : ${Name}.exe" ; $p | Stop-Process -Force } + Else { LogMsg "Not Found: ${Name}.exe is not running"} +} + +Function Remove-Path ([string]$Path) { + If ( Test-Path $Path ) { + LogMsg "Deleting : ${Path}" + Remove-Item $Path -Recurse -Force + } Else { LogMsg "Not Found: ${Path}" } +} + +Function Get-AllExeFiles ([string]$Path) { + If ( Test-Path $Path ) { + Get-ChildItem -Path $Path -Filter *.exe -Recurse | ForEach-Object { $ExeFiles.Add($_.BaseName) | Out-Null } + } +} + +LogMsg "Uninstalling Atera agent" + +LogMsg "Mounting HKEY_CLASSES_ROOT registry hive" +New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT | Out-Null + +LogMsg "Getting MSI package codes from the uninstall key" +$UninstallCodes = New-Object System.Collections.ArrayList +'AteraAgent' | ForEach-Object { Get-UninstallCodes -DisplayName $_ } + +LogMsg "Getting product keys from the list of installed products" +$ProductKeys = New-Object System.Collections.ArrayList +'AteraAgent' | ForEach-Object { Get-ProductKeys -ProductName $_ } + +LogMsg "Directories that we may need to delete" +$Directories = @("${Env:ProgramFiles}\ATERA Networks") +$Directories | ForEach-Object { LogMsg " - ${_}" } + +LogMsg "Processes that we may need to terminate" +$ExeFiles = New-Object System.Collections.ArrayList +$Directories | ForEach-Object { Get-AllExeFiles -Path $_ } +$ExeFiles.Add('reg') | Out-Null +$ExeFiles | ForEach-Object { LogMsg " - ${_}.exe" } + +LogMsg "Windows services that we may need to stop and/or delete" +$ServiceList = @('AteraAgent') +$ServiceList | ForEach-Object { LogMsg " - ${_}" } + +LogMsg "Windows Registry keys we may need to delete" +$RegistryKeys = @('HKLM:SOFTWARE\ATERA Networks') +$RegistryKeys | ForEach-Object { LogMsg " - ${_}" } + +# Uninstall each MSI package code in $UninstallCodes +$UninstallCodes | ForEach-Object { LogMsg "Uninstall: ${_}" ; Start-Process "msiexec.exe" -ArgumentList "/X{${_}} /qn" -Wait } + +# Stop services if they're still running +$ServiceList | ForEach-Object { Stop-RunningService -Name $_ } + +# Terminate all relevant processes that may still be running +$ExeFiles | ForEach-Object { Stop-RunningProcess $_ } + +# Delete services if they're still present +$ServiceList | ForEach-Object { Remove-StoppedService -Name $_ } + +# Delete products from MSI installer registry +$ProductKeys | ForEach-Object { Remove-Path -Path "HKCR:Installer\Products\${_}" } + +# Delete registry keys +$RegistryKeys | ForEach-Object { Remove-Path -Path $_ } + +# Delete remaining directories +$Directories | ForEach-Object { Remove-Path -Path $_ } + +LogMsg "Unmount HKEY_CLASSES_ROOT registry hive" +Remove-PSDrive -Name HKCR + +LogMsg "Finished uninstalling Atera Agent" \ No newline at end of file