如何在WiX中启动PowerShell并正确访问Windows注册表?

问题描述:

更新如何在WiX中启动PowerShell并正确访问Windows注册表?

有趣的是,如果我运行32位PowerShell来运行该脚本,它给了我同样的错误。它看起来像32位PowerShell无法访问64位注册表树?我尝试使用WixQuietExec64,但它给出了相同的错误。我也尝试提供PowerShell的完整路径(C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe),以确保安装程序启动64位版本,但这仍然给出了同样的错误...它看起来像这可能是由MSI安装程序本身是32位?

MSI (s) (4C:C0) [14:25:49:955]: Hello, I'm your 32bit Elevated Non-remapped custom action server. 

原帖

我有以下test.ps1脚本:

$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 

在正常PowerShell的Windows上运行的脚本产生以下的输出:

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\ 
... 

所以有用。现在从维克斯安装程序启动PowerShell和执行脚本,它不会产生相同的结果:如果我们观察到的错误信息

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 

现在,就好像它有树的访问,直到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\,因为我的脚本会搜索并列出所有版本,所以v15必须可以访问到这一点,但是当它试图更深入地获取ItemProperty时,它不能。

这使我相信,也许我错过了从WiX安装程序启动我的PowerShell的东西......?

这是在我的WXS文件:

<SetProperty Id="InstallPlugin" 
    Before ="InstallPlugin" 
    Sequence="execute" 
    Value ="&quot;powershell.exe&quot; -Command &quot;cd '[INSTALLFOLDER]'; &amp; '[#TestPS1]' ; exit $$($Error.Count)&quot;" /> 
<CustomAction Id="InstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no" /> 

以下是我已经尝试过或双重检查的项目清单:

  • 我试过的-NoProfile不同的组合, -ExecutionPolicy ByPass-Version 2.0仍然没有好处。
  • 我已经在运行安装程序为InstallPrivileges="elevated"
  • 我已经运行CustomActionExecute="deferred"Impersonate="no"
  • 我已经与AdminImage="yes"
  • 试过我试过设置<Property Id="MSIUSEREALADMINDETECTION" Value="1" />

任何其他线索将不胜感激。 :(

哦...我...上帝...

好吧,我终于得到了它的工作。实际上有几个问题以及这些问题的解决方案位实际上是和的信息,我从多个SO问题中收集信息。

总括来说,这里就是我试图做的事:

  1. 启动一个PowerShell从维克斯运行我的安装脚本。
  2. 我的脚本搜索注册表(需要64位)用于安装Exchange Server的位置
  3. 我的脚本加载在Exchange命令行管理程序(EMS)脚本(需要64位和正确的用户)从安装位置
  4. 根据EMS会议,我的脚本运行的其他脚本的早午餐来注册一个Exchange插件

问题1)

无论我做什么,该WiX的安装程序总是启动我的32B的PowerShell它,这是不管设置Platform="x64"Win64="yes",甚至WixQuietExec64。我甚至在Visual Studio中构建了安装程序x64其他所有内容作为x64

的解决方案是直接引用sysnative的powershell,它必须是在SetPropertysysnative

C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe 

其实我以前尝试过这一点,并认为这是行不通的,但根本原因是受到以下问题2所掩盖。

问题2)

我到处看,他们说你需要与Execute="deferred" Impersonate="No"运行。如果你没有做任何事情,我相信这对大多数情况确实有效。但是,我必须Impersonate。我发现WiX安装程序会以用户NT Authority/System提升您的CA。这使我搞砸了,因为我试图从源代码中获取的Exchange Management Shell脚本基本上会使用您的凭据并尝试与Exchange Server建立会话......当然,您无法连接为NT Authority/System

的解决方案是使用Impersonate="yes",使维克斯安装程序将运行CA的升高,你当前登录的用户。使用Execute="deferred"时,我总是有,你必须使用Impersonate="no"的印象...... 但你不't

我放弃了几天的故障排除,然后回到它并得到它的工作。帮助我想通了这一点的2个最有用的命令实际上是:

  • WHOAMI
  • 获取-ChildItem ENV:(检查PROCESSOR_ARCHITECTURE)