0

I am trying to push an uninstallation script org wide to remove python. Because this is happening on the backend, I need it to uninstall silently. What am I doing wrong? Thanks for any help in advance.

    $Programs = $SearchList | ?{$_.DisplayName -match ($ProgramName -join "|")}
Write-Output "Programs Found: $($Programs.DisplayName -join ", ")`n`n"

Foreach ($Program in $Programs)
{
If (Test-Path $Program.PSPath)
{
Write-Output "Registry Path: $($Program.PSPath | Convert-Path)"
Write-Output "Installed Location: $($Program.InstallLocation)"
Write-Output "Program: $($Program.DisplayName)"
Write-Output "Uninstall Command: $($Program.UninstallString)"

$UninstallString = $_.GetValue('UninstallString')
$isExeOnly = Test-Path -LiteralPath $UninstallString
if ($isExeOnly)
{
$UninstallString = "'$UninstallString'"
}
$UninstallString += '/quiet'

$Uninstall = (Start-Process cmd.exe -ArgumentList '/c', $Program.UninstallString -Wait -PassThru) 
<#Runs the uninstall command located in the uninstall string of the program's uninstall registry key, this is the command that is ran when you uninstall from Control Panel.
If the uninstall string doesn't contain the correct command and parameters for silent uninstallation, then when PDQ Deploy runs it, it may hang, most likely due to a popup.#>
GrayVi02
  • 15
  • 4

1 Answers1

0

There are several problems:

  • You're mistakenly referring to $_ instead of $Program in $_.GetValue('UninstallString'), which is likely what caused the error you saw.

    • However, $Program.GetValue('UninstallString') also doesn't work, because (as you state it in a later comment) $Program is of type [pscustomobject], which doesn't have a method by that name.

    • If you obtained $Program via Get-ItemProperty (without restricting the result to specific values with -Name), you can access the UninstallString value data as follows:

      $Program.UninstallString
      
  • $UninstallString = "'$UninstallString'" should be
    $UninstallString = "`"$UninstallString`"", because cmd.exe only understands "..." quoting.

  • $UninstallString += '/quiet' should be $UninstallString += ' /quiet', i.e. you need a space before /quiet.

  • You're not using $UninstallString in your Start-Process call.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thanks for this, it cleared up some errors. I changed the variable in the Start-Process call to $UninstallString. Now I get the error: ```` Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named 'GetValue'. At C:\Users\GrayVi02\Downloads\Python_Remediation1.ps1:28 char:1 + $UninstallString = $Program.GetValue('UninstallString') + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (GetValue:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFound```` – GrayVi02 Oct 18 '22 at 13:32
  • @GrayVi02, please see my update. If that doesn't help, you'll need to specify how you obtained the `$Program` / `$Programs` / `$SearchList` values. – mklement0 Oct 18 '22 at 16:48
  • Thank you this is helping. One last issue, any ideas? This has deleted the Python Launcher, but not its bits. Sub programs are still getting left behind i.e. Python 3.7.9 documents (64-bit), Python 3.7.9 Executables (64-bit), etc. These bits have exit code 1605 after remediation script runs. How can I get these bits deleted despite version and make sure everything Python is in fact off the device? I think these bits will cause Python to show up in reporting. More code in following comment. – GrayVi02 Oct 19 '22 at 01:29
  • ````$64BitProgramsList = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty $32BitProgramsList = Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty $CurrentUserProgramsList = Get-ChildItem "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | Get-ItemProperty $ProgramName = "Python" $SearchList = $32BitProgramsList + $64BitProgramsList```` – GrayVi02 Oct 19 '22 at 01:32
  • This is the beginning portion of what I posted on original post. The script returns uninstallation key MsiExec.exe /I{xxx -xxx-xxx-xxx} for the remaining bits. Thanks. – GrayVi02 Oct 19 '22 at 01:38
  • @GrayVi02, this answer addresses your question as asked. For follow-up questions, please create a _new_ question post. – mklement0 Oct 19 '22 at 02:07