Wednesday, July 4, 2012

Using Powershell and Logman to deploy Counter Logs

In my working environment I have the necessity of automating most of my administration tasks in order to be able to pass them to other people or to keep the solution I have found at hand in case I have to do it again.

Powershell scripting is often my first choice in Windows farms, for its simplicity and for the capacity it has to integrate with older tools.

Last week I was trying to detect a widespread performance problem on a large farm of hundreds of Windows 2003 servers, and I decided to use Perfmon counters. Of course I knew well of the existence of Logman as a valid solution for deploying remote Counter Logs. My idea was then to use it and to pass two arguments to it: a list of servers and a list of counters.

On the Internet there are many resources explaining you how you can massively deploy Counter Logs to remote systems but none of them take care of explaining how you can start a remote Collection from Powershell, nor how to solve one of the most common problems you can face trying to do it

In fact, you will surely get two events when starting remote Counter Collections.

The first one is:
  • Event Type:    Warning
  • Event Source:    SysmonLog
  • Event ID:    2046
  • Description: The service was unable to add the counter '\\servername.domaine.com\Process(_Total)\Working Set' to the perf_servername log or alert. This log or alert will continue, but data for that counter will not be collected. Use the Run As option in the configuration program to run the log under  an account that has access to the performance data on the computer  from which you are collecting data.
The second one is:
  • Event Type:    Warning
  • Event Source:    SysmonLog
  • Event ID:    2029
  • Description: The service was unable to add any counters to the perf_servername log or alert.   This log or alert will not be started.

This errors are due to the fact that the when you use the Start command on a Collection, you are using a user account which is not part of the Local Administrators group. To solve this issue, when you call Logman from your Powershell script to create the Counter Logs, you have to explicitly specify the '-u' parameter. This parameter defines the user account that will be used to start the Collection. This way you can be sure that you are using the account of your choice and not the account which is used to start the 'Performance Counter and Logs' service (this could be the Local System account or the Network Service account, and both may lack the needed permissions).
$strCMD1 = "C:\Windows\System32\logman.exe create counter perf_$server -s $server -si $frequence -cf $pwd\$server.txt -f $logtype -v mmddhhmm -o C:\PerfLogs\log_$server -rf $max_duration -max $max_size -u adminaccount [adminpassword]
Once you have created your Collection, you have to start it. My choice was to use an invocation to a WMI method (thaks Scripting Guy!) on the class Win32_Process:
$startprocess = Invoke-WmiMethod -ComputerName $server -Class Win32_Process -Name Create -ArgumentList "logman.exe start perf_$server"
There are other ways to do this step. For instance you could use the DataCollectorSet interface (see here). Or you could have used Logman itself:
$strCMD2 = "C:\Windows\System32\logman.exe start perf_$server"
But I like to use WMI so in this example I will stick to it. Here's my full script (tested under Powershell 3.0):
$pwd = "c:\rootfolder"
$counters = @(gc $pwd\perfmon_counters.txt) # List of counters one per line
$servers = @(gc $pwd\perfmon_list.txt) # List of remote computers one per line
$frequence = "00:00:30" #hh:mm:ss
$logtype = "bincirc" # possibles: bin,bincirc,csv,tsv
$max_duration = "168:00:00" # 7 days
$max_size = "50" # megabytes
$l = $servers.length
$i = 0
foreach ($server in $servers)
{
$counters | % {$_ -replace "", "\\$server"} | sc $pwd\$server.txt
Write-Progress -Activity "Setting up Collections...." -Status "Collection: $i of $l" -PercentComplete (100*$i/$l)
$strCMD1 = "C:\Windows\System32\logman.exe create counter perf_$server -s $server -si $frequence -cf $pwd\$server.txt -f $logtype -v mmddhhmm -o C:\PerfLogs\log_$server -rf $max_duration -max $max_size -u adminaccount adminpassword"
$i++
Invoke-Expression $strCMD1
Start-Sleep -Milliseconds 100
$startprocess = Invoke-WmiMethod -ComputerName $server -Class Win32_Process -Name Create -ArgumentList "logman.exe start perf_$server"
ri $pwd\$server.txt
}
If you are interested in a list of basic counters to watch, here's my suggestion:
\Processor(*)\% Processor Time
\Processor(*)\% User Time
\Processor(*)\% Privileged Time
\Physicaldisk(*)\Current Disk Queue Length
\Physicaldisk(*)\% Disk Time
\Physicaldisk(*)\Avg. Disk Queue Length
\Physicaldisk(*)\% Disk Write Time
\Physicaldisk(*)\Avg. Disk sec/Read
\Physicaldisk(*)\Avg. Disk sec/Write
\Physicaldisk(*)\Disk Reads/sec
\Physicaldisk(*)\Disk Writes/sec
\Physicaldisk(*)\Disk Read Bytes/sec
\Physicaldisk(*)\Disk Write Bytes/sec
\Physicaldisk(*)\% Idle Time
\Network Interface(*)\Packets Received/sec
\Network Interface(*)\Packets Sent/sec
\Network Interface(*)\Bytes Received/sec
\Network Interface(*)\Bytes Sent/sec
\Network Interface(*)\Output Queue Length
\Memory\Committed Bytes
\Memory\Pages/sec
\Memory\Cache Bytes
\Memory\% Committed Bytes In Use
\Memory\Available MBytes
\Memory\Transition Faults/sec
\LogicalDisk(*)\% Free Space
\LogicalDisk(*)\Free Megabytes
Please do not hesitate to comment or twit if you have found this post useful!

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...