DBA with PowerShell : Get perfmon counters using PowerShell

dba-with-powershell

DBA with PowerShell” series is to focus on gathering information about SQL Server’s infrastructure. It’s little complex to fetch such detailed information using SQL Server; whereas Windows PowerShell gives us various options and saving the PowerShell output into a database becomes more useful information for analysis perspective. I am here using PowerShell 5.0 but given script will run in lower versions as well. Windows PowerShell is a very powerful, lightweight and free scripting tool based on .Net framework. You can download it from here.

Performance monitoring is a very crucial part of every DBA. In Performance monitoring “CPU utilization”, “memory utilization” and logical/physical disk usage are very important aspects to monitor. Built-in tools like “activity monitor”, “perfmon” and sometimes third party tool are very useful but with cost; either in term of money or machine resources.

We all know that perfmon and other default tools are resources intensive; that’s why these tools are not often used in prod environment, except very specific troubleshooting requirements.

I was keep thing, if we can fetch these info form system directly and save it to database for further analysis; and then I got a chance to attend Mr. Mukesh Shende‘s PowerShell training sessions in my org.. He shared some fundamentals & advance features of PowerShell. That inspires me to write PS scripts to fetch such infrastructure’s information and save the PowerShell output into a database table. I will share all of them in my coming posts.

Perfmon data with PS Script:

The script is to fetch performance counter’s information including “CPU utilization”, “memory usage”, Physical & logical disk read/write info etc. and saves into a SQL Server database table. You need to schedule this script to collect data in required frequency.

Step 01: Creating a table to hold the information

CREATE TABLE [dbo].[SystemInfo] (
[ID] [int] IDENTITY(1,1) PRIMARY KEY,
[DateTime] DATETIME NULL,
[Path] [varchar](100) NULL,
[Value] DECIMAL(18,2) NULL
)

Step 02: Creating event log source in PS.

[System.Diagnostics.EventLog]::CreateEventSource("PSPerformanceCounter", "Application")

Step 03: The PS Script

You need to schedule it in SQL agent job under PowerShell type OR can execute manually for run-time information from PS-ISE.


$SQLInstanceName = ""
$DatabaseName = ""

$Couters = '\Processor(*)\% Processor Time','\Memory\Page Reads/sec','\Memory\Available MBytes','\LogicalDisk(*)\Disk Reads/sec','\LogicalDisk(*)\Disk Writes/sec','\PhysicalDisk(*)\Disk Reads/sec','\PhysicalDisk(*)\Disk Writes/sec'

try
{

$conn = New-Object System.Data.SqlClient.SqlConnection

$conn.ConnectionString = "Data Source=$SQLInstanceName;
Initial Catalog=$DatabaseName;
Integrated Security=SSPI;"

$conn.open()

$cmd = New-Object System.Data.SqlClient.SqlCommand

$cmd.connection = $conn

foreach ($ctval in $Couters)
{
$Prc = Get-Counter -Counter $ctval

$Val = $Prc.CounterSamples | SELECT Path,@{Name = "Timestamp"; Expression= {$_.timestamp}}, CookedValue

foreach ($Info in $Val)
{
$cmd.commandtext = "INSERT INTO SystemInfo (DateTime,Path,Value)
VALUES('{0}','{1}','{2}')" -f $Info.Timestamp.ToString("yyyy-MM-dd HH:mm:ss"),$Info.Path,$Info.CookedValue

$cmd.ExecuteNonQuery()
}
}

$conn.close()
}

catch
{

Write-EventLog -LogName Application -EntryType Error -source 'PSPerformanceCounter' -Message 'Something went wrong' -EventId 1234
$conn.close()
}

Step 04: Enjoy 🙂

Advertisements