Thursday, July 28, 2011

C#: FEP Client Alert Notice

As an alternative to running SCCM for Forefront Endpoint Protection alert notices (since you can easily control the client with GPOs and WSUS for status) I wrote up a C# console application that parses the system log to look for virus\malware notifications from the FEP client and then emails the alert message(s) to the system admins. This is just a proof of concept. Ideally you would want to create a Windows service that run this code to parse the log every hour or so.


using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net.Mail;

namespace FEP_Status_Check
{
class Program
{
static void Main(string[] args)
{
//Counter for FEP Alerts
int x = 0;

//String Building for FEP Log Entry Data
StringBuilder stbFEPNotice = new StringBuilder();

//Create Collection of System Log Entries
EventLog elSys = new EventLog("System", ".");
EventLogEntryCollection elecSystem = elSys.Entries;

//Loop Through System Events Collection
foreach (EventLogEntry sysLogEntry in elecSystem)
{
//Check to See if From FEP
if (sysLogEntry.Source.ToString() == "Microsoft Antimalware")
{
//Check to See if Event Took Place Within 2 Hours
if (DateTime.Compare(DateTime.Now.AddMinutes(-60), sysLogEntry.TimeGenerated) < 0)
{
//Check for Virus\Malware Alert or Remediation Action Alert
if (sysLogEntry.InstanceId.ToString() == "1116" || sysLogEntry.InstanceId.ToString() == "1117")
{
//Add Log Entry Text to FEP Notice
stbFEPNotice.Append(sysLogEntry.Message.ToString());
stbFEPNotice.Append("\n\n\n");
//Increment Counter
x++;
}
}


}

}

//Notify Network Admins of Any FEP Alerts
if (x > 0)
{

//Pull Computer Name
string strHostName = System.Environment.MachineName.ToString();
//Create and Send Email Notice
MailMessage mmFEPNotice = new MailMessage("DCAdmins@my.company.com", "admins@my.company.com");
mmFEPNotice.Subject = "FEP Alert Notice from " + strHostName + " on " + DateTime.Now.ToShortDateString();
mmFEPNotice.IsBodyHtml = false;
mmFEPNotice.Body = stbFEPNotice.ToString();
SmtpClient scMail = new SmtpClient("smtp.my.company.com");
scMail.Send(mmFEPNotice);

}


}
}
}

PowerShell: AD DC Failed Logins Report

I wanted to get a summary view of failed login attempts on a network DCs. Came up with this script that parses Windows 2008 R2 DCs security log files for all failed login attempts in the last 24 hours. Then it compiles a totals counts for each IP and host name combo listed in the logs of all the DCs. Sends a quick summary email to the admins.

#############################################################
# Script Name: AD_DCs_Failed_Login_Report.ps1
# Version: 1.0
# Author: Dean Bunn
# Last Edited: 07/26/2011
# Description: Failed Logins Report for DCs
#############################################################

#Array for All Failed Login Entries
$arrFailures = @()
#Array for Reporting
$Summary = @()

#Domain Controller Array
$DCs = @("dc1","dc2","dc3")

foreach($DC in $DCs)
{
#Retrieve Failed Logins on Each DC for the Last 24 Hours
$failedLogins = get-eventlog -computername $DC -logname security -after (get-date).adddays(-1) | where-object {$_.instanceID -eq 4625 }

#Loop Through Each Failed Login
foreach($failedLogin in $failedLogins)
{

#Var for Workstation Name
$workstation = ""
#Var for IP Address
$networkAddress = ""

#Array of Failed Login Log Entry Message (Split by Line Break)
$flM = $failedLogin.message.Split("`n")

#Loop Through Each Line in the Log Entry Message
foreach($fl in $flM)
{
#Check to See if Line has Source Network Address Info
if($fl.Contains("Source Network Address:"))
{
#Remove Unneeded Data from Line
$fl = $fl.Replace("Source Network Address:","")
#Clean UP Network Address Info
$networkAddress = $fl.ToString().Trim()
}

#Check to See if Line has Workstation Info
if($fl.Contains("Workstation Name:"))
{
#Remove Unneeded Data from Line
$fl = $fl.Replace("Workstation Name:","")
#Clean Up Workstation Info
$workstation = $fl.ToString().ToUpper().Trim()
}

}

#Format Failed Login Entry Data Before Adding to Array
$flEntry = $networkAddress + "," + $workstation

#Quick Check to See if IP And Host Name Weren't Empty
if($flEntry.length -gt 1)
{
#Added Failed Entry to Array
$arrFailures += $flEntry
}


}

}

#Create Hashtable for Unique Check
$htReport = @{}

#Loop Through Failed Log Entries Array and Count How Many Failed Logins
foreach($flEntry in $arrFailures)
{
#Int for Counting Failed Login Attempts
$intEC = 0

if(!$htReport.ContainsKey($flEntry))
{
#Loop Again Through Array Looking for IP + Host Name Match
foreach($item in $arrFailures)
{
if($flEntry -eq $item)
{
$intEC = $intEC + 1
}
}

#After Determining Matches, See if Entry Count Added To Report Already
#And Only Report on 10 or Greater Failed Logins for IP + Host Name Pair
if($intEC -gt 10) #
{

#Split Apart IP Host Name Entry to Add It to Report Summary
$arrFlEntry = $flEntry.Split(",")

#Create New PowerShell Object and Assign Data to It
$uEntry = new-Object PSObject
$uEntry | add-Member -memberType noteProperty -name "IP" -Value $arrFlEntry[0].ToString()
$uEntry | add-Member -memberType noteProperty -name "Host Name" -Value $arrFlEntry[1].ToString()
$uEntry | add-Member -memberType noteProperty -name "Failed Logins" -Value $intEC.ToString()
#Add Entry to Summary Array
$Summary += $uEntry

}

#Add Entry Info to Reporting Hashtable
$htReport.add($flEntry,"1")

}

}

#Get Current Short Date
$rptDate = Get-Date -Format d

#Style for HTML Table in ConvertTo-HTML
$a = "<style>"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;}"
$a = $a + "TH{border-width: 1px;padding: 5px;border-style: solid;border-color: black;text-align: center;}"
$a = $a + "TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;text-align: left;}"
$a = $a + "</style>"

#Message Body (Sorted by Failed Login Attempts)
$emsg = $Summary | Sort-Object {[int]$_."Failed Logins"} -descending | ConvertTo-Html -head $a | Out-String

#Settings for Email Message
$messageParameters = @{
Subject = "DCs Failed Logins Report for " + $rptDate
Body = $emsg
From = "DCAdmins@my.company.com"
To = "DCAdmins@my.company.com"
SmtpServer = "smtp.my.company.com"
}
#Send Report Email Message
Send-MailMessage @messageParameters –BodyAsHtml

Wednesday, July 6, 2011

PowerShell: Quick and Simple Network Monitor

Helped someone with a quick network monitoring PowerShell script. They are loading the list of systems from a text file on the locale system.

#Variable for System Count
$x = 0

#Email Message Body
$emsg = "<p>The following computer(s) failed Ping:</p>"

#Report Date
$rptDate = Get-Date

#Load Array of Computer Systems
$networkSystems = Get-Content "C:\data\network_systems.txt"

#Ping Each System in Array
foreach($ns in $networkSystems)
{
#If Ping Fails then Add to Message
if (!(test-connection -computername $ns -quiet))
{
$x = $x + 1
$emsg = $emsg + $ns + "<br />"
}

}

if($x -gt 0)
{
#Settings for Email Message
$messageParameters = @{
Subject = "Failed Ping Report for " + $rptDate
Body = $emsg
From = "report@mycollege.edu"
To = "admin@mycollege.edu"
SmtpServer = "smtp.mycollege.edu"
}
#Send Email Message
Send-MailMessage @messageParameters –BodyAsHtml
}