Estou procurando uma maneira de descobrir como determinar se um aplicativo de software já está instalado. Vi algumas maneiras pelas quais as pessoas fizeram isso para dependências de software, mas isso não atende exatamente ao que preciso. Estou usando o Get-WmiObject
Powershell. Aqui esta o meu codigo ate agora:
#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
}
Acredito que tenho um problema de formatação e é por isso que minha instrução if else não está funcionando corretamente.
EDIT: Quando o Sophos está presente, a instrução if ignora o else. Acredito que o problema seja como Get-WmiObject
está a formatação da saída para uma variável. Ele produz atualmente como:
Name
----
Sophos Endpoint
O que então falha na lógica da instrução if. Eu preciso do Get-WmiObject
comando apenas para gerar o Sophos Endpoint na Variable $MyApp
.
Responder1
Acredito que tenho um problema de formatação e é por isso que minha instrução if else não está funcionando corretamente.
Na verdade, você tem um problema de programação do PowerShell. O conteúdo da sua variável é na verdade o texto citado abaixo, que não é equivalente a "Sophos Endpoint".
Name ---- Sophos Endpoint
A afirmação a seguir é verdadeira para operadores de igualdade. Basicamente, seu script estava fazendo exatamente o que deveria, já que os valores de entrada não eram idênticos entre si.
Os operadores de igualdade (-eq, -ne) retornam um valor TRUE ou as correspondências quando um ou mais valores de entrada são idênticos ao padrão especificado. O padrão inteiro deve corresponder a um valor inteiro.
Fonte:Operadores de Igualdade
O script a seguir gerará o valor da variável e a mensagem de depuração se uma correspondência com a expressão regular for encontrada. Caso contrário, apenas gerará uma mensagem de depuração.
#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."
}
Responder2
Get-Object
retorna um objeto, não uma string.
A string que você deseja é o .Name
atributo do qual fará parte $MyApp
(já que você o atribuiu na saída de Get-Object
).
Isso deve funcionar:
if ($MyApp.Name -eq "Sophos Endpoint"){`
Responder3
Outra maneira de fazer o que você deseja é ler as informações do produto no registro
Eu uso a seguinte função para isso (veja abaixo)
você poderia simplesmente fazer:
$isInstalled = Get-AppVersion "Sophos Endpoint"
if(!$isInstalled) { .\SophosSetup.exe --products=antivirus,intercept --quiet }
A função também pode lidar com pesquisas RemoteComputers e Wildcard, se você não tiver certeza de como o produto é chamado. Você também pode dizer quais propriedades deseja que sejam devolvidas
A função:
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
}
Aqui estão alguns exemplos de resultados:
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>