Home > OS >  Powershell Get-Itemproperty [Registry] not working for C search
Powershell Get-Itemproperty [Registry] not working for C search

Time:05-04

Trying to use this command in script but the in command appears to be breaking it. Here is the command/results below. Note: I will not be able to use Wildcard because the exact name is used elses where which breaks with wild cards.

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                 HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
    Where-Object { $_.DisplayName -Match 'Microsoft Visual C   2015-2022 Redistributable (x86)'}

Error message:

parsing "Microsoft Visual C 2015-2022 Redistributable (x86)" - Nested quantifier . At line:1 char:169 ... re-Object { $_.DisplayName -Match 'Microsoft Visual C 2015-2022 Red ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CategoryInfo : OperationStopped: (:) [], ArgumentException FullyQualifiedErrorId : System.ArgumentException*

Edit: Including full script of usage.Here is the script which in cludes updates based on comments.

Start-Transcript -Append c:\Deploy\log.txt
$ProgressPreference = 'SilentlyContinue';
#Change App Name, Source, MSI/EXE, Argument
#Create an array whose elements are hashtables.
$appArray = (
    @{
    App         = ($thisApp = 'Google Chrome')
App_source  = "https://dl.google.com/tag/s/defaultbrowser/edgedl/chrome/install/GoogleChromeStandaloneEnterprise64.msi"
Destination = "C:\Deploy\$thisApp.msi"
Argument    = '/norestart /qn'
  },
  ,
  @{
    App         = ($thisApp = 'Microsoft Visual C   2015-2022 Redistributable (x86)')
    App_source  = "https://aka.ms/vs/17/release/vc_redist.x86.exe"
    Destination = "C:\Deploy\$thisApp.exe"
    Argument    = '/q'
  }
  )


foreach ($app in $appArray) {
  # Note how $app.<key> is used to refer to the entries of the hashtable at hand,
  # e.g. $app.App yields "Firefox" for the first hashtable.
  $installed = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* , HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -and $_.DisplayName.Contains($app.App) }
  $installed.displayname
  if ($installed.displayname -Match $app.App) {
    Write-Host "$($app.App) already installed."
  }
  else {
    if ((Test-Path $app.Destination) -eq $false) {
      New-Item -ItemType File -Path $app.Destination -Force
    }
    #install software
    Invoke-WebRequest $app.App_source -OutFile $app.Destination
    Start-Process -FilePath $app.Destination -ArgumentList $app.Argument -Wait
   #Delete installer
   Remove-Item -Recurse $app.Destination
  }
}
Stop-Transcript

CodePudding user response:

The -match operator is a regular expressions operator, so you'll need to escape any regex meta-characters from the pattern used, preferably using [regex]::Escape():

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall* , HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall* | Where-Object { $_.DisplayName -Match [regex]::Escape('Microsoft Visual C   2015-2022 Redistributable (x86)')}

CodePudding user response:

Complementing Mathias R. Jessen's helpful answer, which solves the problem with the -match operator of your code, there are a few alternatives, which don't require escaping of the search string.

First, you wrote that you won't be able to use wildcards, but I didn't fully understand why. If you want to use the wildcard-less search string somewhere else, you could do something like this:

$searchFor = 'Microsoft Visual C   2015-2022 Redistributable (x86)'

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                 HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
    Where-Object DisplayName -like "*$searchFor*"

# Now use $searchFor somewhere else, without wildcards...

In my opinion this would be the most straightforward way. That being said, you may also use String.Contains():

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                 HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
    Where-Object { $_.DisplayName -and $_.DisplayName.Contains('Microsoft Visual C   2015-2022 Redistributable (x86)') }

The additional check for $_.DisplayName (to be not $null) in the Where-Object script block is necessary because the DisplayName property may not be defined for some of the Uninstall sub keys, which would result in error "You cannot call a method on a null-valued expression".

In PS Core 7.x you could simplify this query using the null-conditional operator:

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* ,
                 HKLM:SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | 
    Where-Object { $_.DisplayName?.Contains('Microsoft Visual C   2015-2022 Redistributable (x86)') }
  • Related