Collects information about Antimalware for the Antimalware Intelligence Pack

CollectAntiMalwareInformation (Rule)

Element properties:

TargetMicrosoft.Windows.Computer
CategoryCustom
EnabledFalse
Alert GenerateFalse
RemotableFalse

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource TimedPowershellPropertyBagProvider Default
WA2 WriteAction Microsoft.SystemCenter.AntiMalwareInformationDataWriteAction Default

Source Code:

<Rule ID="CollectAntiMalwareInformation" Enabled="false" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="false">
<Category>Custom</Category>
<DataSources>
<DataSource ID="DS" TypeID="TimedPowershellPropertyBagProvider">
<IntervalSeconds>3600</IntervalSeconds>
<SyncTime/>
<ScriptName>CollectLastUpdateTime</ScriptName>
<ScriptBody><Script>

Param(
[parameter(Mandatory=$false, ValueFromPipeline=$true)]
[string]$logfile = "$env:windir\debug\mrt.log",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$showCount = "false",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$retryTimeInSeconds = 10
)

&lt;#
Defines Protection and Threat Status Codes. Implement general Add-MalwareScan function for all modules.
#&gt;

$global:malwareScans = @();

#region Protection Status Codes and Rankings
$ThreatDetectedProtectionCode = @( 550, "Threat Detected" )
$UnknownProtectionCode = @( 470, "Unknown" )
$NotReportingProtectionCode = @( 450, "Not Reporting" )
$ActionRequiredProtectionCode = @( 350, "Action Required" )
$NoRealTimeProtectionProtectionCode = @( 270, "No real time protection" )
$SignaturesOutOfDateProtectionCode = @( 250, "Signatures out of date" )
$RealTimeProtectionCode = @( 150, "Real time protection" )
#endregion

#region Threat Status Codes and Rankings
$ActiveThreatCode = @( 550, "Active" )
$UnknownThreatCode = @( 470, "Unknown" )
$RemediatedThreatThreatCode = @( 370, "Remediated" )
$QuarantinedThreatCode = @( 350, "Quarantined" )
$BlockedThreatCode = @( 330, "Blocked" )
$AllowedThreatCode = @( 250, "Allowed" )
$NoThreatsDetectedThreatCode = @( 150, "No threats detected" )
#endregion

function Add-MalwareScan {
param(
$ProtectionRank,
$ProtectionStatus,
$ProtectionStatusDetails,
$DetectionId,
$Threat,
$ThreatStatusRank,
$ThreatStatus,
$ThreatStatusDetails,
$Signature,
$ScanDate,
$DateCollected,
$ToolName
)
try {
$scanDateInt = $ScanDate.ToUniversalTime().ToString("G", [System.Globalization.CultureInfo]::InvariantCulture);
} catch {
$scanDateInt = $ScanDate;
}

try {
$dateCollectedInt = $DateCollected.ToUniversalTime().ToString("G", [System.Globalization.CultureInfo]::InvariantCulture);
} catch {
$dateCollectedInt = $DateCollected;
}

$malware_scan = @{};
$malware_scan.ProtectionStatusRank = $ProtectionRank;
$malware_scan.ProtectionStatus = $ProtectionStatus;
$malware_scan.ProtectionStatusDetails = $ProtectionStatusDetails;
$malware_scan.DetectionId = $DetectionId;
$malware_scan.Threat = $Threat;
$malware_scan.ThreatStatusRank = $ThreatStatusRank;
$malware_scan.ThreatStatus = $ThreatStatus;
$malware_scan.ThreatStatusDetails = $ThreatStatusDetails;
$malware_scan.Signature = $Signature;
$malware_scan.Tool = $ToolName;
$malware_scan.ScanDate = $scanDateInt
$malware_scan.DateCollected = $dateCollectedInt
$global:malwareScans += $malware_scan;
} # Contains general definision and
&lt;#
Extracts Anti-Malware information via Microsoft AM Engine PowerShell commands.
Two sets of commands are supported: Defender &amp; SCEP.
#&gt;

$global:msRetryTimeoutInSeconds = 10;
$global:msTimeWindowInHours = 24;
$global:msMpModuleCommands = $null

Function Scan-ComputerStatus
{
Param(
[parameter(Mandatory=$true, ValueFromPipeline=$false)]
[PSObject]$mpModuleCommands,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$retryTimeoutInSeconds = 10,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24
)

$global:msRetryTimeoutInSeconds = $retryTimeoutInSeconds;
$global:msTimeWindowInHours = $timeWindowInHours;
$global:msMpModuleCommands = $mpModuleCommands;

$ThreatStatusFromStatusCode = @{
"0" = $UnknownThreatCode, "Unknown";
"1" = $ActiveThreatCode, "Detected";
"2" = $RemediatedThreatThreatCode, "Cleaned";
"3" = $QuarantinedThreatCode, "Quarantined";
"4" = $RemediatedThreatThreatCode, "Removed";
"5" = $AllowedThreatCode, "Allowed";
"6" = $BlockedThreatCode, "Blocked";
"Blocked" = $BlockedThreatCode, "CleanFailed";
"102" = $ActiveThreatCode, "QuarantineFailed";
"103" = $ActiveThreatCode, "RemoveFailed";
"104" = $QuarantinedThreatCode, "AllowFailed";
"105" = $UnknownThreatCode, "Abandoned";
"107" = $RemediatedThreatThreatCode, "BlockedFailed";
}

Set-StrictMode -Version 2

$currentTime = (Get-Date);
$computerStatus = $null;
$threatDetections = $null;

$protectionStatusCode = $UnknownProtectionCode;
($protectionRank, $protectionStatus) = $UnknownProtectionCode;
$protectionStatusDetails = "Unable to determine status";

($threatStatusRank, $threatStatus) = $UnknownThreatCode;
$threatStatusDetails = "Unable to determine status";

$signature = "";


# Get Computer Status information
try {
$computerStatus = Collect-ComputerStatus

if ($computerStatus -ne $null) {
$protectionStatusDetails = "";

# See if any of the protection aspects are disabled

$protectionStatusDetailsEnableArray = @();

if ($computerStatus.AMServiceEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Antimalware disabled";
}
if ($computerStatus.OnAccessProtectionEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "On access protection disabled";
}
if ($computerStatus.IoavProtectionEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Ioav protection disabled";
}
if ($computerStatus.BehaviorMonitorEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Behavior monitor disabled";
}
if ($computerStatus.AntivirusEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Antivirus disabled";
}
if ($computerStatus.AntispywareEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Antispyware disabled";
}
if ($computerStatus.RealTimeProtectionEnabled -eq $false) {
$protectionStatusDetailsEnableArray += "Real-time protection disabled";
}

# Check currency of signatures and quick scan

$protectionStatusDetailsAgeArray = @();

if ($computerStatus.AntispywareSignatureAge -gt 7) {
$protectionStatusDetailsAgeArray += "Antispyware";
}
if ($computerStatus.AntivirusSignatureAge -gt 7) {
$protectionStatusDetailsAgeArray += "Antivirus";
}

if ($protectionStatusDetailsEnableArray.length -gt 0) {
$protectionStatusCode = $NoRealTimeProtectionProtectionCode;
$protectionStatusDetails += [string]::join('; ', $protectionStatusDetailsAgeArray);
$protectionStatusDetails += ";";
}
elseif ($protectionStatusDetailsAgeArray.length -gt 0) {
$protectionStatusCode = $SignaturesOutOfDateProtectionCode;
$protectionStatusDetails += "Signatures older than 7 days:";
$protectionStatusDetails += [string]::join('; ', $protectionStatusDetailsAgeArray);
$protectionStatusDetails += ";";
} else {
$protectionStatusCode = $RealTimeProtectionCode
$protectionStatusDetails = "AntivirusSignatureLastUpdated:" + $ComputerStatus.AntivirusSignatureLastUpdated;
}

($protectionRank, $protectionStatus) = $protectionStatusCode;

$signature = $ComputerStatus.AntivirusSignatureVersion;
}
} catch {
#
# Something bad happened - Everything goes to not reporting status
#
($protectionRank, $protectionStatus) = $NotReportingProtectionCode;
$protectionStatusDetails = "Failed to collect computer status";
$ErrorMessage = $protectionStatusDetails + "; ErrorMessage:" + $_.Exception.Message;
Write-Warning $ErrorMessage
}

#
# Report about Protection Status State
#

($threatStatusRank, $threatStatus) = $NoThreatsDetectedThreatCode;
$threatStatusDetails = "";
$detectionId = [System.Guid]::NewGuid().ToString();

Add-MalwareScan $protectionRank $protectionStatus $protectionStatusDetails $detectionId "" $threatStatusRank $threatStatus $threatStatusDetails `
$signature $currentTime $currentTime $global:msMpModuleCommands.ToolName;

#
# Get Threads Detection information
#

try {

$threatDetections = Collect-DetectionStatus

if ($threatDetections -ne $null) {

$pastDateTime = (Get-Date).AddHours(-$global:msTimeWindowInHours);

($protectionRank, $protectionStatus) = $ThreatDetectedProtectionCode;
$protectionStatusDetails = "At least one threat detected";

foreach ($threatDetection in $threatDetections) {
# Determine the threat categories based on ThreatStatusID
(($threatStatusRank, $threatStatus), $threatStatusDetails) = ThreatStatusFromStatusCode $threatDetection.ThreatStatusID.ToString();
$scanDate = $threatDetection.LastThreatStatusChangeTime;

if ($threatStatus -eq $ActiveThreatCode[1] &lt;#Active Threat#&gt; -or
$scanDate -ge $pastDateTime &lt;#Filter threads by Time Window#&gt;)
{
$threatStatusDetails += "; ThreatID:" + $threatDetection.ThreatID + "; Resources:" + $threatDetection.Resources;
$threatName = Get-ThreatNameById $threatDetection.ThreatID;
$detectionId = $threatDetection.DetectionID.Substring(1, $threatDetection.DetectionID.Length-2);

Add-MalwareScan $protectionRank $protectionStatus $protectionStatusDetails $detectionId `
$threatName $threatStatusRank $threatStatus $threatStatusDetails $signature `
$scanDate $currentTime $global:msMpModuleCommands.ToolName
}
}
}

} catch {
#
# Something bad happened - Failed to collect threat detections
#
($threatStatusRank, $threatStatus) = $UnknownThreatCode;
$threatStatusDetails = "Failed to collect threat detections";
$ErrorMessage = $threatStatusDetails + "; ErrorMessage:" + $_.Exception.Message;
Write-Warning $ErrorMessage

Add-MalwareScan $protectionRank $protectionStatus $protectionStatusDetails "" "" $threatStatusRank $threatStatus $threatStatusDetails `
$signature $currentTime $currentTime $global:msMpModuleCommands.ToolName;
}
}

function Get-ThreatStatusFromStatusCode {
param(
$ThreatStatusID
)

(($threatStatusRank, $threatStatus), $threatStatusDetails) = $ThreatStatusFromStatusCode[$ThreatStatusID];

if ($threatStatusRank) {
return $ThreatStatusFromStatusCode[$ThreatStatusID];
}
else {
(($threatStatusRank, $threatStatus), $threatStatusDetails) = $ThreatStatusFromStatusCode["0"];
$threatStatusDetails += " (ThreatStatusID:" + $ThreatStatusID + ")";
return (($threatStatusRank, $threatStatus), $threatStatusDetails);
}
}

function Get-ThreatNameById {
param(
$ThreatID
)
# get the threat associated with detection
$threatName = "Unknown"; # defaults to unknown threat name
try {
$threats = Collect-Threats
$threat = $threats | Where-Object { $_.ThreatID -eq $ThreatID } | Select-Object -First 1
if ($threat -ne $null) {
$threatName = $threat.ThreatName;
}
}
catch {
Write-Warning "Failed to collect threat information"
}
$threatName
}

function Collect-ComputerStatus {
foreach ($attempt in 1..5) {
try {
$status = &amp;$global:msMpModuleCommands.GetMpComputerStatusCmdName #Get-MProtComputerStatus
return $status;
}
catch {
if ($attempt -ne 5) {
Start-Sleep -s $global:msRetryTimeoutInSeconds
} else {
throw
}
}
}
}

function Collect-Threats {
foreach ($attempt in 1..5) {
try {
$threats = &amp;$global:msMpModuleCommands.GetMpThreatCmdName #Get-MProtThreat
return $threats;
}
catch {
if ($attempt -ne 5) {
Start-Sleep -s $global:msRetryTimeoutInSeconds
} else {
throw
}
}
}
}

function Collect-DetectionStatus {
foreach ($attempt in 1..5) {
try {
$threatsDetections = @()
$threatsDetectionInfo = &amp;$global:msMpModuleCommands.GetMpThreatDetectionCmdName #Get-MProtThreatDetection
foreach ($tdi in $threatsDetectionInfo)
{
$threatsDetections += $tdi
}
if($threatsDetections.Count -eq 1)
{
return ,$threatsDetections
}
return $threatsDetections
}
catch {
$ErrorMessage = "Failed to call " + $global:msMpModuleCommands.GetMpThreatDetectionCmdName;
Write-Warning $ErrorMessage;
if ($attempt -ne 5) {
Start-Sleep -s $global:msRetryTimeoutInSeconds
} else {
throw
}
}
}
}
# Extracts Anti-Malware information via Microsoft AM Engine PowerShell commands.
&lt;#
Detects Windows Defender AM Engine and returns set of PowerShell commands for MsEngineLib module.
#&gt;

Function Detect-Defender
{
try {
$mpComputerStatus = Get-MpComputerStatus;
return ($mpComputerStatus -ne $null);
}
catch {
return $false;
}
}

Function Get-DefenderCommands
{
return New-Object PSObject -Property @{
GetMpComputerStatusCmdName="Get-MpComputerStatus";
GetMpThreatCmdName="Get-MpThreat";
GetMpThreatDetectionCmdName="Get-MpThreatDetection";
ToolName="Windows Defender";
}
}

# Detects Windows Defender AM Engine and returns set of PowerShell commands for MsEngineLib module.
&lt;#
Detects System Center Endpoint Protection (SCEP) AM Engine and returns set of PowerShell commands for MsEngineLib module.
#&gt;

Function Detect-SCEP
{
try {
$module = Import-SCEPMpModule;
return ($module -ne $null);
}
catch {
return $false;
}
}

Function Get-SCEPCommands
{
return New-Object PSObject -Property @{
GetMpComputerStatusCmdName="Get-MProtComputerStatus";
GetMpThreatCmdName="Get-MProtThreat";
GetMpThreatDetectionCmdName="Get-MProtThreatDetection";
ToolName="System Center Endpoint Protection";
}
}

Function Import-SCEPMpModule
{
$mpModulePaths = @(
"$env:ProgramFiles\Microsoft Security Client\MpProvider\MpProvider.psd1"
);

foreach ($mpModulePath in $mpModulePaths)
{
$path = [System.Environment]::ExpandEnvironmentVariables($mpModulePath)
if (Test-Path $path)
{
$mpModule = Import-Module $path -PassThru
if ($mpModule -ne $null)
{
return $mpModule;
}
}
}

return $null;
} # Detects System Center Endpoint Protection (SCEP) AM Engine and returns set of PowerShell commands for MsEngineLib module.
&lt;#
.SYNOPSIS

Parses the Malicious Software Removal Tool logfile

.DESCRIPTION

Outputs a summary from each run of the Malicious Software Removal Tool, showing:
* return code
* signature version or build number
* scan date
* protection status
* threat status
* malware found
* action taken

.PARAMETER logfile

Path to the logfile to be read.
Default is %windir%\debug\mrt.log

.PARAMETER timeWindowInHours

Controls how many hours in the past to look for scans. (Always returns latest scan)

Default is 24

.PARAMETER showCount

Controls whether the count of total records parsed is output

#&gt;


Function Detect-MsrtLog
{
try {
return (Test-Path $logfile);
}
catch {
return $false;
}
}

Function Scan-MsrtLog
{
Param(
[parameter(Mandatory=$false, ValueFromPipeline=$true)]
[string]$logfile = "$env:windir\debug\mrt.log",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$showCount = "false"
)

Set-StrictMode -Version 2

#region ProtectionCodes
$ProtectionStatusFromStatusCode = @{
"-1" = $NotReportingProtectionCode;
"0" = $NoRealTimeProtectionProtectionCode;
"1" = $NotReportingProtectionCode;
"2" = $NotReportingProtectionCode;
"3" = $NotReportingProtectionCode;
"4" = $NotReportingProtectionCode;
"5" = $UnknownProtectionCode;
"6" = $ThreatDetectedProtectionCode;
"7" = $ThreatDetectedProtectionCode;
"8" = $ActionRequiredProtectionCode;
"9" = $ActionRequiredProtectionCode;
"10" = $ActionRequiredProtectionCode;
"11" = $ActionRequiredProtectionCode;
"12" = $ActionRequiredProtectionCode;
"13" = $ActionRequiredProtectionCode;
}
#endregion

#region MSRTCodes
# MSRT protection status return code taken from http://support.microsoft.com/kb/891716
$DescriptionFromStatusCode = @{
"-1" = "Not reporting - Unable to collect data";
"0" = "No infection found";
"1" = "Not reporting - OS Environment Error";
"2" = "Not reporting - Not running as an Administrator";
"3" = "Not reporting - Not a supported OS";
"4" = "Not reporting - Error Initializing the scanner. (Download a new copy of the tool)";
"5" = "Unknown";
"6" = "At least one infection detected.";
"7" = "At least one infection was detected, but errors were encountered.";
"8" = "Manual steps are required for a complete removal.";
"9" = "Manual steps are required for complete removal and errors were encountered.";
"10" = "Restart is required for complete removal";
"11" = "Restart is required for complete removal and errors were encountered";
"12" = "Manual steps and a restart is required for complete removal.";
"13" = "Restart is required.";
}
#endregion

$build = ""
$returnCode = ""
$signatureVersion = ""
$scanDate = ""
$malware = @()
$malware_found = ""
$malware_details_found = ""
$currentTime = (Get-Date);
$countRecords = 0

foreach ($line in (Get-Content $logfile) )
{
Write-Debug "&gt;$line"
switch -regex ($line)
{
"^-{87}$" # record separator is 87 -, reset values
{
Write-Debug "New record"
$build = ""
$returnCode = ""
$signatureVersion = ""
$scanDate = ""
$malware = @()
$malware_found = ""
$malware_details_found = ""
}

"build ([\d.]+)"
{
$build = $Matches[1]
Write-Debug "Build = $build"
}

"^Started On (.+)"
{
$scanDate = $Matches[1]
Write-Debug "ScanDate = $scanDate"
}

"^Signatures: ([\d.]+)"
{
$signatureVersion = $Matches[1]
Write-Debug "Signature Version = $signatureVersion"
}

"^Threat Detected: (\S+?)(, | and )(.*)$"
{
$malware_found = $Matches[1]
$malware_details_found = $Matches[3]
Write-Debug "Malware: $malware_found, Details: $malware_details_found"
}

" Action: (\w+), Result: ([\d\w]+)"
{
$action = $Matches[1]
$actionCode = $Matches[2]
if (($action -eq "Remove" -or $action -eq "Clean") -and $actionCode -eq "0x00000000")
{
$threat_status = $RemediatedThreatThreatCode
}
else
{
$threat_status = $ActiveThreatThreatCode
}

$item = @{};
$item.Threat = $malware_found;
($item.ThreatStatusRank, $item.ThreatStatus) = $threat_status;
$item.ThreatStatusDetails = $malware_details_found;

$malware += $item
Write-Debug "$malware_found : $item"
}

"^Return code: (\d+)"
{
$returnCode = $Matches[1]
Write-Debug "Return code = $returnCode"

$countRecords += Add-Line $returnCode $build $signatureVersion $scanDate $malware $currentTime;
}
}
}

if ($countRecords -eq 0)
{
$countRecords += Add-Line "" "" "" "" @() $currentTime;
}

if ($showCount -eq "true")
{
Write-Host "$countRecords processed"
}
}

function Add-Line
{
param(
$returnCode,
$build,
$signatureVersion,
$scanDate,
$malware,
$collectedDateTime)

Write-Debug "$returnCode, $build, $signatureVersion, $scanDate, $malware"

$scanDateTime = (Get-Date).ToUniversalTime().Date.ToLocalTime() # scanDateTime will default to 12:00:00AM of the current date if log file doesn't exist or if it cannot parse the format of the MSRT log file
$threatStatus = ""
$returnProtectionStatus = ""
$returnProtectionRank = ""
$returnScanDate = ""
$toolName = "Malicious Software Removal Tool";
$countRecords = 0;

if ($scanDate -ne "")
{
try
{
$scanDateTime = ([datetime]::ParseExact($scandate, 'ddd MMM dd HH:mm:ss yyyy', [System.Globalization.CultureInfo]::InvariantCulture)) # MSRT Date format is not a standard format
}
catch
{
Write-Verbose "Scan date not valid: $scanDate"
}
}

$nowMinusTimeWindow = (Get-Date).AddHours(-$timeWindowInHours)
if ($scanDateTime -gt $nowMinusTimeWindow)
{
if ($returnCode -eq "")
{
$returnCode = "-1";
}

($returnProtectionRank, $returnProtectionStatus) = $ProtectionStatusFromStatusCode[$returnCode];

if ($signatureVersion -eq "")
{
if ($build -ne "")
{
$signatureVersion = $build
}
else
{
$signatureVersion = "Unknown"
}
}

if ($malware.Count -gt 0 )
{
foreach ($item in $malware)
{
$detectionId = [System.Guid]::NewGuid().ToString();
Add-MalwareScan $returnProtectionRank $returnProtectionStatus $DescriptionFromStatusCode[$returnCode] $detectionId `
$item.Threat $item.ThreatStatusRank $item.ThreatStatus $item.ThreatStatusDetails `
$signatureVersion $scanDateTime $collectedDateTime $toolName;

$countRecords++;
}
}
else
{
if ($returnCode -eq -1) {
($threatStatusRank, $threatStatus) = $UnknownThreatCode;
} else {
($threatStatusRank, $threatStatus) = $NoThreatsDetectedThreatCode;
}

$detectionId = [System.Guid]::NewGuid().ToString();

Add-MalwareScan $returnProtectionRank $returnProtectionStatus $DescriptionFromStatusCode[$returnCode] `
$detectionId "" $threatStatusRank $threatStatus "" $signatureVersion $scanDateTime $collectedDateTime $toolName;

$countRecords++;
}
}

return $countRecords;
}
# Parses the Malicious Software Removal Tool logfile.
&lt;#
Detects Windows Security Center and Extract Protection information via WSC API.

enum _WSC_SECURITY_PRODUCT_STATE {
WSC_SECURITY_PRODUCT_STATE_ON = 0,
WSC_SECURITY_PRODUCT_STATE_OFF = 1,
WSC_SECURITY_PRODUCT_STATE_SNOOZED = 2,
WSC_SECURITY_PRODUCT_STATE_EXPIRED = 3
}

enum _WSC_SECURITY_SIGNATURE_STATUS {
WSC_SECURITY_PRODUCT_OUT_OF_DATE = 0,
WSC_SECURITY_PRODUCT_UP_TO_DATE = 1
}
#&gt;

$global:wscRetryTimeoutInSeconds = 10;
$global:wscTimeWindowInHours = 24;

Function Detect-WSC
{
try {
$productsList = New-Object -ComObject wscAPI.WSCProductList;
return ($productsList -ne $null);
}
catch {
return $false;
}
}

Function Scan-WSCStatus
{
Param(
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$retryTimeoutInSeconds = 10,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24
)

$global:wscRetryTimeoutInSeconds = $retryTimeoutInSeconds;
$global:wscTimeWindowInHours = $timeWindowInHours;

Set-StrictMode -Version 2

$currentTime = (Get-Date);

$protectionStatusCode = @(0, "");
$protectionStatusDetails = "";
$computerStatus = $null;
$threatDetections = $null;
($threatStatusRank, $threatStatus) = $UnknownThreatCode;

$productsList = New-Object -ComObject wscAPI.WSCProductList;
$provider = 4; #WSC_SECURITY_PROVIDER_ANTIVIRUS
$productsList.Initialize($provider);

#Find Product in ON state
$productInOnStateInx = -1;
for ($i=0; $i -lt $productsList.Count; $i++){
if ($productsList.Item($i).ProductState -eq 0) {
$productInOnStateInx = $i;
}
}

for ($i=0; $i -lt $productsList.Count; $i++){

# Report only one record in case of On Product was found
if (($productInOnStateInx -ne -1) -and ($i -ne $productInOnStateInx )) {
continue;
}

switch ($productsList.Item($i).ProductState) {
"0" &lt;# WSC_SECURITY_PRODUCT_STATE_ON #&gt; {
if ($productsList.Item($productInOnStateInx).SignatureStatus -eq 1) &lt;# WSC_SECURITY_PRODUCT_UP_TO_DATE #&gt; {
($protectionRank, $protectionStatus) = $RealTimeProtectionCode;
} else {
($protectionRank, $protectionStatus) = $SignaturesOutOfDateProtectionCode;
}
}
"1" &lt;# WSC_SECURITY_PRODUCT_STATE_OFF #&gt; {
($protectionRank, $protectionStatus) = $NoRealTimeProtectionProtectionCode;
}
"2" &lt;# WSC_SECURITY_PRODUCT_STATE_SNOOZED #&gt; {
($protectionRank, $protectionStatus) = $ActionRequiredProtectionCode;
}
"3" &lt;# WSC_SECURITY_PRODUCT_STATE_EXPIRED #&gt; {
($protectionRank, $protectionStatus) = $ActionRequiredProtectionCode;
}
}

$detectionId = [System.Guid]::NewGuid().ToString();
$toolName = "WSC:" + $productsList.Item($i).ProductName;
Add-MalwareScan $protectionRank $protectionStatus $protectionStatusDetails `
$detectionId "" $threatStatusRank $threatStatus "" `
"" $productsList.Item($i).ProductStateTimestamp $currentTime $toolName;
}
} # Detects Windows Security Center and Extract Protection information via WSC API.
#
# Implements Main logic for OMS Anti-Malware solution:
# Run different AM Engines in predefined order, collect &amp; format results and pass its to ODS.
# Create ETW event for debug purpose
#

Function LogScriptEvent
{
Param(
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
$oAPI=$null,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$ScriptName = "",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$EventID = 9999,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$Severity = 0,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$Description = "")

if ($oAPI -ne $null)
{
$oAPI.LogScriptEvent($ScriptName, $EventID, $Severity, $Description);
}
}

Function Run-DetectionInt
{
Param(
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
$oAPI = $null,
[parameter(Mandatory=$false, ValueFromPipeline=$true)]
[string]$logfile = "$env:windir\debug\mrt.log",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$showCount = "false",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$retryTimeInSeconds = 10,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$deviceName = ""
)

LogScriptEvent $oAPI "AntiMalware Collection Script Started" 9991 0 "";

if (Detect-SCEP) {
$SCEPCommands = Get-SCEPCommands
LogScriptEvent $oAPI "AntiMalware Collection Script Detected Engine" 9992 0 $SCEPCommands.ToolName;
Scan-ComputerStatus $SCEPCommands $retryTimeInSeconds $timeWindowInHours;
} elseif (Detect-Defender) {
$DefenderCommands = Get-DefenderCommands
LogScriptEvent $oAPI "AntiMalware Collection Script Detected Engine" 9992 0 $DefenderCommands.ToolName;
Scan-ComputerStatus $DefenderCommands $retryTimeInSeconds $timeWindowInHours ;
} elseif (Detect-WSC) {
LogScriptEvent $oAPI "AntiMalware Collection Script Detected Engine", 9992 0 "Windows Security Center";
Scan-WSCStatus $retryTimeInSeconds $timeWindowInHours
} elseif (Detect-MsrtLog) {
$decription = "MSRT, Logfile Path:" + $logfile;
LogScriptEvent $oAPI "AntiMalware Collection Script Detected Engine " 9992 0 $decription;
Scan-MsrtLog $logfile $timeWindowInHours $showCount
} else { # No AM Engine was detected
LogScriptEvent $oAPI "AntiMalware Collection Script Detected Engine " 9992 0 "No Anti-Malware Tool was detected";
($threatStatusRank, $threatStatus) = $UnknownThreatCode;
($protectionRank, $protectionStatus) = $UnknownProtectionCode;

$detectionId = [System.Guid]::NewGuid().ToString();
$toolName = "No Anti-Malware Tool was detected";
$currentTime = (Get-Date);

Add-MalwareScan $protectionRank $protectionStatus "" $detectionId `
"" $threatStatusRank $threatStatus "" `
"" $currentTime $currentTime $toolName;
}
}

Function Run-Detection
{
Param(
[parameter(Mandatory=$false, ValueFromPipeline=$true)]
[string]$logfile = "$env:windir\debug\mrt.log",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$timeWindowInHours = 24,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$showCount = "false",
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[int]$retryTimeInSeconds = 10,
[parameter(Mandatory=$false, ValueFromPipeline=$false)]
[string]$deviceName = ""
)

$oAPI = new-object -comObject "MOM.ScriptAPI";

Run-DetectionInt $oAPI $logfile $timeWindowInHours $showCount $retryTimeInSeconds $deviceName;

foreach ($scan in $global:malwareScans) {
$oPropertyBag = $oAPI.CreatePropertyBag();

$oPropertyBag.AddValue("DeviceName", $deviceName);
$oPropertyBag.AddValue("Tool", $scan.Tool);
$oPropertyBag.AddValue("Signature", $scan.Signature);
$oPropertyBag.AddValue("ScanDate", $scan.ScanDate);
$oPropertyBag.AddValue("DateCollected", $scan.DateCollected);
$oPropertyBag.AddValue("DetectionId", $scan.DetectionId);

$oPropertyBag.AddValue("ProtectionStatusRank", $scan.ProtectionStatusRank);
$oPropertyBag.AddValue("ProtectionStatus", $scan.ProtectionStatus);
$oPropertyBag.AddValue("ProtectionStatusDetails", $scan.ProtectionStatusDetails);

$oPropertyBag.AddValue("Threat", $scan.Threat);
$oPropertyBag.AddValue("ThreatStatusRank", $scan.ThreatStatusRank);
$oPropertyBag.AddValue("ThreatStatus", $scan.ThreatStatus);
$oPropertyBag.AddValue("ThreatStatusDetails", $scan.ThreatStatusDetails);

$eventData = "DeviceName:" + $deviceName + ", " +
"Tool:" + $scan.Tool + ", " +
"Signature:" + $scan.Signature + ", " +
"ScanDate:" + $scan.ScanDate + ", " +
"DateCollected:" + $scan.DateCollected + ", " +
"ProtectionStatusRank:" + $scan.ProtectionStatusRank + ", " +
"ProtectionStatus:" + $scan.ProtectionStatus + ", " +
"ProtectionStatusDetails:" + $scan.ProtectionStatusDetails + ", " +
"ThreatStatusRank:" + $scan.ThreatStatusRank + ", " +
"ThreatStatus:" + $scan.ThreatStatus + ", " +
"ThreatStatusDetails:" + $scan.ThreatStatusDetails + ", " +
"Threat:" + $scan.Threat + ", " +
"DetectionId:" + $scan.DetectionId;

LogScriptEvent $oAPI "AntiMalware Collection Script scan" 9993 0 $eventData;
$eventData
$oPropertyBag
}

LogScriptEvent $oAPI "AntiMalware Collection Script Finished" 9994 0 "AntiMalware Collection Script Returned";
}



# Implements Main detection logic for OMS Anti-Malware solution

$deviceName = "$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$";

Run-Detection $logfile $timeWindowInHours $showCount $retryTimeInSeconds $deviceName


</Script></ScriptBody>
<TimeoutSeconds>600</TimeoutSeconds>
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="WA2" TypeID="Types!Microsoft.SystemCenter.AntiMalwareInformationDataWriteAction"/>
</WriteActions>
</Rule>