## Client monitoring examples

The following snippets illustrate some of the details of client monitoring. They are written in Windows PowerShell, but can be converted to VisualBasic or any other language that you prefer.

Infected and at risk states are held in variables to make it easier to illustrate recommended roll-up calculations.

Note: | All threshold values are recommendations only. You can adjust these values to fit the standards of your platform.

See Monitoring client state and activity.

State of individual client

Client Software Version, or Not Installed

The version of the client software that is installed on the endpoint, or if the software is not installed. Note that only a successful return of the first check indicates a client that fully supports remote monitoring.

    #checks first for the version that fully supports remote monitoring
    #then checks for previous version
    #if both the above checks fail, returns "Not installed"
    #$ErrorActionPreference setting is required by PowerShell to catch non-terminating errors

    $isInstalled = ""
    $ErrorActionPreference = "Stop"

    try
        {
            $isInstalled = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-Opstate\" DeployRunningVersion).DeployRunningVersion
        }
            catch
                {
                    try
                        {
                            $isInstalled = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\
    Symantec Endpoint Protection\SMC\SYLINK\SyLink\OpState\" DeployRunningVersion).DeployRunningVersion
                        }
                    catch
                        {
                            $isInstalled = "Not installed"
                        }
                }
    $isInstalled

    #Returns the four-part version number of the Symantec Endpoint Protection client
    #software installed on the endpoint, or "Not installed"
    #Example version number: 12.1.1047.347

Infected State

Client is infected with one or more threats detected by Virus and Spyware protection. This state is also useful as a roll-up.

    $isInfected = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-OpState" Infected).Infected
    $isInfected

    #Returns 0 == not infected
    #Returns 1 == infected

    #Note that this script throws an error (location not found) if no scan has been run on the client.
    #The registry key is not created until a scan is run.

Content Status

Whether virus definitions and other product content are up-to-date or out-of-date on the client

    $defsDate = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-OpState\" LatestVirusDefsDate).LatestVirusDefsDate

    #Returns the date in UTC format of the most recent virus definitions file on the client
    #for content status, we must perform additional calculations.
    #AddDays parameter value of 3 is recommended, but can be adjusted

    $contentStatus = (Get-Date).AddDays(-3)-lt $defsDate
    $contentStatus

    #Returns True == content status is up-to-date
    #Returns False == content status is out-of-date

Protection Status

Whether protection components on the client have been disabled. Administrators can let client users disable protection temporarily, typically to allow downloads or to prevent scans from interfering with performance. This state is also useful as a roll-up, to monitor endpoint risk. However, it is typically not a status that indicates high risk. By default, policies on the management server re-enable protection after short intervals.

    $AVEnabled = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-Opstate\" AVRunningStatus).AVRunningStatus
    $FWEnabled = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-Opstate\" FWRunningStatus).FWRunningStatus
    $isEnabled = (If (($AVEnabled -eq 1) -or ($FWEnabled -eq 1)) {write-host "False"} Else {write-host "True"})
    $isEnabled

    #Returns True == client protection is enabled
    #Returns False == client protection is disabled

    #if you prefer, you can report on these two states separately (AVRunningStatus and FWRunningStatus).

Last Scan Time

The last time that a scan was successfully completed on the client.

    (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-Opstate\" LastSuccessfulScanDateTime).LastSuccessfulScanDateTime

    #Note that this query succeeds only if a scan has been run on the client. The default policy
    #for a managed client specifies that a scan is run only after new content definitions are downloaded.
    #There is a setting to run an active scan (shorter than a full scan) on startup, but this setting
    #is disabled by default in the policy and on the client.

You can also report on whether the last scan failed. The -newest argument should be adjusted depending on your individual environment. Note that -newest filters only the log, not the piped filter. We provide two examples.

    #The following snippet assumes minimal client logging and scanning approximately once a day.
    #It is reliable only if there is only one eventID 2 in the most recent 10 events.
    (Get-EventLog "Symantec Endpoint Protection Client" -newest 10 | Where-Object {$_.EventID -eq 21}).TimeWritten

    #The following snippet covers most likely client monitoring scenarios.
    #It gets more than sufficient recent events and then selects only the most recent object in the array.
    (Get-EventLog "Symantec Endpoint Protection Client" -newest 100 | Where-Object {$_.EventID -eq 21}
    | Select-Object -index 0).TimeWritten

    #You can also check for the last successful scan on the client by monitoring the event log.
    #Run a query similar to the query for failed scan, but where {$_.EventID -eq 2}.

Checking in with Server

Whether the client is communicating with the management server. If the client is not communicating (EventID 101 is returned), the state does not necessarily indicate high risk, particularly in the case of roaming laptops. This state is also useful as a roll-up, to monitor endpoint risk.

    $isConnected = (Get-EventLog "Symantec Endpoint Protection Client" -newest 200
    | Where-Object {$_.Category -eq "Connectivity"} | Select-Object -index 0).EventID
    $isConnected

    #Returns 100 == The client is communicating with the management server
    #Returns 101 == The client cannot communicate with the management server

Managed by

Whether the client is managed by the management server, or is self-managed (managed by the end user). This state is also useful as a roll-up, to monitor endpoint risk. However, risk assessment depends on the management environment and the overall individual endpoint status.

    $isManaged = (Get-ItemProperty "HKLM:\SOFTWARE\Symantec\Symantec Endpoint Protection\
    CurrentVersion\Public-Opstate\" LastServerIP).LastServerIP
    $isManaged

    #Returns IP address == client is managed by server
    #Throws script error (location not found) == client is self-managed

Summary state of groups of clients (roll-up reports)

Some individual client states can be rolled up as-is, but for useful summary reporting on a network, you may find the following snippets helpful. All variables are defined in the individual state calculations provided above.

Healthy endpoints

Endpoints that are both not infected and up-to-date. Monitors only endpoints that are online.

    $isInfected = 0 AND $contentStatus = "True"

Out-of-date endpoints

This calculation is slightly different from the script for an individual out-of-date endpoint, because we recommend that you report endpoints that are both out-of-date and infected under an Infected roll-up.

    $contentStatus = "False" AND $isInfected = 0

At risk endpoints

Rolls up the total number of endpoints that are out-of-date, disabled, self-managed, or without protection installed. An endpoint can report more than one at-risk issue. This means that the total number of individual at-risk states does not necessarily equal the total number of at risk endpoints.

    ($contentStatus = "False" AND $isInfected = 0)
     OR
     $isEnabled = "False"
     OR
     $isManaged = error
     OR
     $isInstalled = error