Update
Interesting, if I run 32bit powershell to run the script, it gives me the same error. It looks like the 32bit powershell has no access to the 64 bit registry tree? I tried using WixQuietExec64
but it gave the same error. I also tried providing the full path of the powershell (C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
) to ensure the installer to launch the 64bit version, but that STILL gave the same error... It looks like this might be caused by the MSI installer itself being 32bit??
MSI (s) (4C:C0) [14:25:49:955]: Hello, I'm your 32bit Elevated Non-remapped custom action server.
Original post
I have the following test.ps1
script:
$exchangeroot = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\"
$allexchanges = Get-ChildItem -Path Registry::$exchangeroot -Name | Where-Object { $_ -match "^V.." }
$sorted = $allexchanges | Sort-Object -descending
If ($sorted.Count -gt 1) { $latest = $sorted[0] } Else { $latest = $sorted }
$setup = $exchangeroot + $latest + "\Setup"
$properties = Get-ItemProperty -Path Registry::$setup
$properties
Running the script in a normal PowerShell windows yields the following output:
PS C:\Program Files (x86)\TrustValidator Exchange Server Plugin> .\test.ps1
Required machine-level settings. : 1
Services : C:\Program Files\Microsoft\Exchange Server\V15
NewestBuild : 10845
CurrentBuild : 710737954
Information Store Service : 1
Messaging and Collaboration Event Logging : 1
MsiInstallPath : C:\Program Files\Microsoft\Exchange Server\V15\
...
So it works. Now launching PowerShell from WiX installer and executing the script, it doesn't generate the same result:
WixQuietExec: Get-ItemProperty : Cannot find path
WixQuietExec: 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\v15\Setup' because it
WixQuietExec: does not exist.
WixQuietExec: At C:\Program Files (x86)\TrustValidator Exchange Server Plugin\test.ps1:10
WixQuietExec: char:16
WixQuietExec: + $properties = Get-ItemProperty -Path Registry::$setup
WixQuietExec: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WixQuietExec: + CategoryInfo : ObjectNotFound: (HKEY_LOCAL_MACH...erver\v15\Set
WixQuietExec: up:String) , ItemNotFoundException
WixQuietExec: + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetIt
WixQuietExec: emPropertyCommand
Now if we observe the error message, it is as though it has access of the tree up until HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\
, because my script would search and list all the versions, so v15
has to be accessible up to that point, however when it tries to go deeper to get the ItemProperty
, it can't.
This lead me to believe that perhaps I'm missing something when launching my PowerShell from WiX installer...?
This is what's in my wxs file:
<SetProperty Id="InstallPlugin"
Before ="InstallPlugin"
Sequence="execute"
Value =""powershell.exe" -Command "cd '[INSTALLFOLDER]'; & '[#TestPS1]' ; exit $$($Error.Count)"" />
<CustomAction Id="InstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no" />
Below are a list of items that I've already tried or double checked:
-NoProfile
, -ExecutionPolicy ByPass
, -Version 2.0
and still no good.InstallPrivileges="elevated"
CustomAction
as Execute="deferred"
and Impersonate="no"
AdminImage="yes"
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
Any other clue would be appreciated. :(
Oh... my... god...
Ok I finally got it working. There were actually several problems and the solutions for these problems were actually in bits and pieces of information that I gather from across multiple SO questions.
To recap, here is what I was trying to do:
Problem 1)
No matter what I did, the WiX installer always launches my powershell in 32bit, this is regardless of setting Platform="x64"
, Win64="yes"
, and even WixQuietExec64
. I even built the installer in Visual Studio as x64
and everything else as x64
.
The solution is to directly reference the sysnative
powershell, it has to be sysnative
in the SetProperty
.
C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe
I actually did tried this before, and thought it wasn't working, but the root cause was being masked by Problem 2 below.
Problem 2)
Everywhere I read, they said you need to run with Execute="deferred" Impersonate="No"
. I believe this would indeed work for the most cases if you are not doing anything funky. However, I had to Impersonate
. I discovered that the WiX installer would run your CA as elevated with user NT Authority/System
. This screwed me over because the Exchange Management Shell
script I was trying to source would basically use your credential and try to establish a session with the Exchange Server... and of course you can't connect as NT Authority/System
!
The solution is to use Impersonate="yes"
so that the WiX installer would run your CA as elevated AND the user you are currently logged in. I always had the impression that you must use Impersonate="no"
when using Execute="deferred"
... but you don't.
I gave up troubleshoot this for a few days and then went back to it and got it working. The 2 most helpful commands that helped me figured this out were actually:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With