Troubleshooting an MSI

As part of a project, we need to take a company's set of MSI's and install them all together. Our first revision worked well. Recently I received an update for one of the applications. When I started testing it, the install would get nearly complete and then just sit. It would say '0 Seconds Remaining'. That 0 Seconds occurred for over an hour with no change to the progress or status.

I had run the install using the log option, so I could see that no new log entries were being logged.

I used Process Explorer from Sysinternals. I ordered the processes by CPU utilization and noticed that wmiapsrv.exe was consuming resources. My thought was that the MSI was making a WMI Query. I decided to kill the wmi process to see if the log would update with exactly what was going on.

Lucky for me it did. It gave me a 1720 error. Reading the full error I saw that the error means a custom action failed. I was even provided with a line of where the error occurred. I looked at the custom action using orca and found the binary that it was using and what it was calling in that binary.

Orca can extract the binary, which is what I did and looked at the line referenced in the error. I saw the below VBScript code. (I exercised some Self-Censorship, but the code is still relevant)

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Account")
For Each objItem in colItems
Select Case objItem.SID
...
End Select
Next


The error occurred at the last line. ('Next') So, now I was getting some more clarity as to the problem. It failed at the Next command, since I killed the process that was at least partly responsible in serving up that collection.

I decided to run that query once to confirm what I was thinking. I ran wbemtest and connected to root/cimv2 and then ran the query 'Select * from Win32_Account'. First, I received all the accounts on my local computer. Then, it started retrieving all the accounts on the domain. We have many domain accounts. Easily over 50 thousand and it wouldn't be a stretch to say 100 thousand.

What they actually wanted was simply some account names based on a SID. So, 'S-1-5-32-544' would be the Administrator account. But if you renamed the account, it would be called something else. Here is a different way to get that info, with credit due to The Scripting Guys.

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set objAccount = objWMIService.Get("Win32_SID.SID='S-1-5-32-544'")
Administrators_Name = objAccount.AccountName

This will accomplish the same thing, but won't go through the entire domain like the previous code.

So, I explained this issue and should be receiving updated code shortly. But, what could I do if I didn't receive the updated MSI?

What we could do, is create a transform. In the transform we replace the Binary that the custom action is calling with our version of the code. When we run the installer we now have to call the transform with the TRANSFORMS= argument when launching the MSI.

Problem solved and everyone is happy.

No comments: