function Invoke-DeleteLegacyMicroserviceFromServiceCandidate { <# .SYNOPSIS Private method to system unregister a legacy service. Called from multiple places. .DESCRIPTION Unregisters the Windows Service at a core location .PARAMETER ServiceCandidate [PSObject] A service candidate (needs properties Path and Name) .EXAMPLE # Get a list of candidates for a fragment $ServiceCandidates = (Get-ServiceInfoByCIMFragment -Fragment $fragment) foreach($ServiceCandidate in $ServiceCandidates) { Invoke-DeleteLegacyMicroserviceFromServiceCandidate $ServiceCandidate } #> param ( [PSObject]$ServiceCandidate ) $logLead = (Get-LogLeadName) $ServiceCandidatePath = $ServiceCandidate.ExePath $ServiceCandidateName = $ServiceCandidate.Name Write-Host "$logLead : Trying to remove service [$($ServiceCandidateName)] from [$ServiceCandidatePath]" Stop-AlkamiService -ServiceName $ServiceCandidateName if (Test-Path $serviceCandidatePath) { # Since we are getting the modified ExePath from the CimFragment in our own code, we may need # to switch the path out if those params from TopShelf are problematic? idk Invoke-TopshelfPath $ServiceCandidatePath @("uninstall") } else { Write-Host "$logLead : Chocolatey path not found at [$serviceCandidatePath]. Will attempt to delete with sc.exe" } if ($null -ne (Get-Service -Name $ServiceCandidateName -ErrorAction Ignore)) { # the topshelf installer did not uninstall, let's fall back to sc.exe Write-Verbose "$logLead : Removing [$ServiceCandidateName] via sc.exe" Invoke-SCExe @("delete",$ServiceCandidateName) # Do the least thing possible if ($LASTEXITCODE -eq 1072) { Start-Sleep -Seconds 30 } # 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" } } }