Monitoring with PowerShell: Monitoring Bitdefender status

We’re considering moving RMM systems, and that means reevaluating parts of our stack. One of the pain points in our current stack is the monitoring of anti-virus, we often felt like there is not enough transparency and data returned via our RMM system. Either the system does not return the current state of alerts or forces us to use separate portals.

So I’ve built this for any potential RMM system, decreasing the need to switch a lot between applications, get alerted earlier and allow reporting directly from the RMM system on any threats you’ve encountered.

Quarantine monitoring

To monitor the quarantine we grab the information from the SQLLite Database that Bitdefender creates. To do that we’ll need to download the SQLLite dll that allows us access via Powershell. Remember to host this yourself somewhere. 🙂

if (!$SQLLite) {
    Invoke-WebRequest -uri "https://cyberdrain.com/wp-content/uploads/2021/02/System.Data.SQLite.dll" -UseBasicParsing -OutFile "C:\Programdata\System.Data.SQLite.dll"
}

try {
add-type -path "C:\Programdata\System.Data.SQLite.dll"
}
catch {
Write-Host "Could not load database components."
exit 1
}
$con = New-Object -TypeName System.Data.SQLite.SQLiteConnection
$con.ConnectionString = "Data Source=C:\Program Files\Bitdefender\Endpoint Security\Quarantine\cache.db"
$con.Open()
$sql = $con.CreateCommand()
$sql.CommandText = "select \* from entries"
$adapter = New-Object -TypeName System.Data.SQLite.SQLiteDataAdapter $sql
$data = New-Object System.Data.DataSet
[void]$adapter.Fill($data)
$sql.Dispose()
$con.Close()

$CurrentQ = foreach ($row in $Data.Tables.rows) {
    [PSCustomObject]@{
        Path               = $row.path
        Threat             = $row.threat
        Size               = $row.Size
        'Quarantined On'   = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($row.quartime))
'Last accessed On' = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($row.acctime))
        'Last Modified On' = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($row.modtime))
}
}

if ($CurrentQ) {
write-host $CurrentQ
}
else {
write-host "Healthy - No infections found."
}

Scan Result monitoring

Of course just monitoring the quarantine is not enough, we also want to know the results of each scan and pick that up, For that we have the next script; this checks the last scan XML file for any aberrant behaviour such as infected files or deleted ones.

[xml]$LastScanResult = (get-childitem "C:\Program Files\Bitdefender\Endpoint Security\logs\system" -Recurse -Filter "*.xml" | Sort-Object -Property LastWriteTime | Select-Object -last 1 | get-content -raw)

if (!$LastScanResult) {
    write-host "Unhealthy - could not retrieve last scan result."
    exit 1
}
$ScanResults = [PSCustomObject]@{
    Scanned       = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.Scanned | measure-object -sum).Sum
    Infected      = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.Infected | measure-object -sum).Sum
    suspicious    = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.suspicious | measure-object -sum).Sum
    Disinfected   = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.Disinfected | measure-object -sum).Sum
    Deleted       = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.deleted | measure-object -sum).Sum
    Moved         = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.moved | measure-object -sum).Sum
    Moved_reboot  = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.moved_reboot | measure-object -sum).Sum
    Delete_reboot = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.delete_reboot | measure-object -sum).Sum
    Renamed       = ($LastScanResult.ScanSession.ScanSummary.TypeSummary.renamed | measure-object -sum).Sum
}

$Alertresult = $ScanResults | Select-Object -Property * -ExcludeProperty Scanned | Where-Object { $_.psobject.properties.value -gt 0 }

if ($Alertresult) {
    write-host "Unhealthy - Last scan found issues"
    $ScanResults
}
else {
    write-host "Healthy - Last scan found no issues."
    $ScanResults
}

And that’s it! as always, Happy PowerShelling!

Recent Articles

The return of CyberDrain CTF

CyberDrain CTF returns! (and so do I!)

It’s been since september that I actually picked up a digital pen equivalent and wrote anything down. This was due to me being busy with life but also my side projects like CIPP. I’m trying to get back into the game of scripting and blogging about these scripts. There’s still so much to automate and so little time, right? ;)

Monitoring with PowerShell: Monitoring Acronis Backups

Intro

This is a monitoring script requested via Reddit, One of the reddit r/msp users wondered how they can monitor Acronis a little bit easier. I jumped on this because it happened pretty much at the same time that I was asked to speak at the Acronis CyberSummit so it kinda made sense to script this so I have something to demonstrate at my session there.

Monitoring with PowerShell: Monitoring VSS Snapshots

Intro

Wow! It’s been a while since I’ve blogged. I’ve just been so swamped with CIPP that I’ve just let the blogging go entirely. It’s a shame because I think out of all my hobbies it’s one I enjoy the most. It’s always nice helping others achieve their scripting target. I even got a couple of LinkedIn questions asking if I was done with blogging but I’m not. Writing always gives me some more piece of mind so I’ll try to catch up again. I know I’ve said that before but this time I’ll follow through. I’m sitting down right now and scheduling the release of 5 blogs in one go. No more whining and no more waiting.