Powershell:查找已安装的防病毒软件,过滤掉Windows Defender

时间:2017-04-13 23:14:37

标签: windows powershell antivirus

所有

我有一个PowerShell脚本,可以检测Windows中安装的防病毒软件(它实际上相当普遍)。问题是,我希望它能过滤Windows Defender,特别是因为安装了Windows 8,8.1和10。我希望我的脚本能够指示Windows Defender是否存在ONLY防病毒软件,如果存在则提供不同的输出。

这是我到目前为止所拥有的......

function Get-AntivirusName { 
[cmdletBinding()]     
param ( 
[string]$ComputerName = "$env:computername" , 
$Credential 
) 
    BEGIN  
        { 
            $wmiQuery = "SELECT * FROM AntiVirusProduct" 
        } 
    PROCESS  
        {    
            $AntivirusProduct = Get-WmiObject -Namespace "root\SecurityCenter2" -Query $wmiQuery  @psboundparameters         
            $AntivirusNames = $AntivirusProduct.displayName       
            if ($AntivirusNames -eq "") {
                Write-host "Anti-Virus is NOT installed!"
            } 
            elseif ($AntivirusNames -eq "Windows Defender") {
                Write-host "ONLY Windows Defender is installed!"
            }
            else {
                Write-host "Anti-Virus is installed (" + $AntivirusNames + ")."
            }

        } 
     END { 
         } 
}

Get-AntivirusName 

结果是,无论安装了哪个其他防病毒软件应用程序,它都会告诉我只安装了Windows Defender。有人可以指出我失踪的东西吗?

提前非常感谢!

3 个答案:

答案 0 :(得分:2)

我会在分配时声明$AntivirusNames是一个数组,然后使用开关循环遍历结果。

function Get-AntivirusName { 
[cmdletBinding()]     
param ( 
[string]$ComputerName = "$env:computername" , 
$Credential 
) 
    BEGIN  
        { 
            $wmiQuery = "SELECT * FROM AntiVirusProduct" 
        } 
    PROCESS  
        {    
            $AntivirusProduct = Get-WmiObject -Namespace "root\SecurityCenter2" -Query $wmiQuery  @psboundparameters         
            [array]$AntivirusNames = $AntivirusProduct.displayName       
            Switch($AntivirusNames) {
                {$AntivirusNames.Count -eq 0}{"Anti-Virus is NOT installed!";Continue}
                {$AntivirusNames.Count -eq 1 -and $_ -eq "Windows Defender"} {"ONLY Windows Defender is installed!";Continue}
                {$_ -ne "Windows Defender"} {"Anti-Virus is installed ($_)."}
           }
} 
     END { 
         } 
}
Get-AntivirusName

这样切换......如果结果为零,则声明没有安装AV。如果有1个结果,并且它是Windows Defender,请声明。否则,如果当前结果不是Windows Defender输出的实际AV是什么。

在旁注中,由于您不允许在参数中添加任何数组,因此您可以跳过BEGININGPROCESS并将所有代码填入END,此时你可以跳过声明所有这些块。

function Get-AntivirusName { 
[cmdletBinding()]     
param ( 
[string]$ComputerName = "$env:computername" , 
$Credential 
) 
    $wmiQuery = "SELECT * FROM AntiVirusProduct" 
    $AntivirusProduct = Get-WmiObject -Namespace "root\SecurityCenter2" -Query $wmiQuery  @psboundparameters         
    [array]$AntivirusNames = $AntivirusProduct.displayName       
    Switch($AntivirusNames) {
        {$AntivirusNames.Count -eq 0}{"Anti-Virus is NOT installed!";Continue}
        {$AntivirusNames.Count -eq 1 -and $_ -eq "Windows Defender"} {Write-host "ONLY Windows Defender is installed!";Continue}
        {$_ -ne "Windows Defender"} {"Anti-Virus is installed ($_)."}
   }
}
Get-AntivirusName

答案 1 :(得分:2)

主要问题是:

List<Integer>

int[]返回单个项目时,$AntivirusProduct = Get-WmiObject ... $AntivirusNames -eq "Windows Defender" 会成为字符串,而Get-WmiObject会测试它是否与文字字符串匹配。

$AntivirusNames返回多个项目时,-eq成为一个数组,Get-WmiObject开始成为过滤器,过滤掉与文字字符串匹配的项目。即如果数组包含“Windows Defender”,它就是。

答案 2 :(得分:1)

我的猜测是它在elseif语句中检查数组的每个元素,所以即使有多个结果也是如此。您可以添加一个只有一个结果的条件,如下所示:

elseif ($AntivirusNames -eq "Windows Defender" -and $AntivirusNames.count -eq 1) {
                Write-host "ONLY Windows Defender is installed!"
            }