Offline Machine Tracking with PowerShell

By | 2017-10-19

Here’s a simple little script that will track which computers are offline, and how long they have been offline. It even sends you a handy email summary.

Not a whole lot of magic here, but I thought I would share this for those folks that might have a similar requirement for tracking online/offline machines.

I have been using a version of this script as a scheduled task. In my production version, machines that have not been seen for seven days or more are disabled in Active Directory, and moved to another Organizational Unit (OU). I’ve removed the move-adobject part of this, but you can add it back in pretty easily.

This script is, as I mentioned, pretty simple.  The overview of the flow is as follows:

  • Ensure the AD module is loaded
  • Set some values. Be sure to twiddle these for your environment.
  • Grab a list of the computers we want to check from Active Directory.
  • Loop #1 goes through the list of computers and pings them.  During this loop, if the host is responding, ExtensionAttribute2 of the computer object is set with the date/time of the check. If the host is not responding, then no modification of the attribute is made, leaving the last contact date in place.
  • Email is built, containing a summary of total hosts, number responding, number not responding, and a list of those machines that have not been seen for the number of days specified in $AgeRestriction
  • The last line of the script sends the mail off using the parameters specified earlier.

Like I said, not magic, but maybe helpful to someone. I’ve pasted the script below, as well as attached a zip file of the script to this post.

###############################################################################
# Make sure the AD module is loaded
###############################################################################

import-module ActiveDirectory

###############################################################################
# set up some values
###############################################################################

$MySearchBase="OU=servers,DC=mydomain,DC=com" # OU where your servers live
$DateTime=Get-Date -format g                  # Current Date/Time for insertion and math
$ADTrackingAttribute="extensionattribute2"    # AD field we are using for tracking. D/T gets poked in here
$HostsResponding=0                            # current count of responding hosts
$HostsNotResponding=0                         # current count of not responding hosts
$CurrentHostNumber=1                          # How many hosts have been tested, used only for status bar percentage
$AgeRestriction=7                             # How many days old we are reporting on
$MailFromAddress="sender@mydomain.com"        # Report emails come from this address.
$MailTo="recipient@mydomain.com"              # Who the email is being sent to
$MailSubject="Pinger Report $DateTime"        # Subject line of email
$MailPort=25                                  # Any port in a storm, but using standard SMTP here
$MailServer="mysmtpserver.mydomain.com"       # A happy little mail forwarder

###############################################################################
# Load list of computers
###############################################################################

write-host "Retrieving host list from Active Directory" -ForegroundColor Yellow

$HostList=get-adcomputer -filter * -searchbase $MySearchBase | select name,dnshostname -ExpandProperty dnshostname
$NumberOfHosts=$HostList.count

write-host "Found $NumberOfHosts hosts, beginning connectivity testing" -ForegroundColor Yellow

###############################################################################
# Ping 'em
###############################################################################

foreach($Hostname in $HostList)
{
    ###########################################################################
    # goofy status bar up top
    ###########################################################################

    $Percentage=($CurrentHostNumber/$NumberOfHosts)*100
    write-progress -activity "Pinging $Hostname" -PercentComplete $Percentage -Status "please wait"
    $CurrentHostNumber++

    ###########################################################################
    # test, observe
    ###########################################################################

    if (test-connection -ComputerName $HostName.dnshostname -count 1 -quiet){

        #######################################################################
        # host responding. clear the field, update with current date/time
        #######################################################################

        set-adcomputer -identity $Hostname.name -clear "$ADTrackingAttribute"
        set-adcomputer -identity $Hostname.name -add @{"$ADTrackingAttribute"="$DateTime"}
        $HostsResponding++

    } else
    {
        #######################################################################
        # Host not responding
        #######################################################################

        $HostsNotResponding++
    }
}

write-host "connectivity testing complete, getting results ..." -ForegroundColor Yellow

###############################################################################
# start building email message
###############################################################################

$MessageBody="`n`n$DateTime Connectivity testing results
--------------------------------------
Total Hosts:    $NumberOfHosts
Responding:     $HostsResponding
Not Responding: $HostsNotResponding`n"

###############################################################################
# Check AD Attribute of all the things, and math the number of days since last seen
###############################################################################

If($HostsNotResponding -gt 0)
{
    $MessageBody=$MessageBody + "`nThe following hosts have not been seen for $AgeRestriction day(s) or more:`n"
}

foreach($HostName in $HostList) {
    
    $CurrentHostInfo=get-adcomputer -identity $HostName.name -properties $ADTrackingAttribute
    $CurrentHostLastDate=$CUrrentHostINfo.$ADTrackingAttribute
    $DaysSinceLastSeen=(new-timespan -start $CurrentHostLastDate -end $DateTime).Days

    if($HostsNotResponding -gt 0)
    {
        if($DaysSinceLastSeen -gt $AgeRestriction)
        {
            $MessageBody=$MessageBody + "`n$HostName`n"
        }
    }
}

###############################################################################
# cycle complete; notify user of results (in case of interactivity), and send
# an email to the interested parties.
###############################################################################

write-host $MessageBody -foregroundcolor Yellow
send-mailmessage -from $MailFromAddress -subject "$Mailsubject" -to $MailTo -body "$MessageBody" -port $MailPort -SmtpServer $MailServer

Author: dwirch

Derek Wirch is a seasoned IT professional with an impressive career dating back to 1986. He brings a wealth of knowledge and hands-on experience that is invaluable to those embarking on their journey in the tech industry.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.