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)') }