i tried to uninstall puppet-agent-x64 silently used this command:
$registryPath = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty | Where-Object {
$_.displayName -eq "Puppet Agent (64-bit)"
} | Select-Object -Property UninstallString
$uninstall = $registryPath.UninstallString
& cmd /c $uninstall /qn /norestart
and one can still finding the program under appwiz.cpl
Any hence please!
Related
I'm trying to make a powershell script to uninstall Onedrive from users computers by running Invoke-Command -computername computer1 -filepath script.ps1
but i keep getting issues with the last step.
The first function "doUninstall" works just fine, it runs it and so on.
But the second one "douninstall2" doesnt work, it cant run the file
Anyone have any ideas what im doing wrong and how to fix this?
When i try running it using
Start-Process -filepath $UninstallCommand -ArgumentList "$EXEArgumente" -Wait
I can see the process starting on the target computer but it closes immediately
C:\Users\myuser\AppData\Local\Microsoft\OneDrive\23.002.0102.0004_5\OneDriveSetup.exe /uninstall
DEBUG: 78+ >>>> Write-Output "Uninstalling OneDrive found in Uninstall registry key"
Uninstalling OneDrive found in Uninstall registry key
DEBUG: 79+ >>>> $proc = Start-Process "$UninstallString" -PassThru
DEBUG: 83+ >>>> Write-Output "Uninstall failed with exception $_.exception.message"
Uninstall failed with exception This command cannot be run due to the error: The system cannot find the file specified..exception.message
#Requires -RunAsAdministrator
Set-PSDebug -Trace 2
function doUninstall($check) {
if (Test-Path $check) {
Write-Output "Uninstalling OneDrive found in $check"
$proc = Start-Process $check "/uninstall" -PassThru
$proc.WaitForExit()
}
}
function douninstall2 {
if (Test-Path $UninstallString) {
$UninstallString
Write-Output "Uninstalling OneDrive found in Uninstall registry key"
$proc = Start-Process "$UninstallString" -PassThru
$proc.WaitForExit()
}
else {
write-output "File not found"
}
}
function unstring {
$PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$'
$username = Read-Host "Enter User ID: "
$ApplicationName = "Microsoft Onedrive"
# Get Username, SID, and location of ntuser.dat for all users
$ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} |
Select #{name="SID";expression={$_.PSChildName}},
#{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}},
#{name="$username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}}
# Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded)
$LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select #{name="SID";expression={$_.PSChildName}}
# Get all users that are not currently logged
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select #{name="SID";expression={$_.InputObject}}, UserHive, Username
# Loop through each profile on the machine
Foreach ($item in $ProfileList) {
# Load User ntuser.dat if it's not already loaded
IF ($item.SID -in $UnloadedHives.SID) {
reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null
}
#####################################################################
# This is where you can read/modify a users portion of the registry
# This example lists the Uninstall keys for each user registry hive
"{0}" -f $($item.Username) | Write-Output
$Global:Selection = (Get-ChildItem -Path registry::HKEY_USERS\$($Item.SID)\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | ForEach-Object { Get-ItemProperty $_.PSPath } | Where-Object { $_.DisplayName -match "$ApplicationName" } | Select-Object Publisher,DisplayName,Version,UninstallString)
#$Selection2 = (Get-ChildItem -Path registry::HKEY_USERS\$($Item.SID)\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | ForEach-Object { Get-ItemProperty $_.PSPath } | Where-Object { $_.DisplayName -match "$ApplicationName" } | Select-Object Publisher,DisplayName,Version,UninstallString)
#####################################################################
$Selection | ForEach-Object {
$Global:UninstallString = $_.UninstallString
}
}
# Unload ntuser.dat
IF ($item.SID -in $UnloadedHives.SID) {
### Garbage collection and closing of ntuser.dat ###
[gc]::Collect()
reg unload HKU\$($Item.SID) | Out-Null
}
}
try {
$check1 = "$ENV:SystemRoot\System32\OneDriveSetup.exe"
$check2 = "$ENV:SystemRoot\SysWOW64\OneDriveSetup.exe"
$check3 = "$ENV:ProgramFiles\Microsoft Office\root\Integration\Addons\OneDriveSetup.exe"
$check4 = "${ENV:ProgramFiles(x86)}\Microsoft Office\root\Integration\Addons\OneDriveSetup.exe"
Write-Output "Stopping OneDrive processes..."
Stop-Process -Name OneDrive* -Force -ErrorAction SilentlyContinue
# Uninstall from common locations
doUninstall($check1)
doUninstall($check2)
doUninstall($check3)
doUninstall($check4)
# Uninstall from Uninstall registry key UninstallString
unstring
douninstall2
}
catch {
Write-Output "Uninstall failed with exception $_.exception.message"
exit 1
}
I've tried multiple solutions, like adding "" around the path, adding in invoke-command inside the code but nothing works for me.
uninstall-package wont work for me here.
I'm moving a yaml pipeline so it uses PS Core. One of the steps is to parse currently installed software and uninstall it if it exists:
$appsToUninstall = Get-Package -Provider Programs -IncludeWindowsInstaller -name "*$Instance*"
if ($appsToUninstall.count -gt 0)
{
Get-Service | Where-Object { $_.Name -match "$Instance" } | Stop-Service
$appsToUninstall | Uninstall-Package -Force -Verbose
Write-Output "Uninstalled $Instance"
}
else
{
Write-Warning "Nothing to uninstall! Could not locate $Instance as an installed instance. Continuing as usual."
}
However, it would seem that the new Get-Package - no longer provides installed software.
Is there any way to use native cmdlets (not CMI/WMI [wmi is deprecated!]) to achieve that in the new PS 7+?
You can parse the registry to achieve this :
$Instance = "MyAppToUninstall"
# Initialize array to avoid errors on 32 bits applications addition
[array]$appsToUninstall = #()
# Get 64 bits programs
$appsToUninstall = Get-ItemProperty `
HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select DisplayName, UninstallString |
Where { $_.DisplayName -like "*$Instance*" }
# Add 32 bits programs
$appsToUninstall += Get-ItemProperty `
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select DisplayName, UninstallString |
Where { $_.DisplayName -like "*$Instance*" }
if ($appsToUninstall.count -gt 0)
{
Get-Service | Where-Object { $_.Name -match "$Instance" } | Stop-Service
$appsToUninstall | ForEach-Object {
$app = $_.UninstallString.Substring(0, $_.UninstallString.IndexOf(".exe") + 4)
$arguments = $_.UninstallString.Substring($_.Uninstallstring.IndexOf(".exe") + 5)
if ($app -match "(?i)msiexec")
{
# if MSI package, replace /i parameter by /x to uninstall and
# add /passive parameter to automate the uninstallation
$arguments = "$($arguments.Replace("/I", "/x", [system.StringComparison]::InvariantCultureIgnoreCase)) /passive"
}
Start-Process -FilePath $app -ArgumentList $arguments
}
Write-Output "Uninstalled $Instance"
}
else
{
Write-Warning "Nothing to uninstall! Could not locate $Instance as an installed instance. Continuing as usual."
}
I hope this helps :)
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.
I created a script to uninstall an application silently from the reg keys. It's worked for a few different apps without an issue. I'm trying to uninstall brave browser but, I keep getting this error below. I think the reason is because the uninstall string for brave is
C:\Program Files\BraveSoftware\Brave-Browser\Application\95.1.31.91\Installer\setup.exe" --uninstall --system-level.
The --uninstall and --system-level may be causing the error and I'm not to sure how to get around it.
Any ideas are greatly appreciated.
Error Message Below
Start-Process : This command cannot be run due to the error: The system cannot find the file specified.
At line:11 char:40
... isplayName){Start-Process -Wait -FilePath "$remove32" -ArgumentList "
$appName = "brave"
$32bit = get-itemproperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall*'| Where-Object { $.DisplayName -match "^$appName"} | Select-Object DisplayName, DisplayVersion, UninstallString| Where-Object { $.DisplayName -match "^$appName"}
$remove32 = $32bit.UninstallString
$64bit = get-itemproperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall*' | Where-Object { $.DisplayName -match "^$appName"} | Select-Object DisplayName, DisplayVersion, UninstallString | Where-Object { $.DisplayName -match "^$appName"}
$remove64 = $64bit.uninstallstring
if ($appName -like $32bit.DisplayName){Start-Process -Wait -FilePath $remove32 -ArgumentList "/S" -PassThru}
else {Start-Process -Wait -FilePath $remove64 -ArgumentList "/S" -PassThru}enter code here
It's kind of a pain, but you need to parse the command from the arguments somehow. Also the silent install option might not be '/S'. I think I've seen '--force-uninstall'. It's easier with msi installs. You can just use uninstall-package.
$uninstallstring = '"C:\Program Files\BraveSoftware\Brave-Browser\Application\95.1.31.91\Installer\setup.exe" --uninstall --system-level'
$split = -split $uninstallstring
& (-join $split[0..1]) $split[2] $split[3]
Note that you can get the uninstallstring from get-package too.
$uninstallstring = get-package *brave* | % { $_.metadata['uninstallstring'] }
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
}
}
}