param( [Parameter(Mandatory=$false)][int]$CUSTOMER_ID=1, [Parameter(Mandatory=$false)][string]$INTEGRATOR_ID, [Parameter(Mandatory=$false)][string]$AGENT_FILENAME="AteraAgentSetup.msi", [Parameter(Mandatory=$false)][switch]$FORCE ) # Make sure $INTEGRATOR_ID exists, otherwise exit this script as an agent cannot be downloaded #If ( ($INTEGRATOR_ID -eq $null) -or ($INTEGRATOR_ID -eq '') ) { Exit } # Source the Tools.ps1 script 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 } } } # Build the path for $AGENT_INSTALLER $AGENT_INSTALLER = '{0}{1}' -f (GetTempPath), $AGENT_FILENAME # Make sure we need to install the agent If ( (Test-Path "${Env:ProgramFiles}\ATERA Networks\AteraAgent\AteraAgent.exe") -or (Test-Path "${Env:ProgramFiles(x86)}\ATERA Networks\AteraAgent\AteraAgent.exe") ) { $INSTALL = $false ; $PreviousInstall = $true ; LogMsg "Atera agent is already installed on this endpoint" } Else { $INSTALL = $true ; $PreviousInstall = $false } If ( $FORCE ) { $INSTALL = $true } If ( $INSTALL ) { # Uninstall if $FORCE is true If ( $PreviousInstall ) { LogMsg "Getting information from existing installation" $ACCOUNT_ID = (Get-ItemPropertyValue -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'AccountId' -ErrorAction SilentlyContinue) $AGENT_ID = (Get-ItemPropertyValue -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'AgentId' -ErrorAction SilentlyContinue) $CUSTOMER_ID = (Get-ItemPropertyValue -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'CompanyId' -ErrorAction SilentlyContinue) $INTEGRATOR_ID = (Get-ItemPropertyValue -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'IntegratorLogin' -ErrorAction SilentlyContinue) LogMsg "AccountID : ${ACCOUNT_ID}" LogMsg "AgentID : ${AGENT_ID}" LogMsg "CustomerID : ${CUSTOMER_ID}" LogMsg "IntegratorID: ${INTEGRATOR_ID}" 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\${_}" } LogMsg " Unmount HKEY_CLASSES_ROOT registry hive" Remove-PSDrive -Name HKCR # Delete registry keys $RegistryKeys | ForEach-Object { Remove-Path -Path $_ } # Delete remaining directories $Directories | ForEach-Object { Remove-Path -Path $_ } LogMsg "Finished uninstalling Atera Agent" } # Replace the '@' with '%40' - not sure why this is necessary, but it is $INTEGRATOR_ID = $INTEGRATOR_ID.Replace('@','%40') # Download agent installer Download-File -URL "https://app.atera.com/GetAgent/Msi/?customerId=${CUSTOMER_ID}&integratorLogin=${INTEGRATOR_ID}" -File "${AGENT_INSTALLER}" # Install the agent LogMsg "Installing Atera agent" Try { Start-Process "msiexec.exe" -ArgumentList "/i ""${AGENT_INSTALLER}"" /qn /norestart" -Wait } Catch { LogErr $_.Exception.Message } # Delete the agent installer LogMsg "Deleting ""${AGENT_INSTALLER}""" Try { Remove-Item $AGENT_INSTALLER -Force } Catch { LogErr $_.Exception.Message } If ( $PreviousInstall -and $ACCOUNT_ID -and $AGENT_ID -and $CUSTOMER_ID) { LogMsg "Restoring agent information from previous install" LogMsg " - Stopping AteraAgent service" Stop-Service -Name 'AteraAgent' -Force LogMsg " - Restoring AgentID and AccountID from previous install" Set-ItemProperty -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'AccountId' -Value $ACCOUNT_ID Set-ItemProperty -Path 'HKLM:SOFTWARE\ATERA Networks\AlphaAgent' -Name 'AgentId' -Value $AGENT_ID LogMsg " - Starting AteraAgent service" Start-Service -Name 'AteraAgent' } } # Delete this script Remove-Item $MyInvocation.MyCommand.Path -Force