Sunday, May 22, 2011

PowerShell: AD Logged On Report

Saw a great post on finding logged on users via PowerShell by Ben Wilkinson
http://gallery.technet.microsoft.com/scriptcenter/d46b1f3b-36a4-4a56-951b-e37815a2df0c

Using Ben's script a starting point, I created a script that emails a logged on report for AD systems. This scripts queries AD for all computer systems that aren't disabled. For each of those AD systems it will ping the system before attempting the WMI command. Added a status field to the report for better troubleshooting of failed connections.


#####################################################################
# Script Name: AD_Logged_On_Report.ps1
# Version: 2.0
# Author: Dean
# Last Edited: 05/22/2011
# Description: Email Report of Logged On Accounts for AD Systems
#####################################################################

#Error Handling
$erroractionpreference = "SilentlyContinue"

#Variable for Email FROM Address
$mFrom = "reporter@my.company.net"
#Variable for EMail TO Address
$mTo = "report-Admins@my.company.net"
#Variable for SMTP Server
$smtp = "smtp.my.company.net"

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

#Array for Reporting Objects
$Summary = @()

#LDAP Search for All Computers in Specific OU
#Filtering on Computers That Aren't Disabled
$ADsPath = [ADSI]"LDAP://DC=MY,DC=COMPANY,DC=NET"
$Search = New-Object DirectoryServices.DirectorySearcher($ADsPath)
$Search.filter = "(&(objectClass=computer)(!userAccountControl=4130)(!userAccountControl=4098))"
$Search.SearchScope = "SubTree"
$ADSystems = $Search.FindAll()

foreach ($ADSystem in $ADSystems)
{

#Pull The Computer Name
$Computer = $ADSystem.Properties["cn"][0].ToString()
#Variables for System Status and Logged On Users
$strStatus = ""
$strLoggedOn = ""

#Ping Computer Before Attempting Remote WMI
if (test-connection -computername $Computer -quiet)
{
$strStatus = "Ping Successful"

#Retrieve Processes on Computer System via WMI Call
$processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer)

#If Process Listing Not NUll Then Find Processes Owned by Unique Non Default Accounts
if ($processinfo)
{
$users = $processinfo | Foreach-Object {$_.GetOwner().User} |
Where-Object {$_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM"} |
Sort-Object -Unique

#ADD Unique Accounts to the Logged On Variable
if ($users)
{
foreach ($user in $users)
{
$strLoggedOn = $strLoggedOn + $user.ToLower() + " | "
}
}
#else
#{
#$strLoggedOn = "None"
#}

}
else
{
#Report WMI Call Failure
$strStatus = "WMI Failed"
}

}
else
{
#Report Ping Failure
$strStatus = "Ping Failed"
}

#Clean Up Logged On Variable
if($strLoggedOn.Length -gt 4)
{
$strLoggedOn = $strLoggedOn.Trim().TrimEnd("|")
}

#Create New PowerShell Object and Assign Data to It
$uEntry = new-Object PSObject
$uEntry | add-Member -memberType noteProperty -name "Computer Name" -Value $Computer.ToString().ToUpper()
$uEntry | add-Member -memberType noteProperty -name "Status" -Value $strStatus.ToString()
$uEntry | add-Member -memberType noteProperty -name "Logged On Users" -Value $strLoggedOn.ToString()
#Add Entry to Summary Array
$Summary += $uEntry

}

#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: left;}"
$a = $a + "TD{border-width: 1px;padding: 5px;border-style: solid;border-color: black;text-align: left;}"
$a = $a + "</style>"

#Message Body
$emsg = $Summary | Sort-Object {$_."Computer Name"} | ConvertTo-Html -head $a | Out-String

#Settings for Email Message
$messageParameters = @{
Subject = "Logged On Report for " + $rptDate
Body = $emsg
From = $mFrom
To = $mTo
SmtpServer = $smtp
}
#Send Report Email Message
Send-MailMessage @messageParameters –BodyAsHtml

Write-Host "All Done"

No comments: