Как запустить PowerShell в WiX с правильным доступом к реестру Windows?
Обновить
Интересно, что если я запускаю 32-битную PowerShell для запуска скрипта, это выдает мне ту же ошибку. Похоже, у 32-битного PowerShell нет доступа к 64-битному дереву реестра? Я пытался с помощью WixQuietExec64
но это дало ту же ошибку. Я также попытался указать полный путь к PowerShell (C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
) чтобы убедиться, что установщик запустил 64-битную версию, но STILL выдал ту же ошибку... Похоже, это могло быть вызвано тем, что сам установщик 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 приводит к следующему выводу:
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 из установщика WiX и выполнив сценарий, он не дает того же результата:
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
не может.
Это привело меня к мысли, что, возможно, я что-то упускаю при запуске PowerShell из установщика WiX...?
Вот что в моем файле wxs:
<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" />
Ниже приведен список элементов, которые я уже пробовал или дважды проверил:
- Я пробовал разные комбинации
-NoProfile
,-ExecutionPolicy ByPass
,-Version 2.0
и все равно ничего хорошего. - Я уже запускаю установщик как
InstallPrivileges="elevated"
- Я уже управляю
CustomAction
какExecute="deferred"
а такжеImpersonate="no"
- Я пробовал с
AdminImage="yes"
- Я пытался установить
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
Любая другая подсказка будет оценена.:(
1 ответ
Боже мой...
Хорошо, наконец-то все заработало. На самом деле было несколько проблем, и решения этих проблем были на самом деле кусочками информации, которую я собираю по нескольким вопросам SO.
Напомним, вот что я пытался сделать:
- Запустите PowerShell из WiX, чтобы запустить мой скрипт установки.
- Мой скрипт поиска в реестре Windows (требуется 64 бита) для определения местоположения установленного сервера Exchange
- Мой сценарий загружает сценарий командной консоли Exchange (EMS) (требуется 64-разрядный И соответствующий пользователь) из места установки
- В рамках сеанса EMS мой сценарий запускает множество других сценариев для регистрации плагина Exchange.
Проблема 1)
Независимо от того, что я сделал, установщик WiX всегда запускает мой PowerShell в 32-битной, это независимо от настроек Platform="x64"
, Win64="yes"
, и даже WixQuietExec64
, Я даже построил установщик в Visual Studio как x64
а все остальное как x64
,
Решение состоит в том, чтобы напрямую ссылаться на sysnative
PowerShell, это должно быть sysnative
в SetProperty
,
C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe
Я действительно пробовал это раньше, и думал, что это не работает, но основная причина была замаскирована проблемой 2 ниже.
Проблема 2)
Везде, где я читаю, говорят, что нужно бегать с Execute="deferred" Impersonate="No"
, Я считаю, что это действительно сработает в большинстве случаев, если вы не делаете ничего прикольного. Однако мне пришлось Impersonate
, Я обнаружил, что установщик WiX будет запускать ваш ЦС с повышенными правами пользователя NT Authority/System
, Это облажалось, потому что Exchange Management Shell
скрипт, который я пытался найти, в основном использовал бы ваши учетные данные и пытался установить сеанс с Exchange Server... и, конечно, вы не можете подключиться как NT Authority/System
!
Решение заключается в использовании Impersonate="yes"
так что установщик WiX будет запускать ваш ЦС с повышенными правами и пользователем, в котором вы сейчас авторизованы. У меня всегда было впечатление, что вы должны использовать Impersonate="no"
когда используешь Execute="deferred"
... но ты не
Я отказался от устранения неполадок в течение нескольких дней, а затем вернулся к нему и получил его работать. Две наиболее полезные команды, которые помогли мне понять это, были на самом деле:
- кто я
- Get-ChildItem env: (чтобы проверить PROCESSOR_ARCHITECTURE)