当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 获取防病毒产品状态

作者:精品下载站 日期:2024-12-14 07:49:59 浏览:17 分类:玩电脑

使用 PowerShell 获取防病毒产品状态


我预计大多数安装了企业级防病毒软件的人可能都有供应商工具来管理所有客户端。如果是这样,请先不要离开。尽管我将演示如何使用 PowerShell 获取防病毒产品状态,但脚本技术可能仍然有用。或者您可能会更多地了解 WMI 和 CIM cmdlet。让我从一个简单的命令开始,假设您正在运行 PowerShell 3.0 或更高版本,则可以从本地计算机获取防病毒信息。

尝试这个命令:

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

在早期版本的 Windows 中,此信息存储在 SecurityCenter 命名空间中。我不记得具体是哪个版本的 Windows 更改为 SecurityCenter2,但希望这对您有用,并且您会看到类似这样的内容:

[玩转系统] 使用 PowerShell 获取防病毒产品状态

在我运行 Windows 8.1 的计算机上,您可以看到两个产品。你无法分辨的是每个产品的状态。好吧,实际上你可以,但你需要解码产品状态属性。解码它的第一步是将其转换为十六进制。

'0x{0:x}' -f 393472

我将 Windows Defender 状态转换为值 0x60100。

接下来,我们可以查看该值的中间两个部分 01。如果它与“10”匹配,则该产品已启用。别的什么也不是。这样,我可以看到 Windows Defender 未启用。最后 2 部分 00 将指示产品是否是最新的。值 00 表示它是最新的。但是,在这种情况下,我认为这意味着该产品上次启用时是最新的。我认为这就是 TimeStamp 属性派上用场的地方。转换 ESET 产品上的状态给我一个值 0x41000,该值解码为已启用且最新。

一旦有了基本命令,我就可以构建一个 PowerShell 函数,将其变成可重用的工具。

Get-AVStatus.ps1:

#requires -version 5.1

Function Get-AVStatus {

 Get-AVStatus chi-win10

Displayname  : ESET NOD32 Antivirus 9.0.386.0
ProductState : 266256
Enabled      : True
UpToDate     : True
Path         : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe
Timestamp    : Thu, 21 Jul 2016 15:20:18 GMT
Computername : CHI-WIN10

.Example
PS C:\>  import-csv s:\computers.csv | Get-AVStatus -All | Group Displayname | Select Name,Count | Sort Count,Name

Name                           Count
----                           -----
ESET NOD32 Antivirus 9.0.386.0    12
ESET Endpoint Security 5.0         6
Windows Defender                   4
360 Total Security                 1

Import a CSV file which includes a Computername heading. The imported objects are piped to this command. The results are sent to Group-Object.

.Example
PS C:\> $cs | Get-AVStatus | where {-Not $_.UptoDate}

Displayname  : ESET NOD32 Antivirus 9.0.386.0
ProductState : 266256
Enabled      : True
UpToDate     : False
Path         : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe
Timestamp    : Wed, 20 Jul 2016 11:10:13 GMT
Computername : CHI-WIN11

Displayname  : ESET NOD32 Antivirus 9.0.386.0
ProductState : 266256
Enabled      : True
UpToDate     : False
Path         : C:\Program Files\ESET\ESET NOD32 Antivirus\ecmd.exe
Timestamp    : Thu, 07 Jul 2016 15:15:26 GMT
Computername : CHI-WIN81

You can also pipe CIMSession objects. In this example, the output are enabled products that are not up to date.
.Notes
version: 1.1

Learn more about PowerShell:
http://jdhitsolutions.com/blog/essential-powershell-resources/

.Inputs
[string[]]
[Microsoft.Management.Infrastructure.CimSession[]]

.Outputs
[pscustomboject]

.Link
Get-CimInstance
#>

    [cmdletbinding(DefaultParameterSetName = "computer")]

    Param(
        #The name of a computer to query.
        [Parameter(
            Position = 0,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = "computer"
            )]
        [ValidateNotNullorEmpty()]
        [string[]]$Computername = $env:COMPUTERNAME,

        #An existing CIMsession.
        [Parameter(ValueFromPipeline, ParameterSetName = "session")]
        [Microsoft.Management.Infrastructure.CimSession[]]$CimSession,

        #The default is enabled products only.
        [switch]$All
    )

    Begin {
        Write-Verbose "[BEGIN  ] Starting: $($MyInvocation.Mycommand)"

        Function ConvertTo-Hex {
            Param([int]$Number)
            '0x{0:x}' -f $Number
        }

        #initialize an hashtable of paramters to splat to Get-CimInstance
        $cimParams = @{
            Namespace   = "root/SecurityCenter2"
            ClassName   = "Antivirusproduct"
            ErrorAction = "Stop"
        }

        If ($All) {
            Write-Verbose "[BEGIN  ] Getting all AV products"
        }

        $results = @()
    } #begin

    Process {

        #initialize an empty array to hold results
        $AV = @()

        Write-Verbose "[PROCESS] Using parameter set: $($pscmdlet.ParameterSetName)"
        Write-Verbose "[PROCESS] PSBoundparameters: "
        Write-Verbose ($PSBoundParameters | Out-String)

        if ($pscmdlet.ParameterSetName -eq 'computer') {
            foreach ($computer in $Computername) {

                Write-Verbose "[PROCESS] Querying $($computer.ToUpper())"
                $cimParams.ComputerName = $computer
                Try {
                    $AV += Get-CimInstance @CimParams
                }
                Catch {
                    Write-Warning "[$($computer.ToUpper())] $($_.Exception.Message)"
                    $cimParams.ComputerName = $null
                }

            } #foreach computer
        }
        else {
            foreach ($session in $CimSession) {

                Write-Verbose "[PROCESS] Using session $($session.computername.toUpper())"
                $cimParams.CimSession = $session
                Try {
                    $AV += Get-CimInstance @CimParams
                }
                Catch {
                    Write-Warning "[$($session.computername.ToUpper())] $($_.Exception.Message)"
                    $cimParams.cimsession = $null
                }

            } #foreach computer
        }

        foreach ($item in $AV) {
            Write-Verbose "[PROCESS] Found $($item.Displayname)"
            $hx = ConvertTo-Hex $item.ProductState
            $mid = $hx.Substring(3, 2)
            if ($mid -match "00|01") {
                $Enabled = $False
            }
            else {
                $Enabled = $True
            }
            $end = $hx.Substring(5)
            if ($end -eq "00") {
                $UpToDate = $True
            }
            else {
                $UpToDate = $False
            }

            $results += $item | Select-Object Displayname, ProductState,
            @{Name = "Enabled"; Expression = { $Enabled } },
            @{Name = "UpToDate"; Expression = { $UptoDate } },
            @{Name = "Path"; Expression = { $_.pathToSignedProductExe } },
            Timestamp,
            @{Name = "Computername"; Expression = { $_.PSComputername.toUpper() } }

        } #foreach

    } #process

    End {
        If ($All) {
            $results
        }
        else {
            #filter for enabled only
            ($results).Where( { $_.enabled })
        }

        Write-Verbose "[END    ] Ending: $($MyInvocation.Mycommand)"
    } #end

} #end function

因为该函数使用 Get-CimInstance,所以我编写它是为了支持计算机名称和 CIMSessions 作为参数值或通过管道。您会注意到,我使用了多个参数集从 WMI 收集“原始”防病毒产品信息,并使用反映 ProductState 解码的自定义属性对其进行格式化。在函数结束时,结果被写入管道。默认情况下,仅显示启用的产品,因为我认为这会更有用。但您可以使用 -All 参数查看所有内容。

以下是该命令的一些实际操作的屏幕截图。

[玩转系统] 使用 PowerShell 获取防病毒产品状态

[玩转系统] 使用 PowerShell 获取防病毒产品状态

[玩转系统] 使用 PowerShell 获取防病毒产品状态

最后,当我从事这项工作时,我偶然发现了一个我不知道的 PowerShell“功能”。

对于像这样的独立函数,我总是编写基于注释的帮助。我通常为每个参数包含一个参数部分。最初,我没有,尽管在代码中我向其中一个参数添加了注释。

#The default is enabled products only.
[switch]$All

当我运行完整帮助时,我惊讶地看到了这段文字。

[玩转系统] 使用 PowerShell 获取防病毒产品状态

惊人的!!我为 Param 块中的其他参数添加了类似的注释。我想如果我想提供广泛的参数信息,我会使用基于注释的帮助中的 .Parameter 部分。但由于通常我只需要一个快速描述,将其放在 Param 块中会让事情变得更容易。

就是这样。一个相对简单的 PowerShell 功能,使用 WMI 和 CIM 从远程计算机检索信息。您可以将它用作几乎任何 WMI 类的框架。您需要做的就是修改命名空间、类名和输出属性。事实上,这给了我一个想法,但这必须等到另一天。

如果您遇到该函数的任何问题,请在 GitHub gist 上发表评论。

享受。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯