# *********************************************************** # Copyright (c) 2024 by Ivanti, Inc. All rights reserved # *********************************************************** # Description: This script is used to deep clean the Ivanti # Secure Access Client (ISAC) from the system. This script # will remove all the ISAC related files, directories, # registries, and services from the system. # *********************************************************** # Version: 1.0 # *********************************************************** <# .SYNOPSIS This script performs a deep clean process for the Ivanti Secure Access Client (ISAC). .DESCRIPTION The ISACDeepCleanScriptSilent.ps1 script is designed to remove all traces of the Ivanti Secure Access Client from a system. It performs various cleanup tasks including uninstalling applications, deleting directories, removing registry entries, and terminating processes associated with ISAC. .PARAMETER None This script does not accept any parameters. .NOTES - This script should be run with administrative privileges. - The script is intended for use on Windows systems. - The script assumes the presence of certain file paths and registry keys associated with ISAC. If these paths or keys have been modified, the script may not function correctly. - The script may take some time to complete, depending on the number of user profiles and the amount of data to be cleaned up. - The script generates log files in the same directory where the script is located. The log files contain information about the cleanup process and any errors encountered during execution. The script performs the following tasks: 1. Checks if the script is running with administrative privileges. 2. Creates a log directory to store the script execution logs. 3. Suspends and stops the ISAC client. 4. Terminates ISAC processes running in user mode. 5. Removes ISAC user-mode registry entries for all user SIDs. 6. Uninstalls ISAC user mode applications like PSAL, Pulse Setup Client, Host checker, terminal services clients, etc. for all user SIDs. 7. Uninstalls ISAC. 8. Uninstalls Pulse Secure client. 9. Cleans up the ISAC/Pulse Secure specific registries. 10. Cleans up the ISAC/Pulse Secure installer classes registry entries. 11. Cleans up the ISAC/Pulse Secure uninstall registries. 12. Cleans up the ISAC/Pulse Secure product registries. 13. Cleans up the Pulse Secure component registries. 14. Cleans up the Pulse Secure folders registry entries. 15. Cleans up the ISAC/Pulse Secure residual files. .EXAMPLE .\ISACDeepCleanScriptSilent.ps1 Runs the script to perform the deep clean process for ISAC. #> # ************** Declarations ******************************* $MsiexecExe = "$Env:WINDIR\System32\msiexec.exe" $PowerShellExe = "$Env:WINDIR\System32\WindowsPowerShell\v1.0\powershell.exe" $CurrDir = Split-Path $Script:MyInvocation.MyCommand.Path $ScriptName = &{ $MyInvocation.ScriptName } $LogDir = "C:\Windows\Logs\Software\IvantiDeepCleanlogs" $LogFile = "C:\Windows\Logs\Software\IvantiDeepCleanProgress.log" $CmdLogFile = "C:\Windows\Logs\Software\IvantiCommandOutput.log" $ProgFileDir = '' $CommonProgFileDir = '' $PulseProdName = "Pulse Secure" $ISACProdName = "Ivanti Secure Access Client" $JuniperProdName = "Juniper Networks" $PsalName = "Pulse Application Launcher" $PulseServiceName = "PulseSecureService" $OSArch64Bit = "64-Bit" #**************** Functions ******************************* # Function to check if the OS is 64-bit Function Test-OS64Bit { $ProcessorType = (Get-WmiObject Win32_OperatingSystem).OSArchitecture If($OSArch64Bit -ieq $ProcessorType){ $True } Else { $False } } # Function to check if a file exists Function Test-FileExists { Param ( [string]$FilePath ) Test-Path -Path $FilePath } # Function to check if a directory exists Function Test-DirectoryExists { Param ( [String]$DirPath ) Test-Path -PathType container $DirPath } # Function to write log messages to the console and log file Function Write-LogMessage { Param ( [String]$Message ) $timeStamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") Write-Output $Message Add-Content $LogFile -value "[$timeStamp] | $Message" } # Function to remove a directory Function Remove-Directory { Param ( [String]$DirFullPath, [Bool]$FlushOnly ) If(Test-DirectoryExists -DirPath $DirFullPath) { If( $True -eq $FlushOnly ) { Write-LogMessage -Message "Flushing Directory: $DirFullPath" Remove-Item -Path "$DirFullPath\*" -Recurse -Force -Verbose *>> "$CmdLogFile" } Else { Write-LogMessage -Message "Removing Directory: $DirFullPath" Remove-Item -Path $DirFullPath -Recurse -Force -Verbose *>> "$CmdLogFile" } } Else { Write-LogMessage -Message "'$DirFullPath' does not exist" } } # Function to remove files with wildcard Function Remove-FileWithWildcard { Param ( [String]$DirFullPath, [String]$WildCharFileName ) Write-LogMessage -Message "Removing: $DirFullPath\$WildCharFileName" Remove-Item -Path $DirFullPath -Include $WildCharFileName -Recurse -Force -Verbose *>> "$CmdLogFile" } # Function to remove registry entries Function Remove-Registry { Param ( [String]$RegistryPath ) If(Test-FileExists -FilePath $RegistryPath) { Remove-Item -Path "$RegistryPath\*" -Recurse -Force -Verbose *>> "$CmdLogFile" Remove-Item -Path $RegistryPath -Recurse -Force -Verbose *>> "$CmdLogFile" } Else { Write-LogMessage -Message "'$RegistryPath' does not exist" } } # Function to check if the script is running in Admin mode Function Test-ScriptElevation { $currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent()) $currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) } # Function to stop a process by name Function Stop-ProcessByName { Param ( [String]$ProcessName ) Write-LogMessage -Message "Terminating '$ProcessName'" Stop-Process -Name $ProcessName -Force *>> "$CmdLogFile" } # Function to stop a service Function Stop-ServiceAction { Param ( [String]$ServiceName ) Write-LogMessage -Message "Stopping Service: '$ServiceName'" Stop-Service -Name $ServiceName -Force *>> "$CmdLogFile" } # *********** Deep Clean Script **************************** $IsOS64Bit = Test-OS64Bit If($IsOS64Bit){ $ProgFileDir = "${Env:PROGRAMFILES(X86)}" $CommonProgFileDir = "${Env:COMMONPROGRAMFILES(X86)}" } Else { $ProgFileDir = "$Env:PROGRAMFILES" $CommonProgFileDir = "$Env:COMMONPROGRAMFILES" } If(!(Test-DirectoryExists -DirPath $LogDir)) { Write-Output "Log Dir does not Exists, creating one..." New-Item -ItemType Directory -Path $LogDir } $JamUIPath = "$CommonProgFileDir\$PulseProdName\JamUI" $PulseExe = "$JamUIPath\Pulse.exe" # Check if the script is running in Admin mode If (-not (Test-ScriptElevation)) { Write-LogMessage -Message "The script is not running in Admin mode, so re-invoking it in Admin mode..." Start-Process -FilePath $PowerShellExe -ArgumentList " -File `"$ScriptName`"" -Verb RunAs Exit } # Flush the log directory Remove-Directory -DirFullPath $LogDir -FlushOnly $True # Start the Deep Clean Process Write-LogMessage -Message "************************************************************************************" Write-LogMessage -Message "Welcome to '$ISACProdName/$PulseProdName' Deep Clean Process" Write-LogMessage -Message "Copyright (c) 2024 by Ivanti, Inc. All rights reserved" Write-LogMessage -Message "************************************************************************************" # Check if the script is running as the system user $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent() $isSystemUser = $currentUser.Name -ieq 'NT AUTHORITY\SYSTEM' If ($isSystemUser) { Write-LogMessage -Message "Script is running as the system user" } Else { Write-LogMessage -Message "Script is not running as the system user" } If(Test-FileExists -FilePath $PulseExe) { # Suspend ISAC Write-LogMessage -Message "Suspending $ISACProdName ..." Start-Process -FilePath $PulseExe -ArgumentList "-suspend" -Wait Start-Sleep -Seconds 2 # Stop ISAC Write-LogMessage -Message "Stopping $ISACProdName ..." Start-Process -FilePath $PulseExe -ArgumentList "-stop" -Wait Start-Sleep -Seconds 2 } Else { Write-LogMessage -Message "Pulse.exe does not exist, skipping suspension and stop..." } # Terminate Pulse Secure Processes Write-LogMessage -Message "Terminating User Mode Processes ..." Stop-ProcessByName -ProcessName "Pulse" Stop-ProcessByName -ProcessName "PulseServiceAPI" Stop-ProcessByName -ProcessName "PulseSecure" Stop-ProcessByName -ProcessName "PulseSetupClient" Stop-ProcessByName -ProcessName "PulseApplicationLauncher" # Get the list of installed applications and their product codes Write-LogMessage -Message "Getting list of installed applications ..." $InstalledApps = Get-WmiObject Win32_Product | Select-Object Name, IdentifyingNumber $ISACProductCodes = @() $PulseSecureProductCodes = @() foreach ($App in $InstalledApps) { $Found = $false if ($App.Name -ieq $ISACProdName) { $ISACProductCodes += $App.IdentifyingNumber $Found = $true } if ($App.Name -ieq $PulseProdName) { $PulseSecureProductCodes += $App.IdentifyingNumber $Found = $true } if ($Found) { Write-LogMessage -Message "Name: $($App.Name), Product Code: $($App.IdentifyingNumber)" } } Write-LogMessage -Message "Uninstalling User Mode Applications ..." # List all user SIDs when no user is logged in Write-LogMessage -Message "Listing all user SIDs..." # Get the list of user SIDs from the registry $users = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" | Where-Object { $_.PSChildName -match 'S-\d-\d+-(\d+-){1,14}\d+$' } # Iterate through each user SID and display it foreach ($user in $users) { $userSID = $user.PSChildName Write-LogMessage -Message "User SID from Profile List: $userSID" } # Mount the HKU drive if it is not already mounted $bMounted = $false if (-not (Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) { Write-LogMessage -Message "Mounting HKU drive..." New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS *>> "$CmdLogFile" $bMounted = $true } # Remove the Pulse Secure registry entries for all user SIDs foreach ($user in $users) { $userSID = $user.PSChildName $fullRegPath = "HKU:\$userSID" Write-LogMessage -Message "User SID: $userSID" # Get the user profile path $userProfilePath = (Get-WmiObject Win32_UserProfile | Where-Object { $_.SID -ieq $userSID }).LocalPath # Load the user's registry hive $regHive = "HKEY_USERS\$userSID" $regFile = "$userProfilePath\NTUSER.DAT" Write-LogMessage -Message "Loading user's registry hive: $regHive from file: $regFile" reg load $regHive $regFile # >>>>>> Remove the PSAL registry entries >>>>>>>> $ProductsPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\$userSID\Products" $ProductKeys = Get-ChildItem -Path $ProductsPath foreach ($key in $ProductKeys) { $InstallRegPath = $key.PSPath + "\InstallProperties" $DisplayName = (Get-ItemProperty -Path $InstallRegPath).DisplayName $UninstallString = (Get-ItemProperty -Path $InstallRegPath).UninstallString $PsalName = "Pulse Application Launcher" if ($DisplayName -ieq $PsalName) { $ProductCode = $UninstallString | Select-String -Pattern "{[A-F0-9]{8}-([A-F0-9]{4}-){3}[A-F0-9]{12}}" -AllMatches | ForEach-Object { $_.Matches.Value } Write-LogMessage -Message "Product Code of PSAL for user: $userSID is: $ProductCode" Write-LogMessage -Message "Found PSAL from registry: $($key.PSPath), removing it now..." Remove-Registry -RegistryPath $key.PSPath } } $RegPath = "$fullRegPath\Software\Microsoft\Installer\Products" $ProductKeys = Get-ChildItem -Path $RegPath foreach ($key in $ProductKeys) { $ProductName = (Get-ItemProperty -Path $key.PSPath).ProductName $PsalName = "Pulse Application Launcher" if ($ProductName -ieq $PsalName) { Write-LogMessage -Message "Found $PsalName from registry: $($key.PSPath), removing it now..." Remove-Registry -RegistryPath $key.PSPath } } # <<<<<< Remove the PSAL registry entries <<<<<<<< # >>>>>> Remove the Pulse Secure Setup Client, HC and Terminal Services Client entries >>>>>>>> $RegPath = "$fullRegPath\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pulse_Setup_Client" Write-LogMessage -Message "Removing PSC Registry: $RegPath" Remove-Registry -RegistryPath $RegPath $RegPath = "$fullRegPath\Software\Microsoft\Windows\CurrentVersion\Uninstall\PulseSecure_Host_Checker" Write-LogMessage -Message "Removing HC Registry: $RegPath" Remove-Registry -RegistryPath $RegPath $RegPath = "$fullRegPath\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pulse_Term_Services" Write-LogMessage -Message "Removing Terminal Services Client Registry: $RegPath" Remove-Registry -RegistryPath $RegPath $RegPath = "$fullRegPath\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pulse_Citrix_Services" Write-LogMessage -Message "Removing Citrix Client Registry: $RegPath" Remove-Registry -RegistryPath $RegPath # <<<<<< Remove the Pulse Secure Setup Client, HC and Terminal Services Client entries <<<<<<<< # >>>>>> Remove the Pulse Secure registry entries >>>>>>>> $RegPath = "$fullRegPath\SOFTWARE\$PulseProdName" Write-LogMessage -Message "Removing Registry: $RegPath" Remove-Registry -RegistryPath $RegPath If($IsOS64Bit) { $RegPath = "$fullRegPath\SOFTWARE\Wow6432Node\$PulseProdName" Write-LogMessage -Message "Removing Registry: $RegPath" Remove-Registry -RegistryPath $RegPath } # <<<<<< Remove the Pulse Secure registry entries <<<<<<<< # >>>>>> Remove the Pulse Secure React App for the user >>>>>>>> # Remove the AppxPackage for the user $appxPackages = Get-AppxPackage -User $userSID | Where-Object { $_.Name -like "PulseSecureReactAppPkg*" } foreach ($appxPackage in $appxPackages) { Write-LogMessage -Message "Uninstalling package: $($appxPackage.PackageFullName) for user SID: $userSID" Remove-AppPackage -Package $($appxPackage.PackageFullName) -User $userSID *>> "$CmdLogFile" } # <<<<<< Remove the Pulse Secure React App for the user <<<<<<<< # Unload the user's registry hive Write-LogMessage -Message "Unloading user's registry hive: $regHive" reg unload $regHive } # Remove the PSC registry entries for the default user $RegPath = "HKU:\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pulse_Setup_Client" Write-LogMessage -Message "Removing PSC Registry: $RegPath" Remove-Registry -RegistryPath $RegPath # Remove the PSC registry entries for the system user $RegPath = "HKU:\S-1-5-18\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pulse_Setup_Client" Write-LogMessage -Message "Removing PSC Registry: $RegPath" Remove-Registry -RegistryPath $RegPath # Unmount the HKU drive if it was mounted if ($bMounted) { Write-LogMessage -Message "Unmounting HKU drive..." Remove-PSDrive -Name HKU *>> "$CmdLogFile" } Write-LogMessage -Message "Listing directories in $Env:SystemDrive\Users" $UserDirectories = Get-ChildItem -Path "$Env:SystemDrive\Users" -Directory foreach ($dir in $UserDirectories) { Write-LogMessage -Message "User Name: $($dir.Name)" $UserAppDataDir = "$($dir.FullName)\AppData\Roaming" Write-LogMessage -Message "User AppData Directory: $UserAppDataDir" # Uninstall the Setup Client Write-LogMessage -Message "Un-installing Setup Client for user: $($dir.Name)..." $SetupClientUninstaller="$UserAppDataDir\$PulseProdName\Setup Client\uninstall.exe" If(Test-FileExists -FilePath $SetupClientUninstaller) { Start-Process -FilePath $SetupClientUninstaller -ArgumentList "/S" -Wait Write-LogMessage -Message "SetupClient uninstalled successfully..." } Else { Write-LogMessage -Message "'$SetupClientUninstaller' does not exist" } # Uninstall the Host Checker Write-LogMessage -Message "Un-installing Host Checker for user: $($dir.Name)..." $HostCheckerUninstaller="$UserAppDataDir\$PulseProdName\Host Checker\uninstall.exe" If(Test-FileExists -FilePath $HostCheckerUninstaller) { Write-LogMessage -Message "Terminating Host Checker Processes" Stop-ProcessByName -ProcessName "dsHostChecker" Stop-ProcessByName -ProcessName "uacHostChecker" Start-Process -FilePath $HostCheckerUninstaller -ArgumentList "/S" -Wait Write-LogMessage -Message "Host Checker uninstalled successfully..." } Else { Write-LogMessage -Message "'$HostCheckerUninstaller' does not exist" } # Uninstall the Term Services Client Write-LogMessage -Message "Un-installing Term Services Client for user: $($dir.Name)..." $UninstallerFile="$UserAppDataDir\$PulseProdName\Pulse Terminal Services Client\uninstall.exe" If(Test-FileExists -FilePath $UninstallerFile) { Write-LogMessage -Message "Terminating Term Services Client Process" Stop-ProcessByName -ProcessName "dsTermServ" Start-Process -FilePath $UninstallerFile -ArgumentList "/S" -Wait Write-LogMessage -Message "The Terminal Services Client uninstalled successfully..." } Else { Write-LogMessage -Message "'$UninstallerFile' does not exist" } # Uninstall the Citrix Services Client Write-LogMessage -Message "Un-installing Citrix Client for user: $($dir.Name)..." $UninstallerFile="$UserAppDataDir\$PulseProdName\Pulse Secure Citrix Services Client\uninstall.exe" If(Test-FileExists -FilePath $UninstallerFile) { Write-LogMessage -Message "Terminating Citrix Client Process" Stop-ProcessByName -ProcessName "dsCitrixProxy" Start-Process -FilePath $UninstallerFile -ArgumentList "/S" -Wait Write-LogMessage -Message "The Citrix Client uninstalled successfully..." } Else { Write-LogMessage -Message "'$UninstallerFile' does not exist" } # Clean User Mode Residuals Write-LogMessage -Message "Cleaning User Mode Residuals for user: $($dir.Name)..." $DirName = "$UserAppDataDir\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$UserAppDataDir\PulseSecure" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$UserAppDataDir\..\LocalLow\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$UserAppDataDir\..\..\Library\Application Support\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $UserLocalAppDataDir = "$($dir.FullName)\AppData\Local" Write-LogMessage -Message "User Local AppData Directory: $UserLocalAppDataDir" $DirName = "$UserLocalAppDataDir\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$UserLocalAppDataDir\CrashDumps" Remove-FileWithWildcard -DirFullPath $DirName -WildCharFileName "Pulse*" $DirName = "$UserLocalAppDataDir\CrashDumps" Remove-FileWithWildcard -DirFullPath $DirName -WildCharFileName "cef*" $DirName = "$UserLocalAppDataDir\Temp" Remove-Directory -DirFullPath $DirName -FlushOnly $True } $DirName = "$Env:TEMP" Remove-Directory -DirFullPath $DirName -FlushOnly $True # Uninstall the Admin Mode ISAC Applications Write-LogMessage -Message "Terminating Admin Mode ISAC Processes" # Stop the Pulse Secure Service Stop-ServiceAction -ServiceName $PulseServiceName Stop-ProcessByName -ProcessName $PulseServiceName Stop-ServiceAction -ServiceName $PulseServiceName # Uninstall the Admin Mode ISAC Applications Write-LogMessage -Message "Uninstalling Admin Mode ISAC Applications..." If($IsOS64Bit){ # Uninstall the ActiveX Control (x64) Write-LogMessage -Message "Un-installing ActiveX Control (x64)..." $ActivexX64Uninstaller="$Env:SYSTEMDRIVE\Windows\Downloaded Program Files\PulseSetupClientCtrlUninstaller64.exe" If(Test-FileExists -FilePath $ActivexX64Uninstaller) { Start-Process -FilePath $ActivexX64Uninstaller -ArgumentList "/S" -Wait -Verb RunAs Write-LogMessage -Message "ActiveX X64 uninstalled successfully..." } Else { Write-LogMessage -Message "'$ActivexX64Uninstaller' does not exist" } } # Uninstall the ActiveX Control Write-LogMessage -Message "Un-installing ActiveX Control..." $ActivexUninstaller="$Env:SYSTEMDRIVE\Windows\Downloaded Program Files\PulseSetupClientCtrlUninstaller.exe" If(Test-FileExists -FilePath $ActivexUninstaller) { Start-Process -FilePath $ActivexUninstaller -ArgumentList "/S" -Wait -Verb RunAs Write-LogMessage -Message "ActiveX uninstalled successfully..." } Else { Write-LogMessage -Message "'$ActivexUninstaller' does not exist" } # Uninstall the ISAC Write-LogMessage -Message "Uninstalling ISAC Client instances if available..." $count=0 if($ISACProductCodes) { foreach ($code in $ISACProductCodes) { $count++ Write-LogMessage -Message "Product code: $code. Uninstalling the Client using the Product Code now..." Start-Process -FilePath $MsiexecExe -ArgumentList " /x $code /qn /L*vx `"$LogDir\ISAC_$($count)_uninstall.log`"" -Verb RunAs -Wait } } else { Write-LogMessage -Message "No product codes found for '$ISACProdName'" } # Uninstall the Pulse Secure Client Write-LogMessage -Message "Uninstalling '$PulseProdName' Client instances if available..." $count=0 if($PulseSecureProductCodes) { foreach ($code in $PulseSecureProductCodes) { $count++ Write-LogMessage -Message "Product code: $code. Uninstalling the Client using the Product Code now..." Start-Process -FilePath $MsiexecExe -ArgumentList " /x $code /qn /L*vx `"$LogDir\OldPulseSecure_$($count)_uninstall.log`"" -Verb RunAs -Wait } } else { Write-LogMessage -Message "No product codes found for '$PulseProdName'" } # Uninstall the ISAC Client using custom uninstaller if available Write-LogMessage -Message "Uninstalling '$ISACProdName' using custom uninstaller if available..." $ISACUninstaller = "$ProgFileDir\$PulseProdName\Pulse\PulseUninstall.exe" If(Test-FileExists -FilePath $ISACUninstaller) { Write-LogMessage -Message "ISAC uninstaller file exists, so invoking it now" Start-Process -FilePath $ISACUninstaller -ArgumentList "/silent=1" -Verb RunAs -Wait } Else { Write-LogMessage -Message "ISAC uninstaller file does not Exists..." } Write-LogMessage -Message "Cleaning Admin Mode Registries..." $RegPath = "HKLM:\SOFTWARE\$PulseProdName" Write-LogMessage -Message "Removing Registry: $RegPath" Remove-Registry -RegistryPath $RegPath If($IsOS64Bit) { $RegPath = "HKLM:\SOFTWARE\Wow6432Node\$PulseProdName" Write-LogMessage -Message "Removing Registry: $RegPath" Remove-Registry -RegistryPath $RegPath $RegPath = "HKLM:\SOFTWARE\Wow6432Node\PulseSecure" Write-LogMessage -Message "Removing Registry: $RegPath" Remove-Registry -RegistryPath $RegPath } # Remove the ISAC / Pulse Secure installer classes registry entries $count = 0 Write-LogMessage -Message "Cleaning ISAC / Pulse Secure installer classes registries..." $RegPath = "HKLM:\SOFTWARE\Classes\Installer\Products" $ProductKeys = Get-ChildItem -Path $RegPath foreach ($key in $ProductKeys) { $ProductName = (Get-ItemProperty -Path $key.PSPath).ProductName if ($ProductName -ieq $ISACProdName) { Write-LogMessage -Message "Found '$ISACProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } if ($ProductName -ieq $PulseProdName) { Write-LogMessage -Message "Found '$PulseProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } } Write-LogMessage -Message "$($count) key(s) removed" # Remove the ISAC / Pulse Secure registry entries $count = 0 Write-LogMessage -Message "Cleaning ISAC / Pulse Secure uninstall registries..." $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $ProductKeys = Get-ChildItem -Path $RegPath foreach ($key in $ProductKeys) { $ProductName = (Get-ItemProperty -Path $key.PSPath).DisplayName if ($ProductName -ieq $ISACProdName) { Write-LogMessage -Message "Found '$ISACProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } if ($ProductName -ieq $PulseProdName) { Write-LogMessage -Message "Found '$PulseProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } if ($key.Name -like "$PulseProdName*") { Write-LogMessage -Message "Found '$PulseProdName*' in registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } } Write-LogMessage -Message "$($count) key(s) removed" # Remove the ISAC / Pulse Secure registry entries $count = 0 Write-LogMessage -Message "Cleaning ISAC / Pulse Secure product registries..." $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products" $ProductKeys = Get-ChildItem -Path $RegPath foreach ($key in $ProductKeys) { $InstallRegPath = $key.PSPath + "\InstallProperties" $DisplayName = (Get-ItemProperty -Path $InstallRegPath).DisplayName if ($DisplayName -ieq $ISACProdName) { Write-LogMessage -Message "Found '$ISACProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } if ($DisplayName -ieq $PulseProdName) { Write-LogMessage -Message "Found '$PulseProdName' from registry: $($key.PSPath), removing it now..." $count++ Remove-Registry -RegistryPath $key.PSPath } } Write-LogMessage -Message "$($count) key(s) removed" # clean residual registries Write-LogMessage -Message "Cleaning ISAC / Pulse Secure component registries..." $components = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\components" $count = 0 foreach ($c in $components) { foreach($p in $c.Property) { $propValue = (Get-ItemProperty "Registry::$($c.Name)" -Name "$($p)")."$($p)" if ($propValue -match $PulseProdName) { Write-LogMessage -Message "Residual registry: $propValue" $count++ Remove-Item Registry::$($c.Name) -Recurse *>> "$CmdLogFile" } } } Write-LogMessage -Message "$($count) key(s) removed" # Remove the ISAC / Pulse Secure folders registry entries $count = 0 Write-LogMessage -Message "Cleaning ISAC / Pulse Secure folders registries..." $RegPath = Get-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\Folders" foreach ($p in $RegPath.Property) { if ($p -match $PulseProdName) { Write-LogMessage -Message "Residual property: $p" $count++ Remove-ItemProperty -Path $RegPath.PSPath -Name $p } } Write-LogMessage -Message "$($count) key(s) removed" # Clean Admin Mode Residualsz Write-LogMessage -Message "Cleaning Admin Mode Residuals..." $DirName = "$ProgFileDir\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$CommonProgFileDir\$PulseProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$CommonProgFileDir\$JuniperProdName" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$Env:PROGRAMDATA\$PulseProdName\Logging" Remove-Directory -DirFullPath $DirName -FlushOnly $False $DirName = "$Env:PROGRAMDATA\Packages" Remove-FileWithWildcard -DirFullPath $DirName -WildCharFileName "PulseSecureReactAppPkg*" $DirName = "$Env:WINDIR\Prefetch" Remove-FileWithWildcard -DirFullPath $DirName -WildCharFileName "Pulse*" $DirName = "$Env:SYSTEMDRIVE\Windows\Downloaded Program Files" Remove-Directory -DirFullPath $DirName -FlushOnly $True $DirName = "$Env:WINDIR\Temp" Remove-Directory -DirFullPath $DirName -FlushOnly $True Write-LogMessage -Message "The '$ISACProdName/$PulseProdName' Deep Clean Process has been completed successfully" # SIG # Begin signature block # MIIuwgYJKoZIhvcNAQcCoIIuszCCLq8CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAsZijYtSN3knqe # rKl3/ww+1aL1j//zdDagi+wQmD8TH6CCE6UwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggdZMIIFQaADAgECAhAKWa4NduqztbG3densaafyMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjMwOTI1MDAwMDAwWhcNMjYwNDI5MjM1OTU5WjBhMQsw # CQYDVQQGEwJVUzENMAsGA1UECBMEVXRhaDEVMBMGA1UEBxMMU291dGggSm9yZGFu # MRUwEwYDVQQKEwxJdmFudGksIEluYy4xFTATBgNVBAMTDEl2YW50aSwgSW5jLjCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPZSo6iSXWipswC6jPqwOwqJ # gIJHXh8Pi7t4aXmaorOlpa+y3Q38EJ3wFrVG4cWdrcpBFT01Je8eASXuh7Ndy6yc # B3sdtQ41B/zET1ePmWa6a9KJV2LYy2BmiMRqgw2HBMh0K3rcG/imzTvXr65MFWJu # +gZfVTmzWkwUtDNCR9PflRuPzklp1w9kFT+fS5TiDGCPGe424ABe6HLYJHDNT6Ry # L4LlZoZjM8YnUVNdPLjHrcjtuxd2wIOSFebn8Ch6xlYChvPyxeIJtBT9fg+NQEmE # X0VjYH2mnv5TrlMBYvi1uJD6HAEjxcIt/6STBgLQ5VGP0NShX9z3uqvZ12E0F+Qg # qJnN2GnuGqDd7sJisCM1+LRDLU+VtssI7k2khbDk+07iV+KjVoOdb7BdWxArWgj/ # W7YI/K5ca241O7v5zKC0QW2V6x2AK5bA0po9iCdHoGhjGns9xE2HRmNIJNRph6J5 # Yl57d5I4gtFfD1fUHQ+K6AF52W8a6ycBoF2//f4OQiT3MHOSfBcb0NBjGeMtEL3p # 0GHn6COV1txl1fLZtAuLV3QF1DOKmmX30HDZ0E6f17JnUMpEUCvICSIL/BkG+y0i # 54OHUU0n7WqcLWKDvAWmq4x/vduWQWOleOJsKpPAnbNmOhDKsH71+7bninOjStYI # YUliqMMKBhVm9CIhTHE/AgMBAAGjggIDMIIB/zAfBgNVHSMEGDAWgBRoN+Drtjv4 # XxGG+/5hewiIZfROQjAdBgNVHQ4EFgQUfVFT5pRwkUJj1o3NPg/oZ0O7sPcwPgYD # VR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD # AzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex # LmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsG # AQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j # b20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0 # MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBADzrxl/w8qgIM1YXfhF1mjQo # ikGn88zJmyEWW6m3dgSZxdhwMHlK69dkBZ6U5v0G4MkT0Jp/RVyCi2ywkr5w5edy # MGl/ULvuoWS7HtuusX0rE7YO79hLWLWP+VcSIzXc8Ev1IxaqIO1jdv7rOdfTtqc8 # SFfhYzkKuomMSFC0lYPoITags2jFFFiiSk/ainmdN9poEhANVeID+YD0Fy7U7xzv # qfi1/+aFYkcpsmp4SqqExBhZeq2StufODXH5f36wU2pLtJ9QaKYT36f60HIoMNFk # F5rLmp18C5zb6rXPFVVN75jm+xD4LqyYBqZwcPIPPmTYhZQW83TKryT9myv/WQ7j # avtlTrpKa+3dYTrooaVooKtTaVu/sjDPc44FfmfiUpU7Y+lxULmMjKeua9BEPgmX # UvLHD6mxu8HLYnd7JU8caidTkhqCQ5vdZuoTC7rEC3m8rnUDFkvPOgM2spfH+hHi # t3qVIvWpzKVbxXm3OY5pJAFAaH1DY4NzuwgefadQ+CtjeIeITQiL887AudiGKVSm # ZPRvXNwF5T3nJtlBEtHzz32DDA7wmFfS38uzvG5FRJcYBEAuuPJ2sQbJkV5QnCPD # FXsZLrUhd45V69/mGMiJYrpxQnsbPFFV8bNX3fG/FttbtZItkG3x3JZlXjGKmtEw # lBLUpq5qo0HeykpmeKoyMYIaczCCGm8CAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUG # A1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQg # RzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAKWa4Nduqz # tbG3densaafyMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKA # AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMINw6DYtyCmr1ewMxmDR4QL # ge+F2/f50T/0QW5lzmo+MA0GCSqGSIb3DQEBAQUABIICADTt0yQkLrLDpakIcRi3 # Jpk0ozw3Zjg8YbGlHoHDWsXgq4IUfyNe2I49eT+vU2VgVamb/RzKxd6IB3WCxdz2 # iyoUID9i8UTllL9E1SNK0oCTjZcKWl5WwykOPSGaZnwsa7PAoMmvM2FTRDUBPhXV # JCjknanGJj0MbQ3zaKTn6FW3hhIl7EN6+B8iq/rIZnYnkr6XiRUIWvh++xh2sppG # IM8SFcQon4Q+6ajJYrNBMPsm66lisOw87zFceiGqHXaHNevBUDiposXFnNXNiOJP # ShijuoLHnCTB2mPNDrkKyIlQ++ix73/oToWxvZRaTFWXWUxvuQhzNBYm+A3v75XP # p4N/PdDKT9aVu9eAaY2BWkPFTJq1G2WI9Mku8zPYepSq+ggxXsDHHz6kXoxfoMGj # +ocSv/P2Wo1HDoPQ8f3j1O2meanLr2/l1DZkMW0BatNAaKvAwWXhPtoAK2qASyma # 9DJdMcYXX2qY/4tc75CLttLZLXQlecHrQLILf0DsSBJf0DJkpiHMv/Fy15E+ahFv # /WiAOS8CyDriNt3MqSGX/V5Qqjvqk6ia0oUaR655sfpk0HdTEKHpTJAnM5SfrvrH # ivGZrinNBqZ7QdI/fnqRFrLnad5vjxNuXDHneRtBPIHFKILP64evWywmndIMM2Lh # +z2qvKm84J0egCE6ornMCu4+oYIXQDCCFzwGCisGAQQBgjcDAwExghcsMIIXKAYJ # KoZIhvcNAQcCoIIXGTCCFxUCAQMxDzANBglghkgBZQMEAgEFADB4BgsqhkiG9w0B # CRABBKBpBGcwZQIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIBRCKw0i # D8L3m0MDcWttAmF69oyzYyTNJIO9wQuE8/vnAhEAoGIADJ/2Tlz6L+kL5KanBxgP # MjAyNDA5MzAwNzM2NDhaoIITCTCCBsIwggSqoAMCAQICEAVEr/OUnQg5pr/bP1/l # YRYwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYg # U0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAwMDBaFw0zNDEwMTMy # MzU5NTlaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEg # MB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS512hDgncL0ijl3o7 # Kpxn3GIVWMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCPHCDqx5o7L5Zm42nn # af5bw9YrIBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpqutg7yl3eGRiF+0Xq # DWFsnf5xXsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5FdZZ1/t0QoRuDwbjm # UpW1R9d4KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQhZHDr1eWg2mOzLukF # 7qr2JPUdvJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+Mu5SNPvUu+vUoCw0 # m+PebmQZBzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH72LEs4VGvtK0VBhTq # YggT02kefGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN97t0K/3k0EH6mXApY # TAA+hWl1x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7Kobse1I4qZgJoXGy # bHGvPrhvltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKTBLRpcCcNT7e1NtHJ # XwikcKPsCvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfKlLfiUKHzOtOKg8tA # ewIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZI # AYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQW # BBSltu8T5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2 # VGltZVN0YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hB # MjU2VGltZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCBGtbeoKm1 # mBe8cI1PijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0mgopxLxjdTrbebNfh # YJwr7e09SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4n13IoC4leCWdKgV6 # hCmYtld5j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp0bkrxMZ7z5z6eOKT # GnaiaXXTUOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFpGbrPFvKDNzRusEEm # 3d5al08zjdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjTredDAHDezJieGYkD # 6tSRN+9NUvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MXkdGqwFXjhr+sJyxB # 0JozSqg21Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8AL2+nCpseQHc2kTm # Ot44OwdeOVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qCNVcoFstp8jKastLY # OrixRoZruhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4QyzfTkx9HmhwwHcK # 1ALgXGC7KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG02wyfFgvZ0dl5Rtz # tpn5aywGRu9BHvDwX+Db2a2QgESvgBBBijCCBq4wggSWoAMCAQICEAc2N7ckVHzY # R6z9KGYqXlswDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoT # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UE # AxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3 # MDMyMjIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2 # IFRpbWVTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AMaGNQZJs8E9cklRVcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjz # aPp985yJC3+dH54PMx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3E # F3+rGSs+QtxnjupRPfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYnc # fGpXevA3eZ9drMvohGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8O # pWNs5KbFHc02DVzV5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROp # VymWJy71h6aPTnYVVSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4i # FNmCKseSv6De4z6ic/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmif # tkaznTqj1QPgv/CiPMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0 # UfM2SU2LINIsVzV5K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9Ne # S3YSUZPJjAw7W4oiqMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCj # WAkBKAAOhFTuzuldyF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTAS # BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57I # bzAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMC # AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0 # MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG # SAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAY # LhBNE88wU86/GPvHUF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQx # Z822EpZvxFBMYh0MCIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf # 7WC2qk+RZp4snuCKrOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDV # inF2ZdrM8HKjI/rAJ4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7 # +6adcq/Ex8HBanHZxhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJ # D5TNOXrd/yVjmScsPT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvk # OHOrpgFPvT87eK1MrfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJG # nXUsHicsJttvFXseGYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimG # sJigK+2VQbc61RWYMbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38A # C+R2AibZ8GV2QqYphwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d # 2zc4GqEr9u3WfPwwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqG # SIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFz # c3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTla # MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT # EHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9v # dCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8 # MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauy # efLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34Lz # B4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+x # embud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhA # kHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1Lyu # GwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2 # PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37A # lLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD7 # 6GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ # ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXA # j6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTAD # AQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF # 66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEE # bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB # BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAI # MAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979X # B72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4k # vFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU # 53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pc # VIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5v # Iy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2 # MIIDcgIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j # LjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBU # aW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCg # gdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0y # NDA5MzAwNzM2NDhaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFGbwKzLCwskPgl3O # qorJxk8ZnM9AMC8GCSqGSIb3DQEJBDEiBCCoNSPQ9S/lkXksGkFHj/GkueV7/D9/ # IftHn1Qqafd/mDA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCDS9uRt7XQizNHUQFdo # QTZvgoraVZquMxavTRqa1Ax4KDANBgkqhkiG9w0BAQEFAASCAgB6XeSX7HubNVyV # 2ZXeu/b1eGayl6G7IOV8C6bbP43qqLM/T1AY9OUsxl6fdcIO90e58QuI2HU+yYs8 # 0NBDPkEm0EREtsJaJAcDhXUQgAzUo3TujT7BX7BvKxpseWJOitTR0yLY9nTb7R1A # 00XJy3VKIHULvm/ZkzzxjmTXY7mDFERMiITFI5xzLiPIxbSV24P5ln31r5pBoZWZ # h+EuAE8ud7gF8xoEAzcbckootTsQfZXyCnPxrEpgbSr6KqlavOszdEZPF39AYFdT # VY0gQl+lpiFphHHBHbWD7eCvQzHUSVMD+MIoj1EPUGZIVm98RlD9UUsssxv2s76V # Tm1HPLrtIJy1bSF6xIH23P442p65J+On54V7+z0XsjSwVmeKbBifXANZqiBhiM4v # psBrFhXgFDSmC5IScwqy0EqKO6Iuc9fkhJNtPWnyml/QFlMKXHV0bZkUeV4iGXAT # TrkCNf9Y7mCWr8j9U522KfLuRHhAXceEW5CCN+XH8uloA2i2w1eKbabUKkIdBSmB # H6SLvUqIQAc0vxmRRxVV3hzm8YG6j9pntPphG3Kgv4QFpesUYPLXj1DrfsIYt22D # zBvokUWu33xcWG/jpWEVdPaipTQU4ags/sRDDjzllzu5hOSyJ445gLZMGKkSlyUJ # FXsKnBAj4ObbqpZ9506exrRG6aJ9Aw== # SIG # End signature block