Checking your Application Servers with Powershell (ApplicationPools, Windows Services, EventLog, Performance Counters)

If you are working in enterprise software development, you will sooner or later be involved in deployment of code to multiple machines. Very often deployments are a tedious, annoying and time-consuming task. In the enterprise world you are often confronted with lots of different machines in your deployment process. There could be frontend, backend and database servers and multiple stages such as production, dev, test, QA, etc…

Since the rise of agile development techniques, the number of deployments that are carried out in a year changed drastically. Where some years ago, a company was ahead of time when it had more than two deployments a year, today its different. The flexibility required by the business requirements and the desire to apply agile practices requires very short release cycles and deployments that are automated, repeatable and fast. The best case would be a deployment that takes nothing more than a click of a button.

Automation is the key. As an application grows, the deployment will span more and more machines. Every step that can be avoided must be saved. In this blog post I will share some nifty Powershell one-liners that can drastically speed up your deployment duration and lead to a more scalable process. They gather crucial system information from multiple machines in one line of code. I always see people fiddling with remote desktop connections and clicking through one menu after another just to find out if a certain windows service is stopped. This is fine if you only have to take care of one machine. As soon as you have multiple machines, the fun is over. Powershell is the answer!

1. Checking the State of IIS Application Pools for Multiple Remote Machines

1 $machines = MYSERVER01, MYSERVER02, MYSERVER03
2 InvokeCommand ComputerName $machines ScriptBlock { GetWebAppPoolState
Name MyApplicationPool }

So what does this script do? Very simple: First, it creates an array that contains your machine names, then it uses the Invoke-Command cmdlet to invoke a script block on every machine. The script block contains a call to the Get-WebAppPoolState cmdlet that ships with IIS. The output looks like this:

Value
——–
PSComputerName
————————
Started
Started
Started
MYSERVER01
MYSERVER02
MYSERVER03

Of course you can use the exact same approach to start and stop an Application Pool by using Start-WebAppPool, Stop-WebAppPool and Restart-WebAppPool.

2. Checking the State of Windows Services on Multiple Remote Machines

1 $machines = MYSERVER01, MYSERVER02, MYSERVER03
2 InvokeCommand ComputerName $machines ScriptBlock { GetService
| WhereObject {$_.Name -match NServiceBus }}

This script works in the exact same way than the first one. In the script block, it uses the Get-Service cmdlet to retrieve windows services and filters them to the string “NServiceBus”. The result will be:

 

Status
——Running

Stopped

Running

Name
—nsb01

nsb02

nsb03

DisplayName
—————NServiceBus01

NServiceBus02

NServiceBus03

PSComputerName
————–MYSERVER01

MYSERVER02

MYSERVER03

 

Needless to say that you can use Start-Service, Stop-Service or Restart-Service to start, stop and restart multiple services in one call.

The command can be reduced by using aliases and omitting default property names to:

1 InvokeCommand $machines {gsv | where {$_.Name -match NServiceBus}}

3. Getting the Event Log from multiple Machines

1 InvokeCommand $machines {GetEventLog LogName System EntryType Error, Warning | select First 10 Property TimeWritten, EntryType, MachineName, Message | FormatTable AutoSize wrap}

This will retrieve the first 10 errors and warnings from the “System” event logs of the machines. Output:

image

4. Checking Windows Performance Counters on a Remote Machine

1 GetCounter Counter “\\MYMACHINE01\Processor(_Total)\% Processor Time SampleInterval 1 Continuous

This script calls a performance counter in a regular time interval (here 1 second):

image

If you are interested in what counters are available, just call:

1 GetCounter ListSet *

This will give you the list of all available counters and their paths, such as:

image