Powershell Uninstall Script - Have a real headache - powershell

I am currently writing a script that has involves a number of uninstalls of programs installed on a WES 7 device. One of the applications I need to uninstall (VMware Horizon View Client) asks for a restart. When this is part of the script, it seems to accept the default button (YES) and proceeds to reboot the device. The script therefore fails.
I would really appreciate your help in how to prevent this reboot from taking place.
FYI: This script is sent down via a management tool and is run in an elevated manner on the target.
This is my script:
set-executionpolicy unrestricted
#############################################################
# Un-install unwanted applications
#############################################################
$application = Get-WMIObject Win32_Product -filter "Name='ThinPrint Client Windows 8.6'"
$application.Uninstall()
$application = Get-WMIObject Win32_Product -filter "Name='2X Client'"
$application.Uninstall()
$application = Get-WMIObject Win32_Product -filter "Name='Adobe Reader X (10.1.4)'"
$application.Uninstall()
$application = Get-WMIObject Win32_Product -filter "Name='VMware Horizon View Client'"
$application.Uninstall()
$application = Get-WMIObject Win32_Product -filter "Name='VERDE VDI User Tools'"
$application.Uninstall()
$application = Get-WMIObject Win32_Product -filter "Name='vWorkspace Connector for Windows'"
$application.Uninstall()
#############################################################
# Remove Internet Explorer Access
#############################################################
dism /online /norestart /Disable-Feature /FeatureName:Internet-Explorer-Optional-x86
#############################################################
# Remove IE Browser LNK from Taskbar
#############################################################
del "C:\Users\User\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\Launch Internet Explorer Browser.lnk"
#############################################################
# Make Citrix Receiver the shell
#############################################################
Push-Location
CD 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon'
New-Itemproperty -path .\ -name Shell -Type String -Value 'c:\program files\Citrix\Receiver\receiver.exe'
Pop-Location
set-executionpolicy restricted
# End of Script
I would very much appreciate some help in how to prevent the reboot half way through the script.

I strongly suggest NOT using Win32_Product. Every time Win32_Product is called it does a software consistency check of each installation. Not only does this make things very slow, it may also trigger a software repair if it finds something wrong.
http://gregramsey.net/2012/02/20/win32_product-is-evil/
Instead go into the registry and just call the uninstall string.
http://support.microsoft.com/kb/247501
You can use msiexec's norestart flag to try to prevent reboots.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa372024(v=vs.85).aspx

Related

Delete an .EXE application remotely

when the application is from .msi or .msu it's easy to uninstall them from a remote computer using WMI, but WMI only works on Microsoft based applications (.msi, .msu). I can't find a way to uninstall an exe based app remotely without using invoke, I try to not use it because this will be used by many people and on many computers, it's disabled, I can enable it for me but not for everyone (I'm an intern :D)
this is the code that I have for .exe but it's not remote
cmd.exe /c "$($app.meta.Attributes["UninstallString"]) /S"
while this is a remote msi, msu uninstall line
$Application = Get-WmiObject Win32_Product -ComputerName $ComputerName | Where-Object {$_.Name -eq $Name} #choose the object, this will be the app that we will delete
if ($Application) {
$Application.Uninstall()
any suggestion will be appreciated

How to uninstall a application through powershell which is not a Microsoft product

I want to uninstall an application through powershell scripting which is not a Microsoft product
I have tried with the below code but then it says "you cannot call a method on a null valued expression". This was because it couldn't point to that respective software.
$app = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like "*Software_Name*" }
$app.Uninstall()
And when I tried with Get-RemoteProgram command, it is listing out only the Microsoft softwares.
How to uninstall other softwares?
A possible solution is to find the GUID of the application in the registry in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and uninstall it using MsiExec:
Start-Process -FilePath MsiExec -ArgumentList '/quiet /uninstall {109A5A16-E09E-4B82-A784-D1780F1190D6}' -Wait
The above example uninstalls the Windows Firewall Configuration Provider.

Remote Powershell popup message

I'm attempting to create a remote powershell popup window to any users logged into a target computer.
I have found a simple script that does create a popup window:
(New-Object -ComObject wscript.shell).popup("THIS IS A TEST MESSAGE")
However, I cannot run this script on remote devices. We have powershell remoting restricted in our environment so I cannot use the invoke-command cmdlet in powershell.
I have bypassed this restriction in the past by using the Invoke-WmiMethod cmdlet and creating a new process remotely to achieve the desired results, like such:
Invoke-WmiMethod -Class Win32_Process -ComputerName $computer -Name Create -ArgumentList "C:\Program Files\Test\Test.exe -argument"
However, I cannot seem to find a way to generate a remote popup window using this method.
Does anybody have any great ideas on how I can accomplish my goal?
I figured this out. I used the msg.exe application to display my message and used powershell Invoke-WmiMethod to execute the command locally on the PC as we have remote messaging disabled:
Invoke-WmiMethod -Class Win32_Process -ComputerName HostPC -Name Create -ArgumentList "C:\Windows\System32\msg.exe * This is a test message."
I edited the script samples above with Powershell to make it easier to run with variables so you don't have to edit the file every time.
$server = read-host -prompt 'Input server name';
$message = read-host -prompt 'add text string';
Invoke-WmiMethod -Class win32_process -ComputerName $server -Name create -ArgumentList "c:\windows\system32\msg.exe * $message"
Thanks to Maumee River for the original answer

Invoke-command and msiexec

I'm trying to remove an application on a remote machine using the Invoke-Command cmdlet but it's not working.
Here is my script:
Invoke-Command -ComputerName "Computername" -Verbose -ScriptBlock {
msiexec.exe /x '{4ADBF5BE-7CAF-4193-A1F9-AM6820E68569}' /qn /passive
}
Are there any reliable, working alternatives in this context?
This doesn't use Invoke-Command or MSIExec, but it's a functional uninstall method for removing applications on remote machines using WMI for anything registered with WMI (should be anything installed via msiexec).
(Get-WmiObject -Class Win32_product -ComputerName ComputerName -Filter {IdentifyingNumber LIKE '{4ADBF5BE-7CAF-4193-A1F9-AM6820E68569}'}).uninstall()
Additionally that can be put into a ForEach loop if you have several computers to do it on. If you have the Name, IdentifyingNumber, and Version listed in WMI you can make it much faster with the following context (using AT&T Connect Participant Application v9.0.82):
$App="IdentifyingNumber=`"`{1F3A6960-8470-4C84-820C-EBFFAF4DA580`}`",Name=`"AT&T Connect Participant Application v9.0.82`",version=`"9.0.82`""
([WMI]\\ComputerName\root\cimv2:Win32_Product.$App).Uninstall()
Yes, the $App string is horribly escaped, but that's due to the way WMI requires the string to be formatted with curly braces and double quotes and what not. This is not exactly useful for a single uninstall since it requires you to get all that info up front and format the key string. If you were going to remove a piece of software off 30 machines though, it would be much better. You can get all that info by just leaving off the .Uninstall() method from my first command, so...
Get-WmiObject -Class Win32_product -ComputerName RemoteComputer -Filter {IdentifyingNumber LIKE '{1F3A6960-8470-4C84-820C-EBFFAF4DA580}'}
Will spit back something like:
IdentifyingNumber : {1F3A6960-8470-4C84-820C-EBFFAF4DA580}
Name : AT&T Connect Participant Application v9.0.82
Vendor : AT&T Inc.
Version : 9.0.82
Caption : AT&T Connect Participant Application v9.0.82
Can also be used with the name, or even partial names by changing the filter to something like `{Name LIKE '%AT&T Connect%'} or you can query WMI to list all the applications registered with it by leaving the -Filter off completely, though you probably want to pipe that to Format-Table to make it readable. I used:
gwmi -class win32_product -computername RemoteComputer|ft IdentifyingNumber,Name,Version
A good read with more info about this can be found at this link
Here is the solution I came up with
$myses = New-PSSession -ComputerName "Computer"
Invoke-Command -Session $myses -ScriptBlock {
#finds all instances of Java installed
$find_sep = gwmi win32_product -filter "Name LIKE '%Java%'" | select -ExpandProperty IdentifyingNumber
foreach($i in $find_sep){
msiexec.exe /x $i /qn /passive /l*v! c:\uninst.log
}
}

Enabling Enable-PSRemoting on Powershell 1.0

This is in relation to http://www.computerperformance.co.uk/powershell/powershell_remote.htm . Currently, most of the machines in my Test environment are on Powershell 1.0. Under such a scenario, is there a way by which I can still manage to make remote calls via Powershell from one machine to another.
My ultimate motive is to start/stop/restart a windows service remotely using Powershell.
You're not going to be able to use PowerShell Remoting in 1.0, but you can use WMI or .Net ServiceController for this task.
$S = Get-WmiObject -Computer $Server -Class win32_service -filter "name='$ServiceName'"
$S.StopService()
$S.StartService()
In fact, if you have 2.0 on the client you're on, you can skip a couple of steps versus the way it's written on either of those posts by using Invoke-WMIMethod:
Invoke-WMIMethod -Name StopService -Computer $Server -Class win32_service -filter "name='$ServiceName'"
Invoke-WMIMethod -Name StartService -Computer $Server -Class win32_service -filter "name='$ServiceName'"
Note: for general remoting, you could set up an SSH server on each box and remote in that way (and set up PowerShell as the default shell), /n software has a pre-built solution around that.