If you saw my blog post last week on Pulling performance counter data from daily performance logs you now know, as I do, that Exchange 2013 records a ton of performance data on your Exchange server by default. I was recently out on a walk, where I do some of my best thinking, trying to come up with a way to make use of all that data. Thusly was the Get-EDSData project was born. I am by no means a PowerShell expert. I’m not quite a PowerShell novice, but honestly I am probably closer to being a novice than an expert.
The purpose of this little project of mine is to figure out how to write a script I have dreamed up. I plan on taking you, loyal reader, on a journey with me. This project will have two main goals. The first is produce a PowerShell script that will perform what I believe to be a useful purpose. The second purpose of this project is going to be to learn PowerShell. I plan to lay out what I am doing each step of the way, so that other Exchange administrators will be able to follow along and hopefully contribute to the final product.
So what is Get-EDSData? I envision it to be a PowerShell script (maybe a function?) that will read data from the daily performance logs on an Exchange 2013 server and give an output about the health of that server. For instance, if problem X on an Exchange 2013 server can be diagnosed by looking at 3 performance counters and finding out if they are over threshold A,B, and/or C, then I imagine Get-EDSData would have a parameter for problem X that would give you an output telling you if Exchange server is suffering from the symptoms of problem X.
Eventually I would love to get to a point where I can produce add-ins for this script that would to diagnose lots of different problems. I would love to be able to address questions like “Why is email being delivered so slowly on my new Exchange 2013 servers?” with a simple variant of the Get-EDSData script. Of course that is a long way from being a reality at this point.
As you saw in the pulling performance counter blog post, I have figured out how to pull information for a single counter from the daily performance logs into its own performance log for all the days you have in your daily performance logs. That is going to be my starting point for developing Get-EDSData.
Now you know that as a starting point I have a couple of PowerShell commands that I have already written out to take the data for a single performance counter from your daily performance logs and place that data into a .blg file of its own. Those commands look like this
$Data = Import-Counter -path "C:\Program Files\Microsoft\Exchange Server\V15\Logging\Diagnostics\DailyPerformanceLogs\*.blg" -counter \\EX01\MSExchange ADAccess Domain Controllers(*)\LDAP Read Time
The first step in bringing Get-EDSData to life is going to be to make those two lines into a script that works on any server and for any performance counter. I want to be able to run ./Get-EDSData.ps1 –Server Ex01 –Counter “MSExchange ADAccess Domain Controllers(*)\LDAP Read Time” and have it show me the history of that performance counter on my server for whatever time is recorded in daily performance logs.
This sounds like a job for parameters! At this point, it looks like I need two parameters; one for the server we want to run this on, and the other for the counter for which we want to gather data. Here is how I went about defining those parameters
[CmdletBinding()] Param( [Parameter(Mandatory=$True,Position=1)] [string]$Server, [Parameter(Mandatory=$True)] [string]$Counter )
Huh? Let’s break down each line and see what it does.
CmdletBinding is a command you can put into a PowerShell script that adds some basic PowerShell functionality to that script. For instance, it makes the –verbose and –debugging parameters available. It does not have anything to do with what I was talking about above, but it’s a good idea to add it in anyway
This is where we start to define our parameters. Param tells PowerShell that whatever comes inside the parentheses is going to be about defining our parameters.
This is telling PowerShell that I am about to define my first parameter. The parameter I define here is going to be mandatory. If you do not type this parameter when you run the script, you will get a prompt asking for it. The position part tells PowerShell that in this script, the first parameter is always going to be the one I am about to define.
And here if our first parameter! It is a string parameter, which means it is a string of letters and numbers. I could have chosen to use [Integer] instead of [string], but most servers are not named “1” so that would have broken the script. The comma at the end tells PowerShell that I have another parameter coming.
[Parameter(Mandatory=$True)] [string]$Counter )
The next two lines are much the same as the last two. This parameter is also a string, and it is also mandatory. The only difference is that this one does not have a position defined. If I had 3 parameters, server would come first then the other two could come in any order. The parentheses at the end just closes the one at the beginning of the Param statement.
Now we have our parameters, let’s work them into the existing PowerShell commands that I started with. The whole thing ends up look like this
# Get-EDSData v1.0 # By Nathan O'Bryan # email@example.com # http://www.mcsmlab.com [CmdletBinding()] Param( [Parameter(Mandatory=$True,Position=1)] [string]$Server, [Parameter(Mandatory=$True)] [string]$Counter ) $Data = Import-Counter -path "C:\Program Files\Microsoft\Exchange Server\V15\Logging\Diagnostics\DailyPerformanceLogs\*.blg" -counter \\$Server\"$Counter" $Data | Export-Counter -Path \\$Server\C$\temp\WorkingSet.blg
There you have it. You end up with a file called WorkingSet.blg in your c$\Temp directory that has the data for a single performance counter over the period of time covered by your daily performance logs. A rather short and basic script for now, but it’s a start. I have several ideas for improvements that can be made, but we’ll have to save those for another day.
I have posted this script to TechNet Gallery. It can be found here.
Feel free to let me know what functionality you think this script needs in the comments.