Stopping Automatic Reboot When Using Uninstall-Package or $MyVariable.uninstall() to Remove an Application

Maranya, Damon 326 Reputation points
2022-11-21T18:40:46.187+00:00

I'm building a script that's meant to uninstall a variety of versions of two applications. But the IdentifyingNumber attribute is not the same between some versions. So, I am currently using get-package to pull the application based on the name and $MyVariable.uninstall to remove the discovered applications. I was using Get-WmiObject -class Win32_Product but Get-Package seems to run a bit faster and also returns a more complete list of installed applications.

I can find ways to force a reboot with PowerShell and how to stop an automatic reboot using MSIExec.exe. But I can't seem to find anything about stopping an automatic reboot in PowerShell.

Does anyone know how to stop an automatic reboot after uninstalling an application using either Uninstall-Package or $MyVariable.uninstall?

Windows for business | Windows Server | User experience | PowerShell
Windows for business | Windows Client for IT Pros | User experience | Other
0 comments No comments
{count} votes

Accepted answer
  1. Rich Matheisen 47,901 Reputation points
    2022-11-23T02:43:24.57+00:00

    You really don't have a choice but to get the information from each computer's registry.

    This was the answer that I gave to another user several months ago. That person also had a need to modify the switches on the uninstall command line. You can use it as a template and customize it for your own needs:

    $AppNames =  @(  
     'App display name goes here'  
    )  
      
    $MsiExecOtherArgs = "/S /v /qn /norestart"  
      
    Function GetStartProcessArgs{  
        param (  
            [Parameter(mandatory=$true)]  
            [string]  
            $RemovalString,  
      
            [Parameter(mandatory=$false)]  
            [string]  
            $MoreArgs  
        )  
        $props = [ordered]@{}  
        if ($removalString -like "msiexec.exe *"){  
            $UninstallApp            = $RemovalString -replace "/I", "/X"  
            $props['FilePath']       = $UninstallApp -replace '^([^ ]+) .*$', '$1'          # get the executable name -- expects " /X{<guid>}" to always be there!  
            $props['ArgumentList']   = $UninstallApp -replace '^[^ ]+ ', ''                 # get the argument(s) -- expects " /X{<guid>}" to always be there!  
            if ($MoreArgs -and $MoreArgs.Length -gt 0){                                     # $MoreArgs can be an empty string too  
                $props.ArgumentList += (" " + $MoreArgs)                                    # add additional arguments (with leading space to separate from previous args)  
            }  
        }  
        else{  
            # NOTE: ignores $MoreArgs entirely if msiexec.exe isn't the uninstaller to run  
            if ($RemovalString -match '^"'){                                                # a quoted string -- path contains a space  
                $props['FilePath']   = $RemovalString -replace '^"([^"]+?)" ?.*$', '$1'     # keep spaces in path, drop quotes  
                if ($RemovalString -match '^".+?" ?'){  
                    $potentialargs       = $RemovalString -replace '^".+?" ?', ''           # remove path, keep arguments  
                }  
                else{  
                    $potentialargs = ""                                                     # return an empty string to avoid exceptions in code  
                }  
            }  
            else{  
                $props['FilePath']   = $RemovalString -replace '^([^ ]+?) .*$', '$1'        # get the executable name (unquoted path)  
                $potentialargs       = $RemovalString -replace '^[^ ]+ ', ''                # get the argument(s), if there are any  
            }  
            if ($potentialargs.trim().length -gt 0){                                        # if no arguments, ignore  
                $props['ArgumentList'] = $potentialargs  
            }  
        }  
      
        # return exe and arguments  
        $props  
    }  
      
    # begin main code  
    # get 64-bit software on 64-bit systems OR 32-bit software on 32-bit systems  
    [array]$32_or_64bitsoftware = get-itemproperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'  
    # get 32-bit software ON 64-bit systems  
    [array]$32_on_64bitsoftware = get-itemproperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'  
      
    $AppNames|  
        ForEach-Object{  
            $appname = $_  
            [array]$32_AND_64bit = @()  
            # check for software in both locations  
            $32_AND_64bit  = $32_or_64bitsoftware |  
                                        Where-Object { $_.DisplayName -like "*$appname*" }  
            $32_AND_64bit += $32_on_64bitsoftware |  
                                        Where-Object { $_.DisplayName -like "*$appname*" }                              
            # was the app's display name found?          
            if ($32_AND_64bit.count -eq 0){  
                "'$appname' was not found on this system"  
                Write-Verbose "'$appname' was not found on this system"  
            }  
            else{  
                # uninstall all versions of this software  
                $32_AND_64bit |  
                    ForEach-Object{  
                        if ($_.UninstallString.length -gt 0){  
                            $props = GetStartProcessArgs $_.UninstallString $MsiExecOtherArgs  
                            Write-Verbose "Starting '$($props.FilePath)' with arguments '$($props.ArgumentList)'"  
                            "Starting '$($props.FilePath)' with arguments '$($props.ArgumentList)'"  
                            # uncomment next line when you're ready  
                            #Start-Process @props -NoNewWindow -Wait  
                        }  
                    }  
            }  
        }  
    

2 additional answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2022-11-21T22:42:21.287+00:00

    That's usually a function of the program that does the actual ununstalling. If it's msi.exe, you'd use the /norestart parameter on the command like. If it's a 3rd-party uninstaller then you'd have to find out if there's an equivalent option.


  2. Rich Matheisen 47,901 Reputation points
    2022-11-22T20:05:16.09+00:00

    You can get the uninstall string for a program from the registry and if it's using msi.exe get the string and add "/norestart" to it and then run the modified uninstall string from you script.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.