Troubleshooting SharePoint Performance issues are probably the most challenging issues for a SharePoint Administrator to troubleshoot.   Collecting Performance Monitor output can take time because not only must you understand the options available in the UI, but you also need to know which counters to add.   Microsoft does have some automation available to assists in this area by using publicly available PLA interfaces.  I wrote a PowerShell script that any SharePoint Administrator can save off to a Web Front-End, run, and start Performance Gathering in a quick and efficient manner.  First, I’d like to give a super huge thanks to Brad Rutkowski.  He tipped me off that this was possible using PowerShell by creating –com objects and leveraging the PLA interfaces.  His blog documenting interacting with data collector sets is here:

http://blogs.technet.com/b/brad_rutkowski/archive/2009/02/18/interacting-with-data-collector-sets-via-powershell.aspx

The publicly available PLA interfaces and MSDN documentation was a great help as well. 

http://msdn.microsoft.com/en-us/library/aa372243(v=VS.85).aspx

Also, the Windows SDK provided some slick samples of how to do this in CPP. 

 

Reasons why I wrote this script:

  1. To write something that was publicly available outside the SharePoint object model
  2. To automate a task that takes much longer to implement in the UI
  3. To provide more configurable options to the user running the script

In order to run this, save the below script to a text editor like notepad.   Save the file with a .ps1 extension to a SharePoint server.   To run the file from PowerShell, run .\yourfilename.ps1

Important:  I successfully tested this script on both SharePoint 2007 and SharePoint 2010 installed on Windows 2008.  This script will prompt the user to input the maximum size in MB for the performance monitor log.  When the maximum size is reached,  a new performance log (file) is created and used.  This cycle continues until the Performance Data Collection is manually stopped.   I confirmed this script can run against remote SharePoint servers which means you won’t be required to run this script on each SharePoint Server.  Rather, you can run it from one SharePoint server and for each time you run the script, specify the destination SharePoint Server.   I provided an option in the script to allow for automatically starting the Data Collector to immediately start collecting performance data.   Below is a sample run I performed and I set opted to have the script automatically start the data collector called SharePointRocks.  

What the script looks like

SharePointPerformance1

 

Data Collector set automatically started

SharePointPerformance2

 

Script is below.  Enjoy!

 

#######################
#Grab Initial Settings#
#######################
$Name = Read-Host "Enter a name your Data Collector Set?"
$Machine = Read-Host "Enter the SharePoint Server Name to monitor"
$Sample = Read-Host "Please Enter sample interval in Seconds"
$output = Read-Host "Please enter location for the output (For Example: C:\Perflogs)"
Write-host "Please enter the maximum size of each output file in MB"
$buffer = Read-Host "I recommend 250"


############################
#Create the Data Collector Set#
############################
$DataCollSet = new-object -ComObject pla.DataCollectorSet
$DataCollSet.DisplayName = $Name


#######################
#Create a Data Collector#
#######################
$DataCollector = $DataCollSet.DataCollectors.CreateDataCollector(0)
$DataCollector.name = "SharePoint - Collect"
$filename = $Machine + ".blg"
$DataCollector.FileName = $filename
$DataCollector.FileNameFormat = 0x4000
$DataCollector.SampleInterval = $Sample


######################################################################
#Building up Array of counters and adding as property to the Datacollector#
######################################################################
$counters = @("\ASP.NET v2.0.50727\*","\ASP.NET Apps v2.0.50727(*)\*", "\.NET CLR Networking(*)\*", "\.NET CLR Memory(*)\*", "\.NET CLR Exception(*)\*", "\.NET CLR Loading(*)\*", "\.NET Data Provider for SqlServer(*)\*", "\Processor(*)\*", "\Process(*)\*", "\LogicalDisk(*)\*", "\Memory\*", "\Network Interface(*)\*", "\PhysicalDisk(*)\*", "\Web Service(*)\*", "\Web Service Cache\*", "\System\*", "\TCPv4\*", "\TCPV6\*", "\SharePoint Publishing Cache(*)\*", "\OSS Search Gatherer\*")
$DataCollector.PerformanceCounters = $counters


########################################################################
#Add the data collector to the data collector set and set additional properties#
########################################################################

try
{
    $DataCollSet.DataCollectors.Add($DataCollector)
    $DataCollSet.Segment = "VARIANT_TRUE"
    $DataCollSet.SegmentMaxSize = $buffer
    $DataCollSet.RootPath = $output

    $DataCollSet.Commit($Name, $machine, 0x0003)

    Write-Host "The Data Collector set has been created Successfully." -ForegroundColor Green
   
}
catch [Exception]
    {
      Write-Host "Exception Caught: " $_.Exception -ForegroundColor Red
      return
    }
   
   
Write-Host "Would you like to automatically start the data collection?"
$decide = Read-Host "Press 1 or yes or 2 for no"


if($decide = 1)
{
    try
    {
    $DataCollSet.Start($true)
    Write-Host "Operation Completed Successfully" -ForegroundColor Green
    Write-Host
    }
    catch [Exception]
    {
      Write-Host "Exception Caught: " $_.Exception -ForegroundColor Red
      return
    }
}

else
{
    Write-Host
    Write-Host "To access and start this Data Collector set:"
    Write-Host "1. Select Start, Run, and type Perfmon (press enter)"
    Write-Host "2. Expand Data Collector Sets\User Defined"
    Write-Host "3. Right click on desired data collector set to Start"
}

Write-Host
Write-Host "Script Completed"

 

Thanks!

Russ Maxwell, MSFT  Alien