108 lines
5.6 KiB
PowerShell
108 lines
5.6 KiB
PowerShell
|
function Uninstall-AlkamiService {
|
|||
|
<#
|
|||
|
.SYNOPSIS
|
|||
|
Uninstalls an Alkami Windows Service (not a legacy microservice)
|
|||
|
|
|||
|
.DESCRIPTION
|
|||
|
Uninstalls an Alkami Windows Service (not a legacy microservice)
|
|||
|
Legacy Microservices are considered to be Microservices that implement Alkami.Services.Subscriptions.ParticipatingService.DistributedServiceBase or derivatives.
|
|||
|
This installer does not remove k8s or Lambdas or anything that is not a Windows Service.
|
|||
|
This installer is intended to be used in conjunction with new practices from the Vanguard team
|
|||
|
|
|||
|
.PARAMETER ServicePath
|
|||
|
[string] The path to the service folder or service file. If to a folder, assumes that the file matches the path name.
|
|||
|
Ex: C:\ProgramData\chocolatey\lib\Alkami.Services.Subscriptions.Host as a param would then find the file that matches Alkami.Services.Subscriptions.Host.exe under this path
|
|||
|
|
|||
|
.EXAMPLE
|
|||
|
Uninstall-AlkamiService C:\ProgramData\chocolatey\lib\Alkami.Services.Subscriptions.Host
|
|||
|
#>
|
|||
|
[CmdletBinding()]
|
|||
|
Param(
|
|||
|
[Parameter(Mandatory = $true, Position = 0)]
|
|||
|
[Alias("Path")]
|
|||
|
[string]$ServicePath
|
|||
|
)
|
|||
|
|
|||
|
$logLead = (Get-LogLeadName)
|
|||
|
|
|||
|
$ServicePath = (Resolve-Path $ServicePath)
|
|||
|
|
|||
|
if (!(Test-Path $ServicePath)) {
|
|||
|
Write-Warning "$logLead : Path passed in does not represent a valid path: [$ServicePath]. Can not uninstall something which does not exist."
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
$parentPath = Split-Path -Path $ServicePath -Parent
|
|||
|
|
|||
|
$serviceName = ""
|
|||
|
if (-not (Get-Item -Path $servicePath).PSIsContainer) {
|
|||
|
$serviceName = Split-Path -Path $ServicePath -Leaf
|
|||
|
if ($serviceName.Substring($serviceName.Length - 4) -eq '.exe') {
|
|||
|
$serviceName = $serviceName.Substring(0, $serviceName.Length - 4)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
$serviceCandidates = (Get-ServiceInfoByCIMFragment -Fragment $ServicePath -ForceExact)
|
|||
|
|
|||
|
# If we didn't find anything by the AssemblyInfo, let's double check the parent path
|
|||
|
if (Test-IsCollectionNullOrEmpty $serviceCandidates) {
|
|||
|
if (Test-StringIsNullOrWhiteSpace -Value $serviceName) {
|
|||
|
$serviceCandidates = @(Get-ServiceInfoByCIMFragment -Fragment $parentPath)
|
|||
|
if ($serviceCandidates.Count -gt 3) {
|
|||
|
# 3 chosen because you could end up with 2 services in one folder, and that's not-great, but at 3 we clearly have a bad search
|
|||
|
# This comment is for Cole to know that we just flat out couldn't get there from here
|
|||
|
Write-Host "$logLead : Bad path given for trying to determine the root of the service to remove it"
|
|||
|
}
|
|||
|
if (!(Test-IsCollectionNullOrEmpty $serviceCandidates)) {
|
|||
|
# This comment is for Cole to know that there were only 2, or more than 2, based on the prior output
|
|||
|
# We will write out more details at the end
|
|||
|
Write-Warning "$logLead : Could not find services under [$ServicePath] but found some under [$parentPath]"
|
|||
|
}
|
|||
|
} else {
|
|||
|
$serviceCandidates = @(Get-ServiceInfoByCIMFragment -Fragment $serviceName -ForceExact)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (Test-IsCollectionNullOrEmpty $serviceCandidates) {
|
|||
|
Write-Host "$logLead : No services found registered under [$ServicePath] or [$parentPath] or with [$serviceName]"
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
$exactPathMatch = @($serviceCandidates.Where({
|
|||
|
# Manifest based installers allow for three paths
|
|||
|
(Join-Path -Path $_.ParentFolder -ChildPath '\') -eq (Join-Path -Path $ServicePath -ChildPath 'lib\') -or
|
|||
|
(Join-Path -Path $_.ParentFolder -ChildPath '\') -eq (Join-Path -Path $ServicePath -ChildPath 'app\') -or
|
|||
|
(Join-Path -Path $_.ParentFolder -ChildPath '\') -eq (Join-Path -Path $ServicePath -ChildPath 'tools\') -or
|
|||
|
(Join-Path -Path $_.ParentFolder -ChildPath '\') -eq (Join-Path -Path $ServicePath -ChildPath '\')
|
|||
|
}))
|
|||
|
|
|||
|
if ($exactPathMatch.Count -eq 1) {
|
|||
|
$serviceCandidateName = $exactPathMatch.Name
|
|||
|
$serviceCandidatePath = $exactPathMatch.Path
|
|||
|
Write-Host "$logLead : Uninstalling existing service [$serviceCandidateName] at [$serviceCandidatePath] for [$ServicePath]"
|
|||
|
|
|||
|
# Ensure it isn't running first
|
|||
|
Stop-AlkamiService $serviceCandidateName
|
|||
|
|
|||
|
Write-Verbose "$logLead : Removing [$serviceCandidateName] via sc.exe"
|
|||
|
Invoke-SCExe @("delete", $serviceCandidateName)
|
|||
|
|
|||
|
# Give Windows time to breathe. This might could be shorter, who knows. 150 is a magic number from thin air.
|
|||
|
Start-Sleep -Milliseconds 150
|
|||
|
|
|||
|
if ($null -ne (Get-Service -Name $serviceCandidateName -ErrorAction Ignore)) {
|
|||
|
# How did this happen? sc.exe is a hot-knife.
|
|||
|
throw "$logLead : Tried to uninstall [$serviceCandidateName] from [$serviceCandidatePath] but it seems to still be present"
|
|||
|
}
|
|||
|
} else {
|
|||
|
# If it couldn't do the thing, Cole needs to investigate, because the assumptions are bad
|
|||
|
foreach($candidate in $serviceCandidates) {
|
|||
|
Write-Warning "$logLead : TOO MANY SERVICES FOUND FOR [$ServicePath] : Found service [$($candidate.Name)] at [$($candidate.Path)]"
|
|||
|
}
|
|||
|
Write-Warning "$logLead : ---------------------"
|
|||
|
Write-Warning "$logLead : You probably have an inconsistent package state. Please reinstall this service, then re-uninstall it."
|
|||
|
Write-Warning "$logLead : It is worth slacking/paging out to Cole on this to see why we ended up in this weird state, because this was unexpected"
|
|||
|
Write-Warning "$logLead : ---------------------"
|
|||
|
throw "$logLead : More than 1 service candidates found in this location. Are you sure you wanna do this? Did you mean to specify a deeper path?"
|
|||
|
}
|
|||
|
}
|