Я ищу способ выяснить, как определить, установлено ли уже программное приложение. Я видел несколько способов, которыми люди делали это для Software Dependencies, но это не совсем то, что мне нужно. Я использую Get-WmiObject
в Powershell. Вот мой код на данный момент:
#Check for Sophos
$MyApp = Get-WmiObject -Class Win32_Product | sort-object Name | select Name | where { $_.Name -eq "Sophos Endpoint"}
#Logic To Install or Skip
if ($MyApp -eq "Sophos Endpoint"){
Write-Output "Sophos Endpoint is already installed on this computer."
}
else{
Write-Output "Sophos Endpoint will be installed quietly in the background"
#Install Sophos
SophosSetup.exe --products=antivirus,intercept --quiet
}
Я считаю, что у меня проблема с форматированием, из-за которой мой оператор if else работает неправильно.
EDIT: Когда присутствует Sophos, оператор if пропускает else. Я считаю, что проблема в том, как Get-WmiObject
форматировать вывод в переменную. В настоящее время он выводит как:
Name
----
Sophos Endpoint
Что затем терпит неудачу в логике оператора if. Мне нужна команда, Get-WmiObject
чтобы просто вывести Sophos Endpoint в переменную $MyApp
.
решение1
Я считаю, что у меня проблема с форматированием, из-за которой мой оператор if else работает неправильно.
У вас на самом деле проблема с программированием PowerShell. Содержимое вашей переменной на самом деле является цитируемым текстом ниже, который не эквивалентен "Sophos Endpoint".
Name ---- Sophos Endpoint
Следующее утверждение верно для операторов равенства. По сути, ваш скрипт делал именно то, что и должен был делать, поскольку входные значения не были идентичны друг другу.
Операторы равенства (-eq, -ne) возвращают значение ИСТИНА или совпадения, когда одно или несколько входных значений идентичны указанному шаблону. Весь шаблон должен соответствовать целому значению.
Источник:Операторы равенства
Следующий скрипт выведет значение переменной и отладочное сообщение, если будет найдено соответствие регулярному выражению. В противном случае он выведет только отладочное сообщение.
#Check for Sophos
$MyApp = Get-WmiObject -Class Win32_Product | sort-object Name | select Name | where { $_.Name -match "WinZip 24.0"}
if ($MyApp -match "WinZip 24.0")
{
Write-Output $MyApp.Name
Write-Output "WinZip is already installed on this computer."
}
else
{
Write-Output "WinZip is already installed on this computer."
}
решение2
Get-Object
возвращает объект, а не строку.
Нужная вам строка — это .Name
атрибут, который будет частью $MyApp
(поскольку вы назначили его из вывода Get-Object
).
Это должно сработать:
if ($MyApp.Name -eq "Sophos Endpoint"){`
решение3
Другой способ сделать то, что вам нужно, — прочитать информацию о продукте из реестра.
Для этого я использую следующую функцию (см. ниже)
Тогда вы могли бы просто сделать:
$isInstalled = Get-AppVersion "Sophos Endpoint"
if(!$isInstalled) { .\SophosSetup.exe --products=antivirus,intercept --quiet }
Функция также может обрабатывать RemoteComputers и Wildcard search, если вы не совсем уверены, как называется продукт. Вы также можете указать ей, какие свойства вы хотите получить обратно
Функция:
function Get-AppVersion {
param (
[Parameter(Position = 0)]
[string]$filter = '*',
[string[]]$properties = @("DisplayName", "DisplayVersion", "InstallDate"),
[string[]]$ComputerName
)
$regpath = @(
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
$sb = {
param ( $regpath, $filter, $properties )
$regpath | ForEach-Object { Get-ItemProperty $_ } |
Where-Object { $_.DisplayName -ne $null -and $_.DisplayName -like $filter } |
Select-Object $properties
}
$splat = @{}
if ($ComputerName) { $splat['ComputerName'] = $ComputerName }
Invoke-Command -ScriptBlock $sb -ArgumentList $regpath, $filter, $properties @splat
}
Вот несколько примеров выводов:
PS Z:\Powershell-Scripts> Get-AppVersion SwyxIt!
DisplayName DisplayVersion InstallDate
----------- -------------- -----------
SwyxIt! 11.32.3220.0 20181123
PS Z:\Powershell-Scripts> Get-AppVersion *swyx*
DisplayName DisplayVersion InstallDate
----------- -------------- -----------
SwyxIt! 11.32.3220.0 20181123
PS Z:\Powershell-Scripts> Get-AppVersion *swyx* -ComputerName RS
DisplayName : SwyxIt!
DisplayVersion : 11.32.3220.0
InstallDate : 20181129
PSComputerName : RS
RunspaceId : ed097948-c722-4235-aa64-9b0045c5478f
PS Z:\Powershell-Scripts> Get-AppVersion dkgfmnslkf
PS Z:\Powershell-Scripts> Get-AppVersion *swyx* -properties *
AuthorizedCDFPrefix :
Comments : SwyxIt! macht aus Ihrem PC ein komfortables und leicht zu nutzendes Telefon.
Contact :
DisplayVersion : 11.32.3220.0
HelpLink :
HelpTelephone :
InstallDate : 20181123
InstallLocation : C:\Program Files (x86)\SwyxIt!\
InstallSource : Z:\Software\q-z\Swyx\SwyxWare 11.32.0.0\SwyxIt!\x64\Deutsch\
ModifyPath : MsiExec.exe /I{1BA548A7-D32F-4D06-B9A9-451947814967}
Publisher : Swyx Solutions GmbH
Readme : C:\Program Files (x86)\SwyxIt!\Readme.rtf
Size :
EstimatedSize : 318937
UninstallString : MsiExec.exe /I{1BA548A7-D32F-4D06-B9A9-451947814967}
URLInfoAbout :
URLUpdateInfo : http://www.swyx.de/support/update.html?product=SwyxIt!&version=11.32.3220.0&language=1031
VersionMajor : 11
VersionMinor : 32
WindowsInstaller : 1
Version : 186649748
Language : 1031
DisplayName : SwyxIt!
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\{1BA548A7-D32F-4D06-B9A9-451947814967}
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
PSChildName : {1BA548A7-D32F-4D06-B9A9-451947814967}
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
PS Z:\Powershell-Scripts>