Manual check if your AV is working

Unfortunately Microsoft System Center Endpoint Protection doesn’t have a very good administration console and as a System Administrator you are forced sometime to do some manual work to make sure everything is working smoothly and all your devices are protected.

Cryptolocker is the latest threat that everyone is fighting against so in order to make sure that out environment is protected in one of those days I’ve created a script to query the SecurityClient namespace that s added on a computer when the SCEP client is installed.

This namespace is hosting all the information you need to know. The same amount of information that the console is displaying when you open Endpoint Protection client.

The logic behind the script was to query a list of all devices from Active Directory and run some standard checks before extracting the information. The standard checks that this script is doing before the query are: check if computer is on-line, check if WMI is not returning any error (TEST-WMI function from the below script which will be dissected in another post) , check if the namespace is present.  If the namespace is not present it will mean that that device doesn’t have an AV client from this vendor.

 

foreach ($server in $ServersList){
    $server = $server.DNSHostName
    $count += 1
	Write-Host "Checking server:   " $server -ForegroundColor Green
    Write-Host "         $count out of:  " $ServersList.Count -ForegroundColor Green
    if (Test-Connection -ComputerName $server -Count 1 -Quiet)  {
    #if (($ping.send($server)).status -eq 'Success') {
        if ((Test-Wmi -computername $server) -eq "OK") { 
           $testNamespace = gwmi -ComputerName $server -Namespace "root\Microsoft\SecurityClient" -list 
                if ($testNamespace) {
                    $InfectionStatus = get-wmiobject -ComputerName $server -query "select * from AntimalwareInfectionStatus" -namespace "root\Microsoft\SecurityClient"|
                                        select @{n='InfectionStatus';e={$_.ComputerStatus}},
                                        PendingReboot,
                                        PendingFullScan,
                                        PendingManualSteps,
                                        PendingOfflineScan
                    $AVDetailes += get-wmiobject -ComputerName $server -query "select * from AntiMalwareHealthStatus" -namespace "root\Microsoft\SecurityClient"|
                                        select @{n='Server';e={$_.__SERVER}},
                                        @{n='DNSName';e={$Server}},
                                        @{n='InfectionStatus';e={$InfectionStatus.InfectionStatus}},
                                        @{n='PendingReboot';e={$InfectionStatus.PendingReboot}},
                                        @{n='PendingFullScan';e={$InfectionStatus.PendingFullScan}},
                                        @{n='PendingManualSteps';e={$InfectionStatus.PendingManualSteps}},
                                        @{n='PendingOfflineScan';e={$InfectionStatus.PendingOfflineScan}},
                                        AntispywareEnabled,
                                        AntispywareSignatureAge,
                                        AntispywareSignatureVersion,
                                        AntivirusSignatureAge,
                                        @{n='AntivirusSignatureUpdateDateTime';e={$_.AntivirusSignatureUpdateDateTime -replace "T.+",""}},
                                        AntivirusSignatureVersion,
                                        BehaviorMonitorEnabled,
                                        Enabled,
                                        EngineVersion,
                                        LastFullScanAge,
                                        @{n='LastFullScanDateTimeEnd';e={$_.LastFullScanDateTimeEnd -replace "T.+",""}},
                                        @{n='LastFullScanDateTimeStart';e={$_.LastFullScanDateTimeStart -replace "T.+",""}},
                                        LastQuickScanAge,
                                        @{n='LastQuickScanDateTimeEnd';e={$_.LastQuickScanDateTimeEnd -replace "T.+",""}},
                                        @{n='LastQuickScanDateTimeStart';e={$_.LastQuickScanDateTimeStart -replace "T.+",""}},
                                        NisEnabled,
                                        NisEngineVersion,
                                        NisSignatureVersion,
                                        OnAccessProtectionEnabled                       
                 }
                 else {
                    $errNameSpaceTmp = New-Object PSObject -Property @{
                    'ServerName' = $Server;
                    'NameSpace/AV' = "Missing"
                    }
                    $errNameSpaceResult += $errNameSpaceTmp
        }
                }
        else { 
            $errWMITmp = New-Object PSObject -Property @{
                    'ServerName' = $Server;
                    'Message' = "WMI Failed"
                    'NameExtractedFromComputer' = $(gwmi -computername (Test-Connection $Server -Count 1 | select IPV4Address).IPV4Address -class Win32_ComputerSystem | select -ExpandProperty Name);
                    }
        $errResult += $errWMITmp    
        }
     }
     else {
			$resultDown = New-Object PSObject -Property @{
				'ComputerName' = $server;
				'Error' = "ServerNotReportingToPing"
			}
            $resultDownResult += $resultDown
	}

}

 

Powershell function to get the server uptime

This function is using just one parameter which is mandatory: computername.

You can run it like this:  Get-ServersUptime -computername MySuperComputer

Function Get-ServersUptime {
	[CmdletBinding()]
    
    Param(
		[Parameter(Mandatory=$true)]
		[string[]]$ComputerName
	)
  
	$now = Get-Date
	
	$result = @()

	#$ComputerName | Foreach-Object {
    foreach ($computer in $ComputerName) {

        Write-Verbose ("Connecting to {0,10}" -f $computer)
        if (Test-Connection -ComputerName $computer -Count 1 -Quiet)  {
			$wmiOS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer -ErrorAction SilentlyContinue
            # if above command threw an error
            if (!$?) {
                Write-Host "Failed to retrieve information from $computer. Is WMI working properly?" -ForegroundColor Red
                
                $result += New-Object PSObject -Property @{
                    'ComputerName' = $computer;
                    'Uptime' = 'WMI not working'
                }
            }
            else {
    			$bootTime = $wmiOS.ConvertToDateTime($wmiOS.LastBootUpTime)
    			$upTime = $now - $bootTime
    			
    			if ($upTime.TotalHours -gt 22) {
    				$result += New-Object PSObject -Property @{
    					'ComputerName' = $computer;
    					'Uptime' = ("{0}:{1,2:00}" -f [int]$upTime.TotalHours, $upTime.Minutes)
    				}			
    			}
            }
		}
		else {
			$result += New-Object PSObject -Property @{
				'ComputerName' = $computer;
				'Uptime' = $false
			}
		}
	}	
	Write-Output $result
}

 

Audit all servers model (physical vs. virtual)

I’ve been asked to to run a query in one of our client environments and extract a list with all servers that are subject to visualization.  The easy way to check which server is virtual and which server is physical is to query the server through WMI class Win32_ComputerSystem and read the Manufacturer and the model of the server.

The query I’ve used was:

$strFilter = "(&(objectCategory=computer)(operatingsystem=*server*))"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher

$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter

$fullList = @();
$report = @();

$colProplist = @(
    "name",
    "enabled"  
)
foreach ($i in $colPropList){
    $objSearcher.PropertiesToLoad.Add($i)
}

$colResults = $objSearcher.FindAll()

foreach ($objResult in $colResults) {
    $objItem = $objResult.Properties;
    $fullList += $objItem.name;
}

$fullList | % {
    if (Test-Connection -ComputerName $_ -Count 1 -ErrorAction 0 {
        $_
        $wmiTemp = gwmi -ComputerName $_ -Class Win32_computerSystem | select Model, Manufacturer
        $report += New-Object PSObject -property @{
            'ServerName' = $_;
            'Model' = $wmiTemp.Model;
            'Manufacturer' = $wmitemp.Manufacturer
        }
    }
}

 

Instead of using IF we can also use TRY and CATCH to catch those servers that are not responding to ping or those servers that are failing the WMI query.

$error.clear()
try { 
    something 
}
catch {
     "Error occured" 
     }
if (!$error) {
    "No Error Occured"
}