Skip to content

Win_Antivirus_Verify.ps1 may falsly detect AV as disabled or not up to date if multipe instances of the same AV are installed. #268

@SpookOz

Description

@SpookOz

I've found that often when an AV updates itself, it leaves the old instance in the the security center. So often there are 2 instances with the same name displayName, pathToSignedProductExe and pathToSignedReportingExe but different instanceGuid. In these cases, this script seems to occassionally report one instance as being active, but the other as having updated defs. Therefor, it gives an error saying "There do not seem to be any active and / or up-to-date Antivirus! Please check the installed AV for issues."

May I propose an alternative script that combines instances with the same displayName and pulls the status from both?

# Ensure OS Build supports SecurityCenter2
if ([environment]::OSVersion.Version.Build -le 14393) {
    Write-Host "Antivirus check not supported on this OS. Exiting."
    exit 2
}

# Define Product State Flags
[Flags()] enum ProductState {
    Off = 0x0000
    On = 0x1000
    Snoozed = 0x2000
    Expired = 0x3000
}

[Flags()] enum SignatureStatus {
    UpToDate = 0x00
    OutOfDate = 0x10
}

[Flags()] enum ProductFlags {
    SignatureStatus = 0x000000F0
    ProductState = 0x0000F000
}

# Fetch installed AV products
$antivirusProducts = Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

if (-not $antivirusProducts) {
    Write-Host "No antivirus detected in SecurityCenter2! Please verify manually."
    exit 1
}

# Group AVs by displayName
$groupedAVs = $antivirusProducts | Group-Object -Property displayName

# Initialize AV status check
$avFound = $false
$avResults = @()

foreach ($group in $groupedAVs) {
    $avName = $group.Name
    $instances = $group.Group

    # Initialize merged status
    $isEnabled = $false
    $isUpToDate = $false

    $avOutput = "`n$avName"

    foreach ($av in $instances) {
        $productState = $av.productState

        # Extract "Status" (Enabled/Disabled) using bitwise AND
        $currentState = [ProductState]($productState -band [ProductFlags]::ProductState)
        $currentStatus = if ($currentState -eq [ProductState]::On) { "Enabled" } else { "Disabled" }

        # Extract "Definition Status" using bitwise AND
        $currentSignatureStatus = [SignatureStatus]($productState -band [ProductFlags]::SignatureStatus)
        $currentDefinitionStatus = if ($currentSignatureStatus -eq [SignatureStatus]::UpToDate) { "UpToDate" } else { "OutOfDate" }

        # Merge instances: AV is considered "Enabled" if any instance is enabled
        if ($currentStatus -eq "Enabled") {
            $isEnabled = $true
        }

        # Merge instances: AV is considered "UpToDate" if any instance is up to date
        if ($currentDefinitionStatus -eq "UpToDate") {
            $isUpToDate = $true
        }
    }

    # Final decision for this AV
    $finalStatus = if ($isEnabled) { "Enabled" } else { "Disabled" }
    $finalDefinitionStatus = if ($isUpToDate) { "UpToDate" } else { "OutOfDate" }

    $avOutput += "`n  - Status: $finalStatus"
    $avOutput += "`n  - Definitions: $finalDefinitionStatus"

    # Check if AV is enabled and up-to-date
    if ($finalStatus -eq "Enabled" -and $finalDefinitionStatus -eq "UpToDate") {
        $avFound = $true
    }

    # Store the AV results to display later
    $avResults += $avOutput
}

# Print summary message first
if ($avFound) {
    Write-Host "At least one antivirus is enabled and up-to-date."
} else {
    Write-Host "No active and up-to-date antivirus detected! Please check your AV software."
}

# Print the detailed AV results
$avResults | ForEach-Object { Write-Host $_ }

# Exit with appropriate status code
if (-not $avFound) {
    exit 1
}

exit 0  # Success

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions