mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Adding fix to not use COM installer object (#9661)
This relates to #9576
This commit is contained in:
parent
aeeae1706e
commit
9f6c803b4f
2 changed files with 238 additions and 148 deletions
|
|
@ -0,0 +1 @@
|
|||
* Orbit now installs propery on Windows Server 2012 and 2016 environments with legacy Orbit or Osquery previously installed
|
||||
|
|
@ -205,7 +205,17 @@ var windowsPSInstallerUtils = template.Must(template.New("").Option("missingkey=
|
|||
[switch] $help = $false
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
#ErrorActionPreference valid values are as follows:
|
||||
# Break: Enter the debugger when an error occurs or when an exception is raised.
|
||||
# Continue: (Default) Displays the error message and continues executing.
|
||||
# Ignore: Suppresses the error message and continues to execute the command. The Ignore value is intended for per-command use, not for use as saved preference. Ignore isn't a valid value for the $ErrorActionPreference variable.
|
||||
# Inquire: Displays the error message and asks you whether you want to continue.
|
||||
# SilentlyContinue: No effect. The error message isn't displayed and execution continues without interruption.
|
||||
# Stop: Displays the error message and stops executing. In addition to the error generated, the Stop value generates an ActionPreferenceStopException object to the error stream.
|
||||
# Suspend: Automatically suspends a workflow job to allow for further investigation. After investigation, the workflow can be resumed. The Suspend value is intended for per-command use, not for use as saved preference. Suspend isn't a valid value for the $ErrorActionPreference variable.
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
|
||||
$code = @"
|
||||
using Microsoft.Win32;
|
||||
|
|
@ -410,214 +420,293 @@ function Do-Help {
|
|||
Write-Host " -uninstallOsquery Uninstall Osquery"
|
||||
Write-Host " -uninstallOrbit Uninstall Orbit"
|
||||
Write-Host " -stopOrbit Stop Orbit"
|
||||
Write-Host ""
|
||||
Write-Host " -help Shows this help screen"
|
||||
|
||||
Exit 1
|
||||
}
|
||||
|
||||
# borrowed from Jeffrey Snover http://blogs.msdn.com/powershell/archive/2006/12/07/resolve-error.aspx
|
||||
function Resolve-Error-Detailed($ErrorRecord = $Error[0]) {
|
||||
$error_message = "========== ErrorRecord:{0}ErrorRecord.InvocationInfo:{1}Exception:{2}"
|
||||
$formatted_errorRecord = $ErrorRecord | format-list * -force | out-string
|
||||
$formatted_invocationInfo = $ErrorRecord.InvocationInfo | format-list * -force | out-string
|
||||
$formatted_exception = ""
|
||||
$Exception = $ErrorRecord.Exception
|
||||
for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException)) {
|
||||
$formatted_exception += ("$i" * 70) + "-----"
|
||||
$formatted_exception += $Exception | format-list * -force | out-string
|
||||
$formatted_exception += "-----"
|
||||
}
|
||||
|
||||
return $error_message -f $formatted_errorRecord, $formatted_invocationInfo, $formatted_exception
|
||||
}
|
||||
|
||||
#Stops Osquery service and related processes
|
||||
function Stop-Osquery {
|
||||
|
||||
$kServiceName = "osqueryd"
|
||||
|
||||
# Stop Service
|
||||
Stop-Service -Name $kServiceName
|
||||
Start-Sleep -Milliseconds 1000
|
||||
Stop-Service -Name $kServiceName -ErrorAction "Continue"
|
||||
Start-Sleep -Milliseconds 1000
|
||||
|
||||
# Ensure that no process left running
|
||||
Get-Process -Name $kServiceName | Stop-Process -Force
|
||||
Get-Process -Name $kServiceName -ErrorAction "SilentlyContinue" | Stop-Process -Force
|
||||
}
|
||||
|
||||
#Stops Orbit service and related processes
|
||||
function Stop-Orbit {
|
||||
|
||||
# Stop Service
|
||||
Stop-Service -Name "Fleet osquery"
|
||||
Stop-Service -Name "Fleet osquery" -ErrorAction "Continue"
|
||||
Start-Sleep -Milliseconds 1000
|
||||
|
||||
# Ensure that no process left running
|
||||
Get-Process -Name "orbit" | Stop-Process -Force
|
||||
Get-Process -Name "osqueryd" | Stop-Process -Force
|
||||
Get-Process -Name "fleet-desktop" | Stop-Process -Force
|
||||
Get-Process -Name "orbit" -ErrorAction "SilentlyContinue" | Stop-Process -Force
|
||||
Get-Process -Name "osqueryd" -ErrorAction "SilentlyContinue" | Stop-Process -Force
|
||||
Get-Process -Name "fleet-desktop" -ErrorAction "SilentlyContinue" | Stop-Process -Force
|
||||
Start-Sleep -Milliseconds 1000
|
||||
}
|
||||
|
||||
|
||||
#Revove Orbit footprint from registry and disk
|
||||
function Force-Remove-Orbit {
|
||||
|
||||
#Stoping Orbit
|
||||
Stop-Orbit
|
||||
try {
|
||||
|
||||
#Remove Service
|
||||
$service = Get-WmiObject -Class Win32_Service -Filter "Name='Fleet osquery'"
|
||||
$service.delete()
|
||||
#Stoping Orbit
|
||||
Stop-Orbit
|
||||
|
||||
#Removing Program files entries
|
||||
$targetPath = $Env:Programfiles + "\\Orbit"
|
||||
Remove-Item -LiteralPath $targetPath -Force -Recurse
|
||||
|
||||
#Remove HKLM registry entries
|
||||
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse | Where-Object {($_.ValueCount -gt 0)} | ForEach-Object {
|
||||
|
||||
# Filter for osquery entries
|
||||
$properties = Get-ItemProperty $_.PSPath | Where-Object {($_.DisplayName -eq "Fleet osquery")}
|
||||
if ($properties) {
|
||||
|
||||
#Remove Registry Entries
|
||||
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $_.PSChildName
|
||||
Get-Item $regKey | Remove-Item -Force
|
||||
|
||||
return
|
||||
#Remove Service
|
||||
$service = Get-WmiObject -Class Win32_Service -Filter "Name='Fleet osquery'"
|
||||
if ($service) {
|
||||
$service.delete() | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
#Removing Program files entries
|
||||
$targetPath = $Env:Programfiles + "\\Orbit"
|
||||
Remove-Item -LiteralPath $targetPath -Force -Recurse -ErrorAction "Continue"
|
||||
|
||||
#Remove HKLM registry entries
|
||||
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse -ErrorAction "SilentlyContinue" | Where-Object {($_.ValueCount -gt 0)} | ForEach-Object {
|
||||
|
||||
# Filter for osquery entries
|
||||
$properties = Get-ItemProperty $_.PSPath -ErrorAction "SilentlyContinue" | Where-Object {($_.DisplayName -eq "Fleet osquery")}
|
||||
if ($properties) {
|
||||
|
||||
#Remove Registry Entries
|
||||
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $_.PSChildName
|
||||
|
||||
Get-Item $regKey -ErrorAction "SilentlyContinue" | Remove-Item -Force -ErrorAction "SilentlyContinue"
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "There was a problem running Force-Remove-Orbit" -ForegroundColor Red
|
||||
Write-Host "====================================="
|
||||
Write-Host "$(Resolve-Error-Detailed)"
|
||||
Write-Host "====================================="
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
|
||||
#Revove Osquery footprint from registry and disk
|
||||
function Force-Remove-Osquery {
|
||||
|
||||
#Stoping Osquery
|
||||
Stop-Osquery
|
||||
try {
|
||||
|
||||
#Remove Service
|
||||
$service = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'"
|
||||
$service.delete() | Out-Null
|
||||
#Stoping Osquery
|
||||
Stop-Osquery
|
||||
|
||||
#Remove HKLM registry entries and disk footprint
|
||||
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse | Where-Object {($_.ValueCount -gt 0)} | ForEach-Object {
|
||||
|
||||
# Filter for osquery entries
|
||||
$properties = Get-ItemProperty $_.PSPath | Where-Object {($_.DisplayName -eq "osquery")}
|
||||
if ($properties) {
|
||||
|
||||
#Remove files from osquery location
|
||||
if ($properties.InstallLocation){
|
||||
Remove-Item -LiteralPath $properties.InstallLocation -Force -Recurse
|
||||
}
|
||||
|
||||
#Remove Registry Entries
|
||||
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $_.PSChildName
|
||||
Get-Item $regKey | Remove-Item -Force
|
||||
|
||||
return
|
||||
#Remove Service
|
||||
$service = Get-WmiObject -Class Win32_Service -Filter "Name='osqueryd'"
|
||||
if ($service) {
|
||||
$service.delete() | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
#Remove user entries if present
|
||||
[RegistryUtils]::RemoveOsqueryInstallationFromUserHives()
|
||||
#Remove HKLM registry entries and disk footprint
|
||||
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse -ErrorAction "SilentlyContinue" | Where-Object {($_.ValueCount -gt 0)} | ForEach-Object {
|
||||
|
||||
# Filter for osquery entries
|
||||
$properties = Get-ItemProperty $_.PSPath -ErrorAction "SilentlyContinue" | Where-Object {($_.DisplayName -eq "osquery")}
|
||||
if ($properties) {
|
||||
|
||||
#Remove files from osquery location
|
||||
if ($properties.InstallLocation){
|
||||
Remove-Item -LiteralPath $properties.InstallLocation -Force -Recurse -ErrorAction "SilentlyContinue"
|
||||
}
|
||||
|
||||
#Remove Registry Entries
|
||||
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" + $_.PSChildName
|
||||
Get-Item $regKey -ErrorAction "SilentlyContinue" | Remove-Item -Force -ErrorAction "SilentlyContinue"
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
#Remove user entries if present
|
||||
[RegistryUtils]::RemoveOsqueryInstallationFromUserHives()
|
||||
}
|
||||
catch {
|
||||
Write-Host "There was a problem running Force-Remove-Osquery" -ForegroundColor Red
|
||||
Write-Host "====================================="
|
||||
Write-Host "$(Resolve-Error-Detailed)"
|
||||
Write-Host "====================================="
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
function Graceful-Product-Uninstall($productName) {
|
||||
|
||||
if (!$productName) {
|
||||
Write-Host "Product name should be provided" -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
try {
|
||||
|
||||
# Grabbing the location of msiexec.exe
|
||||
$targetBinPath = Resolve-Path "$env:windir\system32\msiexec.exe"
|
||||
if (!(Test-Path $targetBinPath)) {
|
||||
Write-Host "msiexec.exe cannot be located." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
if (!$productName) {
|
||||
Write-Host "Product name should be provided" -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Creating a COM instance of the WindowsInstaller.Installer COM object
|
||||
$Installer = New-Object -ComObject WindowsInstaller.Installer
|
||||
if (!$Installer) {
|
||||
Write-Host "There was a problem retrieving the installed packages." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Enumerating the installed packages
|
||||
$ProductEnumFlag = 7 #installed packaged enumeration flag
|
||||
$InstallerProducts = $Installer.ProductsEx("", "", $ProductEnumFlag);
|
||||
if (!$InstallerProducts) {
|
||||
Write-Host "Installed packages cannot be retrieved." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Iterating over the installed packages results and checking for osquery package
|
||||
ForEach ($Product in $InstallerProducts) {
|
||||
|
||||
$ProductCode = $null
|
||||
$VersionString = $null
|
||||
$ProductPath = $null
|
||||
|
||||
try {
|
||||
$ProductCode = $Product.ProductCode()
|
||||
$VersionString = $Product.InstallProperty("VersionString")
|
||||
$ProductPath = $Product.InstallProperty("ProductName")
|
||||
}
|
||||
catch { }
|
||||
|
||||
if ($ProductPath -like $productName) {
|
||||
Write-Host "Graceful uninstall of $ProductPath version $VersionString." -foregroundcolor Cyan
|
||||
$InstallProcess = Start-Process $targetBinPath -ArgumentList "/quiet /x $ProductCode" -PassThru -Verb RunAs -Wait
|
||||
if ($InstallProcess.ExitCode -eq 0) {
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "There was an error uninstalling osquery. Error code was: $($InstallProcess.ExitCode)." -foregroundcolor Yellow
|
||||
return $false
|
||||
if ($productName -eq "Fleet osquery") {
|
||||
Stop-Orbit
|
||||
} elseif ($productName -eq "osquery") {
|
||||
Stop-Osquery
|
||||
}
|
||||
|
||||
# Grabbing the location of msiexec.exe
|
||||
$targetBinPath = Resolve-Path "$env:windir\system32\msiexec.exe"
|
||||
if (!(Test-Path $targetBinPath)) {
|
||||
Write-Host "msiexec.exe cannot be located." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Creating a COM instance of the WindowsInstaller.Installer COM object
|
||||
$Installer = New-Object -ComObject WindowsInstaller.Installer
|
||||
if (!$Installer) {
|
||||
Write-Host "There was a problem retrieving the installed packages." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Enumerating the installed packages
|
||||
$ProductEnumFlag = 7 #installed packaged enumeration flag
|
||||
$InstallerProducts = $Installer.ProductsEx("", "", $ProductEnumFlag);
|
||||
if (!$InstallerProducts) {
|
||||
Write-Host "Installed packages cannot be retrieved." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
|
||||
# Iterating over the installed packages results and checking for osquery package
|
||||
ForEach ($Product in $InstallerProducts) {
|
||||
|
||||
$ProductCode = $null
|
||||
$VersionString = $null
|
||||
$ProductPath = $null
|
||||
|
||||
$ProductCode = $Product.ProductCode()
|
||||
$VersionString = $Product.InstallProperty("VersionString")
|
||||
$ProductPath = $Product.InstallProperty("ProductName")
|
||||
|
||||
if ($ProductPath -like $productName) {
|
||||
Write-Host "Graceful uninstall of $ProductPath version $VersionString." -foregroundcolor Cyan
|
||||
$InstallProcess = Start-Process $targetBinPath -ArgumentList "/quiet /x $ProductCode" -PassThru -Verb RunAs -Wait
|
||||
if ($InstallProcess.ExitCode -eq 0) {
|
||||
return $true
|
||||
} else {
|
||||
Write-Host "There was an error uninstalling osquery. Error code was: $($InstallProcess.ExitCode)." -foregroundcolor Yellow
|
||||
return $false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "There was a problem running Graceful-Product-Uninstall" -ForegroundColor Red
|
||||
Write-Host "====================================="
|
||||
Write-Host "$(Resolve-Error-Detailed)"
|
||||
Write-Host "====================================="
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
|
||||
function Main {
|
||||
# Is Administrator check
|
||||
if (-not (Test-Administrator)) {
|
||||
Write-Host "Please run this script with Admin privileges!" -foregroundcolor Red
|
||||
Exit -1
|
||||
}
|
||||
|
||||
# Help commands
|
||||
if ($help) {
|
||||
Do-Help
|
||||
Exit -1
|
||||
}
|
||||
try {
|
||||
# Is Administrator check
|
||||
if (-not (Test-Administrator)) {
|
||||
Write-Host "Please run this script with Admin privileges!" -foregroundcolor Red
|
||||
Exit -1
|
||||
}
|
||||
|
||||
# Help commands
|
||||
if ($help) {
|
||||
Do-Help
|
||||
Exit -1
|
||||
}
|
||||
|
||||
if ($uninstallOsquery) {
|
||||
Write-Host "About to uninstall Osquery." -foregroundcolor Yellow
|
||||
|
||||
if ($uninstallOsquery) {
|
||||
Write-Host "About to uninstall Osquery." -foregroundcolor Yellow
|
||||
#if (Graceful-Product-Uninstall("osquery")) {
|
||||
if ($false) {
|
||||
Force-Remove-Osquery #best effort action to ensure cleanup after graceful uninstall
|
||||
Write-Host "Osquery was gracefully uninstalled." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
|
||||
} else {
|
||||
if (Force-Remove-Osquery) {
|
||||
Write-Host "Osquery was uninstalled." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
} else {
|
||||
Write-Host "There was a problem uninstalling Osquery" -foregroundcolor Cyan
|
||||
Exit -1
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($uninstallOrbit) {
|
||||
Write-Host "About to uninstall Orbit." -foregroundcolor Yellow
|
||||
|
||||
#if (Graceful-Product-Uninstall("Fleet osquery")) {
|
||||
if ($false) {
|
||||
Force-Remove-Orbit #best effort action to ensure cleanup after graceful uninstall
|
||||
Write-Host "Orbit was gracefully uninstalled." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
|
||||
} else {
|
||||
if (Force-Remove-Orbit) {
|
||||
Write-Host "Orbit was uninstalled." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
} else {
|
||||
Write-Host "There was a problem uninstalling Orbit" -foregroundcolor Cyan
|
||||
Exit -1
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($stopOrbit) {
|
||||
Write-Host "About to stop Orbit and remove it from system." -foregroundcolor Yellow
|
||||
|
||||
Stop-Orbit
|
||||
|
||||
Write-Host "Orbit was stopped." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
|
||||
Stop-Osquery
|
||||
|
||||
if (Graceful-Product-Uninstall("osquery")) {
|
||||
Write-Host "Osquery was gracefully uninstalled." -foregroundcolor Cyan
|
||||
} else {
|
||||
Force-Remove-Osquery
|
||||
Write-Host "Osquery was uninstalled." -foregroundcolor Cyan
|
||||
Write-Host "Invalid option selected: please see -help for usage details." -foregroundcolor Red
|
||||
Do-Help
|
||||
Exit -1
|
||||
}
|
||||
Exit 0
|
||||
|
||||
} elseif ($uninstallOrbit) {
|
||||
Write-Host "About to uninstall Orbit." -foregroundcolor Yellow
|
||||
|
||||
Stop-Orbit
|
||||
|
||||
if (Graceful-Product-Uninstall("Fleet osquery")) {
|
||||
Force-Remove-Orbit
|
||||
Write-Host "Orbit was gracefully uninstalled." -foregroundcolor Cyan
|
||||
} else {
|
||||
Force-Remove-Orbit
|
||||
Write-Host "Orbit was uninstalled." -foregroundcolor Cyan
|
||||
}
|
||||
Exit 0
|
||||
} elseif ($stopOrbit) {
|
||||
Write-Host "About to stop Orbit and remove it from system." -foregroundcolor Yellow
|
||||
|
||||
Stop-Orbit
|
||||
|
||||
Write-Host "Orbit was stopped." -foregroundcolor Cyan
|
||||
Exit 0
|
||||
} else {
|
||||
Write-Host "Invalid option selected: please see -help for usage details." -foregroundcolor Red
|
||||
Do-Help
|
||||
} catch {
|
||||
Write-Host "There was a problem running installer entry point logic" -ForegroundColor Red
|
||||
Write-Host "====================================="
|
||||
Write-Host "$(Resolve-Error-Detailed)"
|
||||
Write-Host "====================================="
|
||||
Exit -1
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue