Learning PowerShell – Lesson Eleven


PowerShell Lesson Eleven

By: Steven Aiello

Teach Your Self PowerShell – Setting Our Ground Work for a Free Monitoring System

Note to interact with running processes and services from PowerShell you will have to run Windows PowerShell ISE as an administrator!

Lesson Objectives

In this lesson we will accomplish something very important. We will learn how to read data from a CSV file. This is important because you don’t want to have to be sitting at the computer when your system is looking for information. Storing that information in a file is a great way to make sure it’s there when needed.

For the rest of our lessons we will construct a simple free service monitoring script that we can use in our environment to alert us if a service we want to monitor stops. This may not be the fanciest way to monitor our environment but if you only have a few servers that you need to keep track of it may be just the tool to do the job.

The first step in this process will be to construct the part of the script that will read in our CSV file.

Second we will take the name of the service and the “DesiredStatus” and make sure that if a service is set as ‘Running’ than we will validate it is in fact running.

We will set a variable for the administrator who will receive the e-mail for our alerts and configure the script to send an e-mail (we will install the mail server in the next lesson using PowerShell)

If the service’s DesiredStatus is set to “Running” and the actual service status is not “Running” we will display this on the PowerShell console.

In the next lesson we will install and configure an SMTP (e-mail server) through PowerShell (mostly) and then modify the script to not just display there was an error but actually send the e-mail.


Understanding Imported CSV Files

There are a few things I recommend when working with CSV files, the first may seem fairly obvious but always think about what your headings are going to be. What are CSV headings you may ask? Well when you create a CSV file for use in PowerShell you need to give PowerShell a way to understand the values in the CSV files. Remember that PowerShell is an object oriented language, so the contents of the CSV file will be an object, and all the data in that object needs to be accessible somehow. So in our example our CSV file will look something like this:

As you may be able to tell from this image we named our properties for PowerShell to access the data “ServiceName” and “DesiredStatus”. In theory we could have just put the name of the service that we wanted to monitor in the file, however, what is removed the service temporarily but then when we went back to re-add it to the file we forgot what we wanted to monitor. This may seem farfetched but administrators are “over worked” and they do forget things that should be simple. By being able to turn the alerting on and off in your file you have a slight safety net.

Lastly on this topic descriptive header names will make your code more easy to read, and will make it more understandable for people who may have to use your scripts later.

The second thing I like to do when importing files especially if you’re going to be working with several files is create a scripts directory variable:

$SCRIPT_DIR = “C:UsersStevenDesktopPowerShellLearning PowerShellLesson 11″

In the case above I can have one variable that points to the directory of all my scripts

$SERVICES = Import-Csv $SCRIPT_DIR’service.csv’

Then I can simply reference all my input or output files by concatenating the directory variable with the file name. If we use this method instead of using an absolute path like:

$SERVICES = Import-Csv “C:UsersStevenDesktopPowerShellLearning PowerShellLesson 11” service.csv”

If we were to move our script to another folder server, or share scripts with someone else they would have to go through and change all of the absolute paths in the locations any file was referenced. All in all this makes for cleaner and more easily maintained scripts.

So far using what we have discussed we have the following simple framework set for our script:

Next we will simply add in our variable for our admin user who will receive the e-mail alerts in the middle of the night when the service crashes!

Next we’re going to add some code so that we can make sure that our Import-Csv statement is working properly and that we can address the data in the CSV file as we expect:

As you can see here the two services that we had listed in our CSV file are now showing up, and we are able to access the “DesiredStatus” data option in that file. As you can see we are monitoring two services:

Spooler (The Window’s Print Spooler Service)

BDESVC (The BitLocker Drive Encryption Service)

The Spooler’s desired status is set to “Running” and the BitLocker Drive Encryption Service desired status is set to “Stopped”.

Next we are going to add the code that will match the desired status that we’ve found in our file to what’s actually going on within the system at the time the script is running.



Pay close attention to this line:

$SERVICE_TO_CHECK = Get-Service | WHERE {$_.Name -eq $SERVICE.ServiceName}

What are we doing in the script here?

First we are creating a new variable “$SERVICE_TO_CHECK”

Then we set that variable to what current status of the service object is with in Windows at the time the script is ran

We do this by using the WHERE statement that we have learned about previously

We are filtering all of the Get-Service data based on the ServiceName option that we had previously set in our CSV file

We are specifically using the ServiceName property that is attached to the instance of the current variable $SERVICE in our foreach services array

It through this process that we are able to retrieve only the current service and it’s properties that we’ve specified in our CSV file.

Next in the script we use a simple if else statement to validate that the current service status is what it’s desired status should be. Notice that in the code example we are using the –ne option which will check for not matched condition. If the conditions do not match we print a message that the settings don’t match. If we enter the else section of the statement we know the conditions match and we print out that information. You could have written this if else statement another way:

See here we are checking for the positive condition first, that is:

$SERVICE_TO_CHECK.Status is equal to $SERVICE.DesiredStatus

If else statements can usually be written in whatever fashion you find most readable.

In the next lesson we will install an SMTP server and replace the simple Write-Host statements will e-mail functionality!



Leave a reply

− one = three

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