How to uninstall dell support assist with powershell? - powershell

So there was an article that came out about support assist being vulnerable, bla bla.
Upper management has deemed support assist to be unsafe and has ordered it removed from every machine.....
no I cannot/will not try to convince them otherwise, this is going to happen one way or another
Trying to get this done has been a nightmare for the past 8 hours while I try unsuccessful script after the next only to have this damned program NOT DIE
Here is what I have so far
MsiExec.exe /X "{0309AC01-330F-494C-B27D-58E297E4674F}" /quiet
MsiExec.exe /X "{F1D17890-F41B-4BFA-8893-B2C8A248BE0D}" /quiet
$CurrentSAPkg = Get-WMIObject -Class Win32_Product | Where-Object { $_.Name -like "Dell*" }
$CurrentSAPkg.Uninstall()
& "C:\Program Files\Dell\SupportAssist\uninstaller.exe" /arp /S
The get-WMIObject part works, and the uninstaller.exe /arp /S works
however those only work for the older versions, newer versions require something more like the top two commands, but there is a problem
the /quiet flag makes it not work. if I omit the quiet flag I get a popup, "Are you sure" yes, it uninstalls, with the quiet flag, nothing happens, the program stays
I use the folowing to get the uninstall paths
$regQuery32 = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | Where {$_.GetValue("DisplayName") -match "Dell*"}
I really hate support assist now and I want it to die and I am at my wits end.

So I am having the exact opposite issue. I was able to get the newer versions to remove, but anything that returned "C:\Program Files\Dell\SupportAssist\uninstaller.exe /arp" as the UninstallString is failing in my automation as I can't get the prompt to not display (I have around 700 agents to remove this crap from, some with multiple versions, so I feel your pain).
For the newer versions, I used:
$SAVer = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall |
Get-ItemProperty |
Where-Object {$_.DisplayName -match "SupportAssist" } |
Where-Object {$_.DisplayVersion -notlike "3.2*"} |
Select-Object -Property DisplayVersion, UninstallString, PSChildName
ForEach ($ver in $SAVer) {
If ($ver.UninstallString) {
$uninst = $ver.UninstallString
& cmd /c $uninst /quiet /norestart
}
}
I am going to look into the method you are showing for the older version (2.0 and earlier) to see if this resolves my issue. Hopefully my code snippet will help with yours. Cheers.

Ran into a similar problem. I had a bunch of computers all with different versions of Support Assist. I compiled this from a few different sources. So far I have had really good success. I am using PDQ deploy. I am not the most PowerShell proficient but perhaps this will help.
"C:\ProgramData\Package Cache\{ec40a028-983b-4213-af2c-77ed6f6fe1d5}\DellUpdateSupportAssistPlugin.exe" /uninstall /quiet
MsiExec.exe /qn /norestart /X{E98E94E2-12D1-48E5-AC69-2C312F466136}
MsiExec.exe /qn /norestart /X{806422F1-FC4E-4D7C-8855-05748AEFC031}
MsiExec.exe /X{0309AC01-330F-494C-B27D-58E297E4674F} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{122666A9-2995-4E47-A75E-6423A827B7AF} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{18EF001B-B005-46CB-917B-112BA69ED85E} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{1AE53ECE-2255-4191-998B-07741E5EFCDA} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{33E712C1-2183-421C-9BC8-C902DB9C596C} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{45FD01F4-B11B-4A58-B465-1D600B5CDF64} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{4CB4741A-20C1-454E-8276-993D06A76D67} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{50EF2C72-95EC-4206-AAC3-9E84004A6140} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{5A18ABE3-52D1-4CA5-9169-25EC7E789582} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{8D7B279C-A661-465C-9658-F62FBD6A6B91} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{9074E264-F615-4DDE-969E-1FDBCFEC3FB5} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{90881C8E-6C4F-4662-9923-85AFCA058C44} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{9DD6B149-CEBC-4910-B11A-242393EDF6D3} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{D793D5B1-A985-4443-90F4-E55A13CFF117} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{E98E94E2-12D1-48E5-AC69-2C312F466136} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{806422F1-FC4E-4D7C-8855-05748AEFC031} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{27130E51-9555-408B-8134-7BFF54EDE27B} /qn REBOOT=REALLYSUPRESS
MsiExec.exe /X{3ED468C2-2235-4747-90AD-A7A34F0FE70A} /qn REBOOT=REALLYSUPRESS
taskkill /im SupportAssistAgent.exe /f /t
net stop SupportAssistAgent
sc delete SupportAssistAgent
rd "C:\Program Files\Dell\SupportAssist"/s /q
rd "C:\Program Files\Dell\SupportAssistAgent" /s /q
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\PC-Doctor for Windows" /f
del "C:\Users\Public\Desktop\SupportAssist.lnk" /f /q
Sources:
https://community.spiceworks.com/topic/2229972-using-pdq-deploy-to-uninstall-dell-supportassist
https://www.dell.com/community/SupportAssist-for-PCs/Silently-Update-SupportAssist-in-background/td-p/7294483

Have you tried something like:
get-package *dell* | uninstall-package -whatif

I know this is an old post but I was just looking for a script to do this and ended up writing my own Powershell script.
This is what I came up with..
Uninstalls "Dell SupportAssist" and "Dell SupportAssist OS Recovery Plugin for Dell Update"
Hope this helps someone else too.. The code probably could be cleaned up or simplified a bit but it worked for me.
$supportassist = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall| Get-ItemProperty | Where-Object {$_.DisplayName -ceq "Dell SupportAssist" } | Select-Object -ExpandProperty UninstallString
if ($supportassist)
{
$arguments = $supportassist.substring(12) + " /qn REBOOT=REALLYSUPRESS"
echo "Uninstalling Dell SupportAsist"
echo "msiexec.exe " $arguments
(Start-Process "msiexec.exe" -ArgumentList $arguments -NoNewWindow -Wait -PassThru).ExitCode
}
$supportassist2 = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall| Get-ItemProperty | Where-Object {$_.DisplayName -ceq "Dell SupportAssist OS Recovery Plugin for Dell Update" } | Select-Object -ExpandProperty UninstallString
if ($supportassist2)
{
$arguments2 = $supportassist2.substring(12) + " /qn"
echo "Uninstalling Dell SupportAssist OS Recovery Plugin for Dell Update"
echo "msiexec.exe " $arguments2
(Start-Process "msiexec.exe" -ArgumentList $arguments2 -NoNewWindow -Wait -PassThru).ExitCode
}

Here is a Powershell script that I currently use to remove it
Param (
[Parameter(Mandatory=$false)]
[switch]$Force = $false,
[Parameter(Mandatory=$false)]
[String] $SoftwareVersion = "3.11"
)
$Software = "Dell SupportAssist"
$ScriptName = $myinvocation.MyCommand
Function Remove-CachedScripts {
$Agent = "C:\Program Files\N-able Technologies\Windows Agent"
if (test-path "C:\Program Files (x86)\N-able Technologies\Windows Agent") {
$Agent = "C:\Program Files (x86)\N-able Technologies\Windows Agent"
}
remove-item "$Agent\cache\$scriptname" -force -erroraction SilentlyContinue
remove-item "$Agent\Temp\Script\$scriptname" -force -ErrorAction SilentlyContinue
}
Function Get-InstalledApp($Target) {
$Apps = #()
$Apps += Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
Get-ItemProperty | Where-Object {$_.DisplayName -eq "$Target" } | Select-Object -Property DisplayName, DisplayVersion, UninstallString
If ($(Get-WmiObject Win32_OperatingSystem).OSArchitecture -match "64") {
$Apps += Get-ChildItem -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall |
Get-ItemProperty | Where-Object {$_.DisplayName -eq "$Target" } | Select-Object -Property DisplayName, DisplayVersion, UninstallString
}
$Apps
}
Function Uninstall-Software {
if ($SoftwareUninstall -ne $null) {
if (($($SoftwareUninstall.DisplayVersion) -ge "$SoftwareVersion") -and ($force -eq $false)) {
exit 0
}
if ($($SoftwareUninstall.DisplayVersion) -lt "$SoftwareVersion") {
}
ForEach ($item in $SoftwareUninstall) {
if (($item.displayversion -le "$softwareversion") -or ($force -eq $true)) {
If ($item.UninstallString) {
$uninst = $item.UninstallString.Split('/X')[0]
$guid = $item.UninstallString.Split('/X')[2]
$argument = "/x $guid /qn /norestart"
Start-Process $uninst -ArgumentList "$argument" -wait -passthru -NoNewWindow
$Timeout = 0
$MaxWait = 10
While (($CheckSoftware -ne $null) -and ($Timeout -lt $MaxWait)) {
Start-Sleep -Seconds 30
$Timeout++
$CheckSoftware = Get-InstalledApp("$Software")
}
If ($CheckSoftware -eq $null)
{
Exit 0
}
}
}
}
}
}
$SoftwareUninstall = . Get-InstalledApp($software)
. Uninstall-Software
Remove-CachedScripts

Related

Silently Uninstall NVIDIA Display Driver using Uninstall String

I can uninstall NVIDIA Graphics Driver from PowerShell but I am unable to figure out how to do it silently. The normal code looks like this:
#Get Uninstall String from Registry
$us = Get-childItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -ErrorAction SilentlyContinue | Get-ItemProperty | Where-Object {$_.DisplayName -like "*NVIDIA Graphics Driver*"} | select DisplayName, UninstallString
# Splitting the Uninstall String into executable and argument list
$unused, $filePath, $argList = $us.UninstallString -split '"', 3
# Any of the following command can start the process
Start-Process -FilePath "C:\Windows\SysWOW64\RunDll32.EXE" -ArgumentList $argList -Wait
# or
Start-Process $filePath $argList -Wait
Once the process is started it displays the NVIDIA Uninstaller dialog box for manual selection/click of the UNINSTALL button to proceed further.
My UninstallString looks like:
"C:\Windows\SysWOW64\RunDll32.EXE" "C:\Program Files\NVIDIA Corporation\Installer2\InstallerCore\NVI2.DLL",UninstallPackage Display.Driver
I have tried following ways but nothing seems to work.
Start-Process -FilePath "C:\Windows\SysWOW64\RunDll32.EXE" -ArgumentList "/X $argList /quiet" -Wait
Start-Process $filePath -ArgumentList $argList "/S" -Wait
Please guide me, how to do silent uninstallation.
To summarize the comments into an answer:
#Get Uninstall String from Registry
$us = Get-childItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -ErrorAction SilentlyContinue | Get-ItemProperty | Where-Object {$_.DisplayName -like "*NVIDIA Graphics Driver*"} | select DisplayName, UninstallString
# Splitting the Uninstall String into executable and argument list
$unused, $filePath, $argList = $us.UninstallString -split '"', 3
# Append arguments for silent uninstall
# -deviceinitiated avoids a system restart
$argList += ' -silent -deviceinitiated'
# Any of the following command can start the process
Start-Process -FilePath "C:\Windows\SysWOW64\RunDll32.EXE" -ArgumentList $argList -Wait
The key is to add any arguments intended for rundll32.exe to the $argList string.

How to get pid from identical running processes and pipe the output into if statement

I want the script to find two identical processes that are currently running and pipe the PID of the process that matches a defined path in the variable $procName by using the If($_.Path -eq $procName){ command.
After the correct process has been identified based on it's full file path found earlier, I want to use it's unique PID to check whether it is currently suspended or not suspended.
If all goes well in the current pipe then use it's output value to run one of two commands below:
If($_.Path -eq $procName) {
Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner $myPID"
} Else {
Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner -r $myPID"
}
My issue is the output is the same result no matter if the processes is currently suspended or not
Start-Process cmd.exe -WindowStyle Maximized -ArgumentList /D /K pssuspend.exe -nobanner -r 18960
This is what I have so far:
$procName = 'C:\Program Files (x86)\Steam\steamapps\common\rocketleague\Binaries\Win64\RocketLeague.exe'
$procID = Get-Process -Name 'RocketLeague' | Select-Object -Property Id,Path | ForEach-Object {
If($_.Path -eq $procName){
$myPID = $_.Id
If(Get-ChildItem | Where-Object -FilterScript {$_.Responding -eq $false}) {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner $myPID"
} Else {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner -r $myPID"
}
}
}
Based on the code and respecting what Santiago has already pointed out, it looks like you are trying to take certain actions based on whether a particular process is responding. If I have that right, I don't see the need for Get-ChildItem. You could append the Select-Object command to include the Responding property then do the logic like:
$procName = 'C:\Program Files (x86)\Steam\steamapps\common\rocketleague\Binaries\Win64\RocketLeague.exe'
$procID =
Get-Process -Name 'RocketLeague' |
Select-Object -Property Id, Path, Responding |
ForEach-Object {
If($_.Path -eq $procName){
$myPID = $_.Id
If( !$_.Responding ) {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner $myPID"
}
Else {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner -r $myPID"
}
}
}
However, and unless there's more to the script, I don't think you need the Select-Object command at all:
$procName = 'C:\Program Files (x86)\Steam\steamapps\common\rocketleague\Binaries\Win64\RocketLeague.exe'
$procID =
Get-Process -Name 'RocketLeague' |
ForEach-Object {
If($_.Path -eq $procName){
$myPID = $_.Id
If( !$_.Responding ) {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner $myPID"
}
Else {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner -r $myPID"
}
}
}
Also, nothing will be in the $procID variable as the subsequent code doesn't write anything to the pipeline. I left it in only because I don't know the full intent.
You could also shorten the code Somewhat by moving some of the If Logic into a Where-Object clause, See below with $ProcID removed.
$procName = 'C:\Program Files (x86)\Steam\steamapps\common\rocketleague\Binaries\Win64\RocketLeague.exe'
Get-Process -Name 'RocketLeague' |
Where-Object{ $_.Path -eq $procName }|
ForEach-Object {
If( !$_.Responding ) {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner $($_.Id)"
}
Else {
Write-Host Start-Process cmd.exe -WindowStyle Maximized -ArgumentList "/D /K pssuspend.exe -nobanner -r $($_.Id)"
}
}
Note: I also used string expansion with a subexpression instead of assigning the $myPID variable.

How i take a first output before a command - Powershell

How do I take a first command output?
I Want to take the IdentifyingNumber.
I Have tried this following command:
$app = Get-WmiObject -Class Win32_Product | Where-Object {$_.Name -Like "App"}
$getNumber = $app[1]
OutPut:
IdentifyingNumber : {00000-00000-0000-000000000}
Name : App
Vendor : App
Version : 1.0.0
Caption : App, Inc.
Technically if you're putting [1] it selects the second object in the array as they start at [0] so if you wanted the first one do $var = $app[0].IdentifyingNumber
i have created this following scrip and it's worked so well, thank's for all, if i help someone this is the script.
$Keys = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
foreach ($subkey in $Keys) {
if($subkey.Name -notmatch "InstallWIX_"){
Set-Location -Path $subkey.PSPath
$app1 = Get-ItemProperty -Path ".\" | Where-Object displayname -Match "app1"
$app2 = Get-ItemProperty -Path ".\" | Where-Object displayname -Match "app2"
$GUID_APP1 = $app1.PSChildName
$GUID_APP2 = $app2.PSChildName
if ($app1.Displayname -eq "APP1") {
& cmd /c msiexec.exe /x $GUID_APP1 /qn /norestart
} elseif ($app2.Displayname -eq "APP2") {
& cmd /c msiexec.exe /x $GUID_APP2 /qn /norestart
}
}
}

Using result of test-path to execute powershell command

Looking to execute a powershell command that will uninstall an application and clear some registry entries if either a file/folder is not present on the system.
Currently looking at something like this:
if(!(test-path “c:\Windows\mdm” )
{
$productdetails=(Get-WmiObject -Query “Select IdentifyingNumber from win32_product where name = ‘Tesapp’“).identifyingnumber
$proc=(Start-Process -FilePath “msiexec.exe” -ArgumentList “/x $productdetails /qn /l*v c:\temp\Uninstall-testapp.log” -Wait -PassThru).ExitCode
if (!($proc -eq 0 -or $proc -eq 3010))
{
exit(1)
}
$RegKey=“HKLM:\SOFTWARE\Microsoft\TestAppManagement\S-0-0-00-0000000000-0000000000-000000000-000\MSI\{0}” -f $productdetails
if(test-path $RegKey)
{
$op= Get-Item $RegKey | Out-File “c:\windows\temp\TestApp_Reg_backup.reg” -Force
$op= Remove-Item $RegKey -Force
}
}
Interestingly if I run the test path it will return false which is expected, or if run the app uninstall/reg clear on its own it will work as intended - however i cannot run them together.
I assume i am making some sort of syntax/ basic logic error?

Powershell unable to uninstall silently

Start-Process -FilePath $application.UninstallString -ArgumentList "/q" -Wait -NoNewWindow
Start-Process -FilePath $application.UninstallString -ArgumentList "/s" -Wait -NoNewWindow
Start-Process -FilePath $application.UninstallString -ArgumentList "-q" -Wait -NoNewWindow
I tried to uninstall an application using the above commands, but when I run it the confirm window is prompted, I want to prevent the window from showing.
PoSH simply starts the installer / uninstaller (.msi, .exe). If the installer / uininstaller does not have a silent option, there is nothing PoSH can do about that. The RegKey uninstall string is only calling the original installer used to deploy the application.
See this post for a similar discussion.
How can I uninstall an application using PowerShell?
Using the WMI object takes forever. This is very fast if you just know the name of the program you want to uninstall.
$uninstall32 = gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
$uninstall64 = gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
if ($uninstall64) {
$uninstall64 = $uninstall64.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall64 = $uninstall64.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall64 /qb" -Wait}
if ($uninstall32) {
$uninstall32 = $uninstall32.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall32 = $uninstall32.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall32 /qb" -Wait}
Other example(s)s:
https://social.technet.microsoft.com/Forums/scriptcenter/en-US/60e06261-f134-41e8-9f99-6bada23a6f02/using-registry-uninstallstring-to-remove-software?forum=winserverpowershell
$javaVer = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall |
Get-ItemProperty |
Where-Object {$_.DisplayName -match "java" } |
Select-Object -Property DisplayName, UninstallString
ForEach ($ver in $javaVer) {
If ($ver.UninstallString) {
$uninst = $ver.UninstallString
& cmd /c $uninst /quiet /norestart
}
}
Search for and Uninstall Software on Remote or Local Computer via
Powershell
This script searches for and attempts to uninstall a piece of software
by product name. It queries the SCCM client's WMI class for the
product, finds the uninstall string and executes the uninstall string.
https://gallery.technet.microsoft.com/scriptcenter/Search-for-and-Uninstall-8c2c457e