powershell script installs an application using msiexec and was closed

Christoph_H 20 Reputation points
2023-04-27T09:52:06.4833333+00:00

We have a powershell-install script, that installs automatically our application-msi at a Windows Server 2019.

This script worked fine. For a few months, the script/powershell-session has been aborted during execution of the msiexec command. The installation with msiexec completes successfully, but the powershell-script is closed.

Here the part of the powershell-script:

try {
	Write-Host "[+] Start-Process msiexec for application-installation..."
	Start-Process "msiexec" -ArgumentList @("/i $msiFile","/passive","APPPOOL=$targetAppPool","WEBSITE=$webSiteName","WEBSITE_PORT=$webSitePort","IISROOT=$wwwrootFolder") -Wait
	# --- here, the powershell-execution was interrupted and also no exception was occured ---
	Write-Host "[:] msiexec has exited properly."
} catch {
	Write-Host "[#] An exception occured during install..."
}

The eventlog on the server:

User's image

And the warning shows:

User's image

I did not find any solutions until now.

Can anyone help me to find out, what's the reason for this issue?

Thanks,

Christoph

Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

Answer accepted by question author
  1. MotoX80 37,156 Reputation points
    2023-04-28T13:33:12.81+00:00

    It would appear that something else is the script is opening a handle to something that the MSI restart manager wants to update, and it is terminating the Powershell process.

    What does the script do before it hits the try/catch portion that you posted? Can you simplify the script to just call msiexec?

    Try this, download handle.exe and put it on the server somewhere.

    https://learn.microsoft.com/en-us/sysinternals/downloads/handle

    In the script add a transcript (start-transcript) if you haven't already added one. Then right before you call msiexec, call handle.exe. That will show all handles for the current Powershell pid.

    c:\utils\handle.exe  -accepteula -p $pid
    
    

    Do you see any files/folders/registry in the transcript that are related to what the MSI might update?

    0 comments No comments

6 additional answers

Sort by: Most helpful
  1. MotoX80 37,156 Reputation points
    2023-05-02T14:16:14.34+00:00

    Well, here are some more thoughts that I had. Don't know if any will help you, but I will offer them up anyway.

    What is the current working directory for the Powershell process? Maybe CD to some unrelated folder like c:, or \Windows\temp before calling msiexec.

    When you test for the version of the application, remove the variable when you are done. Do that for any variable that might refer to an app related resource.

    $app = get-item myapp.exe 
    ... test ....
    remove-variable app
    

    Temporarily disable any antivirus software that you have running when you run the script.

    Change the log switch to add the x option. See if that adds any more output. "/lxv* log.txt"

    On the problem server, RDP to it and run the script interactively. Remove the /passive switch from the msiexec call and let it display the UI. Do you get a prompt that says that it needs to terminate Powershell.exe because it has an open handle?

    On the test server where it works, add the call to handle.exe and then compare its output with the output on the failing server.

    Good luck.

    0 comments No comments

  2. Christoph_H 20 Reputation points
    2023-05-03T15:16:06.6066667+00:00

    I found it (ahhhhh).

    The solution was your last answer (remove the /passive argument) in combination with the handle.exe to specify which files are locked.

    On our application server i have to determine which version of our application is installed and then it would only be shown the "newer" created versions. To get the version of the dll i used the powershell-command:

    $Assembly = [Reflection.Assembly]::Loadfile($filename)
    

    and this command locks the file ... and the handle.exe did correctly show this file as locked:

    B7C: File (R-D) C:\inetpub\wwwroot\WebServicesRoot\ServerConfigurator\bin\MyApplication.exe

    Now i've changed this command to:

    $Assembly = [Reflection.Assembly]::Load([System.IO.File]::ReadAllBytes($filename))
    

    and now it works as it should.

    For comparison on our testservers i did'nt look at the version because the currently installed app will be uninstalled before installing the test-version and so the file was never locked.

    Many thanks to the helpers especially to MotoX80 for the helpful ideas and the solution!

    Thanks!!


Your answer

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