Я пытаюсь получить имя ключа из раздела реестра, свойство которого соответствует определенному тексту. Это имя ключа затем будет использоваться для поиска правильного файла MSI для запуска с помощью MSIExec.exe для удаления программного обеспечения. Следующее работает, как и ожидалось, когда ключ найден, но не работает, если ключ не найден.
Try{
$ErrorActionPreference = "SilentlyContinue"
$AlphaRegistry = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object{$_.DisplayName -like "*Alpha*"}
switch ($AlphaRegistry.PSChildName.trim('{}')) {
FB917EA8-1B7F-4347-A05F-7AF03DF0577D {$InstallerMSI = 'setup17_6.msi'}
C75C2499-0D4D-6789-BEB2-32CA03BF8880 {$InstallerMSI = 'setup17_5.msi'}
68C6A4F3-3422-467D-AAAA-924282DC5365 {$InstallerMSI = 'set17_4_1.msi'}
Default {Add-LogContent "Unable to identify msi file to uninstall Alpha version installed. Unable to progress"
[System.Environment]::Exit(1)}}
# Uninstall code using $InstallerMSI here
}
catch{
$ErrorMessage = " Error during removal. Unable to continue. " + $Error[0].Exception.Message
Add-LogContent -LogText $ErrorMessage
[System.Environment]::Exit(1)
}
Я знаю, что после $AlphaRegistry = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object{$_.DisplayName -like "*Alpha*"} мне нужно проверить значение null, но, что бы я ни пытался, я не могу пройти эту строку. Я всегда получаю сообщение об ошибке: «Вы не можете вызвать метод для выражения с нулевым значением». Я даже не знаю, какой метод вызывается в этой строке.
Я попытался вывести из уравнения совокупность $AlphaRegistry, но все равно получаю ту же ошибку, поэтому знайте, что это не присвоение переменной значения null.
Я попробовал тот же код вне блока Try-Catch, но не получил ошибки и поэтому предполагаю, что причиной является моя реализация блока Try-Catch. Я также пробовал различные настройки $ErrorActionPreference как внутри, так и перед блоком Try-Catch.
Я хочу использовать обработку ошибок для удаленного кода удаления, поэтому в идеале мне нужен способ заставить поиск работать в блоке Try-Catch.
Любой указатель в правильном направлении будет оценен по достоинству.
Я согласен с комментарием выше. Хотя я бы пошел по пути if ($null -eq ($AlphaRegistry = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' | ? {$_.DisplayName -like "*Alpha*"})) { throw "No program found" }
@TheMadTechnician. Спасибо, после дальнейшего тестирования вы оказались правы, проблема возникает в следующей строке. При выполнении кода ошибка выдается при переходе на эту строку, а не при ее выполнении. Я думаю, это странное поведение, наблюдаемое как в редакторах кода ISE, так и в Visual Studio. Я поработаю над исправлением и опубликую, когда оно будет доказано.





Если вы используете PowerShell Core (v6.1+), вы можете использовать операторы с нулевым условием (.?), вот так $AlphaRegistry.PSChildName?.trim('{}').
switch ($AlphaRegistry.PSChildName?.trim('{}')) { <# ... #> }
Если вы используете Windows PowerShell, вы можете использовать оператор if, завернутый в подвыражение $():
switch ($(if ($null -ne $AlphaRegistry.PSChildName) { $AlphaRegistry.PSChildName.trim('{}') })) { <# ... #> }
Или приведите объект к строке, заключив его значение в двойные кавычки, например "$($AlphaRegistry.PSChildName)", и это работает в обеих версиях PowerShell:
switch ("$($AlphaRegistry.PSChildName)".trim('{}')) { <# ... #> }
После тестирования я остановился на следующем решении. Мне нравится его простота и тот факт, что в конечном итоге я получаю строку для «сравнения» в операторе переключения.
Этот способ также позволяет мне использовать значение по умолчанию в переключателе для журналирования без дополнительных строк кода.
Перед процессом удаления добавляется дополнительный оператор if для размещения нулевого значения в $AlphaRegistry.
Спасибо всем за вашу помощь.
Try{
$ErrorActionPreference = "SilentlyContinue"
$AlphaRegistry = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object{$_.DisplayName -like "*Alpha*"}
switch ("$($AlphaRegistry.PSChildName)".trim('{}')) {
FB917EA8-1B7F-4347-A05F-7AF03DF0577D {$InstallerMSI = 'setup17_6.msi'}
C75C2499-0D4D-6789-BEB2-32CA03BF8880 {$InstallerMSI = 'setup17_5.msi'}
68C6A4F3-3422-467D-AAAA-924282DC5365 {$InstallerMSI = 'set17_4_1.msi'}
Default {Add-LogContent "Unable to identify msi file to uninstall Alpha version installed. Unable to progress"}
}
enter code here
if ($null -ne $AlphaRegistry) {
# Uninstall code using $InstallerMSI here
}
}
catch{
$ErrorMessage = " Error during removal. Unable to continue. " +
$Error[0].Exception.Message
Add-LogContent -LogText $ErrorMessage
[System.Environment]::Exit(1)
}
Вы уверены, что ошибка именно в этой строке? Мои деньги на ошибку, возникающую в следующей строке при попытке вызвать метод
.Trim(). Неужели так сложно добавитьIf(!$AlphaRegistry){Write-Warning "App not found"; continue}передswitch?