Welcome back for part 2 of the series. In this post, I’ll be putting together a simple collector script with PowerShell for gathering metrics on a Windows host, and sending the data to the ingestor.
The idea behind this script is to have it run at certain intervals, to gather performance measurement and send them off to the ingestor. For this particular example, I’ll be grabbing total processor utilization as a percentage.
I see this script as being a starting point, or “template”. Eventually, there will be four scripts. Each script will cover a category of measurements such as CPU, memory, storage, and networking. Further, other scripts can be built off the same template for specific applications or services, such as Exchange, IIS, SharePoint, etc. Basically, if you can take a measurement via PowerShell, you can send it up to the database.
The first section of the script is some basic setup.
$HostName=$env:COMPUTERNAME
$CounterName="\processor(_total)\% processor time"
$Tree=$HostName
$Subtree="CPU"
$MetricName="PercentProcessorTimeTotal"
$Endpoint="http://webserver.psmetricslab.local/ingestor.asp"
Nothing magical here; we’re just setting some values for what we want to watch and where we want to store it.
- Grab the hostname from the environment.
- Define what performance counter that is going to be observed. In this case, it is Total % Processor Time.
- The next three variables define how the data is going to be stored in the database. A little organization now saves headaches later.
- And finally, the $Endpoint variable stores the URL of the ingestor that we are storing data to.
We’re also going to want to timestamp the datapoint, so we need to grab the current date/time.
$TimeStamp=Get-Date -format u
$TimeStamp=$TimeStamp.Replace("Z","")
For this exercise, I’m just going to use the in-built Windows performance counters, which we can grab with Get-Counter. As mentioned previously, any measurement can be stored. Use your imagination!
$CounterValue=Get-Counter "\\$HostName$CounterName"
$CounterValue=$CounterValue.counterSamples.CookedValue
Now to put all the data together in a querystring, in preparation for sending it to the ingestor.
$Values="?tree=$Tree&subtree=$Subtree&metric=$MetricName&cvalue=$CounterValue&TimeStamp=$TimeStamp"
For this, I’m using Invoke-WebRequest to send the data to the ingestor, and getting the content back. The content will contain any error codes, if any.
$Results=(Invoke-WebRequest -Uri $Endpoint$Values -DisableKeepAlive -Method Post).content
At this point, this script will return “success” for a successful run. Any other errors are not trapped here, and you’ll need to check the IIS logs on the ingestor to see what failed run was caused by. You could also post the URL manually in a browser to see if there is a problem.
In the final version of this script, I will be adding event logging to the Windows event log. In the event of a failed run, you’d just crack open the PSMetrics custom event log on the monitored host to see what the error is.
This temporary, rudimentary error processing shown below is basically just a placeholder.
if($Results -ne "success")
{
# the remote web server returned an error - display it to the user
write-host "The remote server has returned an error message -`n" -ForegroundColor red
write-host " $Results" -ForegroundColor Yellow
write-host "`nPlease check that you are passing all the required values" -ForegroundColor Red
}
So there we are. We have a basic collector. As the project progresses, I’ll be improving on this script, adding things such as logging and error checking. Stay tuned for Part 3!