Monitor Everything with Monitis – And do it easily with PowerShell – Part 9

Monitoring Connections to Shared Folders with Monitis and Custom Monitors

In the last couple of articles, we’ve talked about how to create and update custom monitors that use WMI to push information into Monitis.  So far, we’ve only used WMI to get the information, and then used that to update custom monitors in monitis.  Today, we’re going to use a built in capability of PowerShell and WMI to make custom monitors that update whenever something happens on the system.

WMI stands for Windows Management Instrumentation, and it is a huge store of information that’s been built into the operating system since Windows 2000.  So far we’ve been using one feature of WMI, getting information from classes.  It’s also possible to use WMI to find out when things happen on the operating system.

To find all of the things PowerShell can do with WMI, you can use Get-Command’s –Noun parameter.  Remember: all commands in PowerShell are named in a Verb-Noun pair.

Get-Command -Noun *wmi*

The command we’re interested in is Register-WmiEvent.  WmiEvents are a nifty feature of WMI:  They can be used to tell you when something is happening in the operating system.  To make things even better, you can track anything piece of information in WMI and respond with an event.

For instance, there’s a really nifty WMI class called Win32_ServerConnection.  It tells who is connected to a shared folder on a computer.

Let’s try it out interactively first, and then build a custom monitor that does the trick.  I’m going to just give you a magic query, and then explain it.

Register-WmiEvent -Query 'SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA "Win32_SessionConnection           

Now go ahead an open up a loopback connection to your own box (\\yourcomputername\c$\) , and then run Get-Event in powerShell.

You should see an event, which has buried within it your connection information.

Get-Event is PowerShell’s event queue.  You can use Get-Event to loop thru events that Powershell has caught that haven’t been acted on yet.  You can remove events with Remove-Event.

 

That long, magic filter is something called WQL.  WQL is kind of like SQL, and it’s the query language used by WMI.  When you write an event query, you can use a built in class __InstanceCreationEvent, to keep track of changes in the operating system.  WITHIN is a clause required in order to make sure your queries aren’t too greedy.  Any time you find a cool WMI thing you want to track, you can use this trick.

We can use a built in PowerShell command called Foreach-Object, and this will let us walk thru the event results.

Because of the way we asked for them, they’re a little buried.  PowerShell event results are usually in SourceEventArgs.  When you use a built-in event class like we did, a property called NewEvent contains the result.  Inside of that, a property called TargetInstance finally has our server connection.

This quick script gets it out.  In Foreach-Object, $_ is the current item, and we just walk down all of the properties until we get to the item we want:

Get-Event |
    Foreach-Object {
        $_.SourceEventArgs.NewEvent.TargetInstance
    }

To turn this into an automated monitor, we’re going to use a parameter of Register-WMIEvent, -Action.  –Action is a script that runs whenever the event happens, and it has an automatic variable $eventArgs, which we can use to drill down into the results.

This script isn’t really that different from the rest of the WMI scripts we’ve seen so far, except that will keep adding results whenever any connection is made.

Import-Module Monitis
Connect-Monitis

$monitorExists = Get-MonitisCustomMonitor -Name SharedFolderConnections
if (-not $monitorExists) {
    Add-MonitisCustomMonitor -Name SharedFolderConnections -Parameter Username, Sharename, ComputerName
}

Register-WmiEvent -Query 'SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA "Win32_ServerConnection"' -Action {
    $username = $EventArgs.NewEvent.TargetInstance.UserName
    $shareName = $EventArgs.NewEvent.TargetInstance.ShareName
    $computerName = $EventArgs.NewEvent.TargetInstance.__Server
    Update-MonitisCustomMonitor -Name SharedFolderConnections -value @{
        UserName = $username
        Sharename = $sharename
        ComputerName = $computerName 
    }
}

As you can see, -Action is almost exactly like the custom monitor code we’ve been doing over the last couple of days, but it will run whenever any user connects to a share until you exit PowerShell.

When we say “Monitor everything with Monitis and PowerShell”, we mean it.

Tomorrow, we’ll show you how to use the same trick to accomplish one of the great common needs of systems admins:  Knowing when a USB drives is plugged into a machine.

Monitor Everything with Monitis – And do it easily with PowerShell – Part 1

Monitor Everything with Monitis – And do it easily with PowerShell – Part 2

Monitor Everything with Monitis – And do it easily with PowerShell – Part 3

Monitor Everything with Monitis – And do it easily with PowerShell – Part 4

Monitor Everything with Monitis – And do it easily with PowerShell – Part 5

Monitor Everything with Monitis – And do it easily with PowerShell – Part 6

Monitor Everything with Monitis – And do it easily with PowerShell – Part 7

Monitor Everything with Monitis – And do it easily with PowerShell – Part 8

You might also like