Top 10 Process Listing By Memory Consumption – GUI Tool

This Powershell GUI tool is used to list Top 10 memory consumption process of a given computer[local /Remote]. In the screen that follows, enter the computer name that you would like to get the top 10 processes and hit Get Process button.

This pulls out the memory consumed by top process of the given computer. If you don’t make an entry, then by default local machine details will be displayed.  If you give a wrong name then message box will be pop up stating its reason for not connecting.

The code is tested in all version of Powershell. You need to have .Net framework 3.0 or 3.5 as its pre-requisites for 3D Graph Display.

you can run the downloaded file from Powershell ISE or directly in Powershell console.

Download TOP 10 Process Memory Consumption

Image

CODE:

#======================================================================== 
# Generated On: 02/07/2014 
# Generated By: Prashanth Jayaram 
# Version     : 1.0 
# Description : TOP 10 Process - Memory consumption Report - 3D Graph 
#======================================================================== 

function OnApplicationLoad { 

 if([Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization") -eq $null) 
 { 
  #Microsoft Chart Controls are not installed 
  [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") 
  [void][System.Windows.Forms.MessageBox]::Show("Microsoft Chart Controls for Microsoft .NET 3.5 Framework is required","Microsoft Chart Controls Required") 
  #Open the URL 
  [System.Diagnostics.Process]::Start("http://www.microsoft.com/downloads/en/details.aspx?familyid=130F7986-BF49-4FE5-9CA8-910AE6EA442C&displaylang=en"); 
  return $false 
 } 

 return $true #return true for success or false for failure 
} 

function OnApplicationExit { 
 #Note: This function is not called in Projects 
 #Note: This function runs after the form is closed 
 #TODO: Add custom code to clean up and unload snapins when the application exits 

 $script:ExitCode = 0 #Set the exit code for the Packager 
} 

#endregion Application Functions 

#---------------------------------------------- 
# Generated Form Function 
#---------------------------------------------- 
function Call-SystemInformation_pff { 

 #---------------------------------------------- 
 #region Import the Assemblies 
 #---------------------------------------------- 
 [void][reflection.assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") 
 [void][reflection.assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") 
 [void][reflection.assembly]::Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") 
 [void][reflection.assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") 
 [void][reflection.assembly]::Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") 
 [void][reflection.assembly]::Load("System.Windows.Forms.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35") 
 #endregion Import Assemblies 

 #---------------------------------------------- 
 #region Generated Form Objects 
 #---------------------------------------------- 
    [System.Windows.Forms.Application]::EnableVisualStyles() 
    $formProcessPieChart = New-Object System.Windows.Forms.Form 
    $dataGrid1 = New-Object System.Windows.Forms.DataGrid  
    $chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart 
    $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState 
    $btnRefresh = New-Object System.Windows.Forms.Button 
    $btnClear = New-Object System.Windows.Forms.Button 
    $btngetdata=New-Object System.Windows.Forms.Button 
    $rtbPerfData = New-Object System.Windows.Forms.RichTextBox 
    $lblServicePack = New-Object System.Windows.Forms.Label 
    $lblDBName= New-Object System.Windows.Forms.Label 
    $lblOS = New-Object System.Windows.Forms.Label 
    $statusBar1 = New-Object System.Windows.Forms.StatusBar 
    $btnClose = New-Object System.Windows.Forms.Button 
    $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState 
    $txtComputerName = New-Object System.Windows.Forms.TextBox 
    $dataGrid1 = New-Object System.Windows.Forms.DataGrid  

 function Load-Chart 
 { 
  Param( #$XPoints, $YPoints, $XTitle, $YTitle, $Title, $ChartStyle) 
   [Parameter(Position=1,Mandatory=$true)] 
     [System.Windows.Forms.DataVisualization.Charting.Chart]$ChartControl 
   , 
   [Parameter(Position=2,Mandatory=$true)] 
     $XPoints 
   , 
   [Parameter(Position=3,Mandatory=$true)] 
     $YPoints 
   , 
   [Parameter(Position=4,Mandatory=$false)] 
     [string]$XTitle 
   , 
   [Parameter(Position=5,Mandatory=$false)] 
     [string]$YTitle 
   , 
   [Parameter(Position=6,Mandatory=$false)] 
     [string]$Title 
   , 
   [Parameter(Position=7,Mandatory=$false)] 
     [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]$ChartType 
   , 
   [Parameter(Position=8,Mandatory=$false)] 
     $SeriesIndex = 0 
   , 
   [Parameter(Position=9,Mandatory=$false)] 
     $TitleIndex = 0, 
   [switch]$Append) 

  $ChartAreaIndex = 0 
  if($Append) 
  { 
   $name = "ChartArea " + ($ChartControl.ChartAreas.Count + 1).ToString(); 
   $ChartArea = $ChartControl.ChartAreas.Add($name) 
   $ChartAreaIndex = $ChartControl.ChartAreas.Count - 1 

   $name = "Series " + ($ChartControl.Series.Count + 1).ToString(); 
   $Series = $ChartControl.Series.Add($name)  
   $SeriesIndex = $ChartControl.Series.Count - 1 

   $Series.ChartArea = $ChartArea.Name 

   if($Title) 
   { 
    $name = "Title " + ($ChartControl.Titles.Count + 1).ToString(); 
    $TitleObj = $ChartControl.Titles.Add($name) 
    $TitleIndex = $ChartControl.Titles.Count - 1  
    $TitleObj.DockedToChartArea = $ChartArea.Name 
    $TitleObj.IsDockedInsideChartArea = $false 
   } 
  } 
  else 
  { 
   if($ChartControl.ChartAreas.Count -eq  0) 
   { 
    $name = "ChartArea " + ($ChartControl.ChartAreas.Count + 1).ToString(); 
    [void]$ChartControl.ChartAreas.Add($name) 
    $ChartAreaIndex = $ChartControl.ChartAreas.Count - 1 
   }  

   if($ChartControl.Series.Count -eq 0) 
   { 
    $name = "Series " + ($ChartControl.Series.Count + 1).ToString(); 
    $Series = $ChartControl.Series.Add($name)  
    $SeriesIndex = $ChartControl.Series.Count - 1 
    $Series.ChartArea = $ChartControl.ChartAreas[0].Name 
   } 
  } 

  $Series = $ChartControl.Series[$SeriesIndex] 
  $ChartArea = $ChartControl.ChartAreas[$Series.ChartArea] 

  $Series.Points.Clear() 

  if($Title) 
  { 
   if($ChartControl.Titles.Count -eq 0) 
   { 
    $name = "Title " + ($ChartControl.Titles.Count + 1).ToString(); 
    [void]$ChartControl.Titles.Add($name) 
    $TitleIndex = $ChartControl.Titles.Count - 1 
    $TitleObj.DockedToChartArea = $ChartArea.Name 
    $TitleObj.IsDockedInsideChartArea = $false 
   } 

   $ChartControl.Titles[$TitleIndex].Text = $Title 
  } 

  if($ChartType) 
  { 
   $Series.ChartType = $ChartType 
  } 

  if($XTitle) 
  { 
   $ChartArea.AxisX.Title = $XTitle 
  } 

  if($YTitle) 
  { 
   $ChartArea.AxisY.Title = $YTitle 
  } 

  if($XPoints -isnot [Array] -or $XPoints -isnot [System.Collections.IEnumerable]) 
  { 
   $array = New-Object System.Collections.ArrayList 
   $array.Add($XPoints) 
   $XPoints = $array 
  } 

  if($YPoints -isnot [Array] -or $YPoints -isnot [System.Collections.IEnumerable]) 
  { 
   $array = New-Object System.Collections.ArrayList 
   $array.Add($YPoints) 
   $YPoints = $array 
  } 

  $Series.Points.DataBindXY($XPoints, $YPoints) 

 } 

 function Clear-Chart 
 { 
  Param (   
  [Parameter(Position=1,Mandatory=$true)] 
    [System.Windows.Forms.DataVisualization.Charting.Chart]$ChartControl 
  , 
  [Parameter(Position=2, Mandatory=$false)] 
  [Switch]$LeaveSingleChart 
  ) 

  $count = 0  
  if($LeaveSingleChart) 
  { 
   $count = 1 
  } 

  while($ChartControl.Series.Count -gt $count) 
  { 
   $ChartControl.Series.RemoveAt($ChartControl.Series.Count - 1) 
  } 

  while($ChartControl.ChartAreas.Count -gt $count) 
  { 
   $ChartControl.ChartAreas.RemoveAt($ChartControl.ChartAreas.Count - 1) 
  } 

  while($ChartControl.Titles.Count -gt $count) 
  { 
   $ChartControl.Titles.RemoveAt($ChartControl.Titles.Count - 1) 
  } 

  if($ChartControl.Series.Count -gt 0) 
  { 
   $ChartControl.Series[0].Points.Clear() 
  } 
 } 
 #endregion 

<# 
 $FormEvent_Load={ 
  #TODO: Initialize Form Controls here 
  Load-PieChart  
 } 
 #> 

 Function  Load-PieChart { 
 Param([string]$computername) 
  $Chart.ChartAreas.Add($ChartArea) 

$process = [System.Diagnostics.Process] 

$Processes = $process::GetProcesses($computername)|Sort-Object WS -Descending|select Handles,  
@{Label="NPM(K)";Expression={[int]($_.NPM/1024)}}, ` 
@{Label="PM(K)";Expression={[int]($_.PM/1024)}}, ` 
@{Label="WS";Expression={[int]($_.WS/1024)}}, ` 
@{Label="VM(M)";Expression={[int]($_.VM/1MB)}}, ` 
Id, ProcessName, MachineName -first 9 

$ProcNames = @(foreach($Proc in $Processes){$Proc.ProcessName+ "_"+$Proc.ID})  
$WS = @(foreach($Proc in $Processes){$Proc.WS/1KB}) 

$Chart.Series.Add("Data")  
$Chart.Series["Data"].Points.DataBindXY($ProcNames, $WS) 

$ChartArea.AxisX.Title = "Process"  
$ChartArea.AxisY.Title = "Working Set (KB)" 

# Find point with max/min values and change their colour  
$maxValuePoint = $Chart.Series["Data"].Points.FindMaxByValue()  
$maxValuePoint.Color = [System.Drawing.Color]::Red 

$minValuePoint = $Chart.Series["Data"].Points.FindMinByValue()  
$minValuePoint.Color = [System.Drawing.Color]::Green 

# make bars into 3d cylinders  
#$Chart.Series["Data"]["DrawingStyle"] = "Cylinder" 
$chartArea.Area3DStyle = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea3DStyle  -Property @{Enable3D=$true; IsRightAngleAxes=$false; Rotation=10; Inclination=10;} 

# display the chart on a form  
$Chart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor  
                [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left  

 } 

 Function Get-ProcPerf { 
    Param([string]$computername) 
 $Object =@() 
$array = New-Object System.Collections.ArrayList       
    # load the appropriate assemblies  
# add data to chart  
$process = [System.Diagnostics.Process] 
#$process::GetProcesses($server) 

$prc=$process::GetProcesses($computername)|Sort-Object WS -Descending|select Handles, ` 
@{Label="NPM";Expression={[int]($_.NPM/1024)}}, ` 
@{Label="PM";Expression={[int]($_.PM/1MB)}}, ` 
@{Label="WS";Expression={[int]($_.WS/1MB)}}, ` 
@{Label="VM";Expression={[int]($_.VM/1MB)}}, ` 
Id, ProcessName, MachineName -first 9 

$Object =@() 

foreach ($p in $prc)  
{ 
$Object += New-Object PSObject -Property @{ 
            Handles = $p.Handles; 
            NPM = $P.NPM; 
            PM = $P.PM; 
            WoringSet = $P.WS; 
            VM= $P.VM; 
            ID=$P.Id; 
            Name=$P.ProcessName; 
            SrvName=$P.MachineName 

          } 
} 

$column1 = @{expression="MachineName"; width=20; label="MachineName"; alignment="left"} 
$column2 = @{expression="Handles"; width=10; label="Handles"; alignment="left"} 
$column3 = @{expression="NPM"; width=10; label="NPM(K)"; alignment="left"} 
$column4 = @{expression="PM"; width=10; label="PM(K)"; alignment="left"} 
$column5 = @{expression="WS"; width=10; label="WS(K)"; alignment="left"} 
$column6 = @{expression="VM"; width=10; label="VM(MB)"; alignment="left"} 
$column7 = @{expression="id"; width=10; label="ProcessID"; alignment="left"} 
$column8 = @{expression="Name"; width=15; label="ProcessName"; alignment="left"} 

"#"*80 
"Process Information" 
"Generated $(get-date)" 
"Generated from $(gc env:computername)" 
"#"*80 

#$Object  
$Object |Format-Table  $column1,$column2,$column3,$column4,$column5,$column6,$column7,$column8 

$array.AddRange($Object)  
$dataGrid1.DataSource = $array  

} 

function Clear-Chart 
 { 
  Param (   
  [Parameter(Position=1,Mandatory=$true)] 
    [System.Windows.Forms.DataVisualization.Charting.Chart]$ChartControl 
  , 
  [Parameter(Position=2, Mandatory=$false)] 
  [Switch]$LeaveSingleChart 
  ) 

  $count = 0  
  if($LeaveSingleChart) 
  { 
   $count = 1 
  } 

  while($ChartControl.Series.Count -gt $count) 
  { 
   $ChartControl.Series.RemoveAt($ChartControl.Series.Count - 1) 
  } 

  while($ChartControl.ChartAreas.Count -gt $count) 
  { 
   $ChartControl.ChartAreas.RemoveAt($ChartControl.ChartAreas.Count - 1) 
  } 

  while($ChartControl.Titles.Count -gt $count) 
  { 
   $ChartControl.Titles.RemoveAt($ChartControl.Titles.Count - 1) 
  } 

  if($ChartControl.Series.Count -gt 0) 
  { 
   $ChartControl.Series[0].Points.Clear() 
  } 
 } 

$cleardata={ 
Clear-Chart $chart 

} 

 $GetData={ 
      Clear-Chart $chart 

        if ($txtComputerName.text -eq '') 
        { 
        $txtComputerName.text =$env:COMPUTERNAME 
        } 
        $statusBar1.text="Getting Process information ..please wait" 
        if(Test-Connection -ComputerName $txtComputerName.text -Count 1 -ea 0) {  
        $data=Get-ProcPerf -ComputerName $txtComputerName.text | Out-String 

        Load-PieChart -computername $txtComputerName.text 

   } 
        else 
        { 
        [Windows.Forms.MessageBox]::Show(“Not able connect to the server", [Windows.Forms.MessageBoxIcon]::Information) 
        } 
        #$rtbPerfData.text=$data.Trim() 
        $errorActionPreference="Continue" 
        $statusBar1.Text="Ready" 

    } 

    $Close={ 
        $formProcessPieChart.close() 

    } 
 # --End User Generated Script-- 
 #---------------------------------------------- 
 # Generated Events 
 #---------------------------------------------- 

 $Form_StateCorrection_Load= 
 { 
  #Correct the initial state of the form to prevent the .Net maximized form issue 
  $formProcessPieChart.WindowState = $InitialFormWindowState 
 } 

 #---------------------------------------------- 
 #region Generated Form Code 
 #---------------------------------------------- 
 # 
 # formProcessPieChart 
 # 
 $formProcessPieChart.Controls.Add($buttonSave) 
 $formProcessPieChart.Controls.Add($chart) 
 $formProcessPieChart.ClientSize = New-Object System.Drawing.Size(513,640) 
 $formProcessPieChart.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
 $formProcessPieChart.MinimumSize = New-Object System.Drawing.Size(300,300) 
 $formProcessPieChart.Name = "formProcessPieChart" 
 $formProcessPieChart.Text = "Disk Space Pie Chart" 
 $formProcessPieChart.Controls.Add($btnRefresh) 
 $formProcessPieChart.Controls.Add($lblServicePack) 
 $formProcessPieChart.Controls.Add($lblOS) 
 $formProcessPieChart.Controls.Add($lblDBName) 
 $formProcessPieChart.Controls.Add($statusBar1) 
 $formProcessPieChart.Controls.Add($btnClose) 
 $formProcessPieChart.Controls.Add($txtComputerName) 
 $formProcessPieChart.ClientSize = New-Object System.Drawing.Size(630,630) 
 $formProcessPieChart.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
 $formProcessPieChart.Name = "form1" 
 $formProcessPieChart.Text = "Process Information" 
 $formProcessPieChart.add_Load($PopulateList) 
 $formProcessPieChart.add_Load($FormEvent_Load) 

$System_Drawing_Size = New-Object System.Drawing.Size  
$System_Drawing_Size.Width = 600  
$System_Drawing_Size.Height = 225 
$dataGrid1.Size = $System_Drawing_Size  
$dataGrid1.DataBindings.DefaultDataSourceUpdateMode = 0  
$dataGrid1.HeaderForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)  
$dataGrid1.Name = "dataGrid1"  
$dataGrid1.DataMember = ""  
$dataGrid1.TabIndex = 0  
$System_Drawing_Point = New-Object System.Drawing.Point  
$System_Drawing_Point.X =13  
$System_Drawing_Point.Y = 62 
$dataGrid1.Location = $System_Drawing_Point  

$formProcessPieChart.Controls.Add($dataGrid1)  
$dataGrid1.CaptionText='Process Details' 

    # 
    # btnRefresh 
    # 
    $btnRefresh.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $btnRefresh.Enabled = $TRUE 
    $btnRefresh.Location = New-Object System.Drawing.Point(230,35) 
    $btnRefresh.Name = "btnRefresh" 
    $btnRefresh.Size = New-Object System.Drawing.Size(95,20) 
    $btnRefresh.TabIndex = 2 
    $btnRefresh.Text = "GetProcess" 
    $btnRefresh.UseVisualStyleBackColor = $True 
    $btnRefresh.add_Click($GetData) 
    # 
    # 

    $btnClose.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $btngetdata.Enabled = $TRUE 
    $btnClose.Location = New-Object System.Drawing.Point(328,35) 
    $btnClose.Name = "btnClose" 
    $btnClose.Size = New-Object System.Drawing.Size(95,20) 
    $btnClose.TabIndex = 3 
    $btnClose.Text = "Close" 
    $btnClose.UseVisualStyleBackColor = $True 
    $btnClose.add_Click($Close) 
    # 

    # lblDBName 
    # 
    $lblDBName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $lblDBName.Font = New-Object System.Drawing.Font("Lucida Console",8.25,1,3,1) 
    $lblDBName.Location = New-Object System.Drawing.Point(13,10) 
    $lblDBName.Name = "lblDBName" 
    $lblDBName.Size = New-Object System.Drawing.Size(178,23) 
    $lblDBName.TabIndex = 0 
    $lblDBName.Text = "Enter Server Name " 
    $lblDBName.Visible = $TRUE 
    # 

    #$txtComputerName.text 
    #txtComputerName 
    $txtComputerName.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $txtComputerName.Location = New-Object System.Drawing.Point(13, 35) 
    $txtComputerName.Name = "txtComputerName" 
    $txtComputerName.TabIndex = 1 
    $txtComputerName.Size = New-Object System.Drawing.Size(200,70) 
    $txtComputerName.visible=$TRUE 
    # 
    # lblServicePack 
    # 
    $lblServicePack.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $lblServicePack.Font = New-Object System.Drawing.Font("Lucida Console",8.25,1,3,1) 
    $lblServicePack.Location = New-Object System.Drawing.Point(13,100) 
    $lblServicePack.Name = "lblServicePack" 
    $lblServicePack.Size = New-Object System.Drawing.Size(278,23) 
    $lblServicePack.TabIndex = 0 
    $lblServicePack.Text = "ServicePack" 
    $lblServicePack.Visible = $False 
    # 
    # lblOS 
    # 
    $lblOS.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $lblOS.Font = New-Object System.Drawing.Font("Lucida Console",8.25,1,3,1) 
    $lblOS.Location = New-Object System.Drawing.Point(12,77) 
    $lblOS.Name = "lblOS" 
    $lblOS.Size = New-Object System.Drawing.Size(278,23) 
    $lblOS.TabIndex = 2 
    $lblOS.Text = "Service Information" 
    $lblOS.Visible = $False 
    # 
    # statusBar1 
    # 
    $statusBar1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation  
    $statusBar1.Location = New-Object System.Drawing.Point(0,365) 
    $statusBar1.Name = "statusBar1" 
    $statusBar1.Size = New-Object System.Drawing.Size(390,22) 
    $statusBar1.TabIndex = 5 
    $statusBar1.Text = "statusBar1" 

    $Chart.Width = 600  
    $Chart.Height = 300  
    $Chart.Left = 10  
    $Chart.Top = 300 
    $ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea  

 #Save the initial state of the form 
 $InitialFormWindowState = $formProcessPieChart.WindowState 
 #Init the OnLoad event to correct the initial state of the form 
 $formProcessPieChart.add_Load($Form_StateCorrection_Load) 
 #Show the Form 
 return $formProcessPieChart.ShowDialog() 

} #End Function 

if(OnApplicationLoad -eq $true) 
{ 
    #Create the form 
    #Call-SystemInformation_pff | Out-Null 
    #Call-Disk_Space_Chart_pff | Out-Null 
    Call-SystemInformation_pff | Out-Null 
    #Perform cleanup 
    OnApplicationExit 
}
Advertisements

About Prashanth Jayaram

I’m a Database technologist having 11+ years of rich, hands-on experience on Database technologies. I am Microsoft Certified Professional and backed with a Degree in Master of Computer Application. My expertise lies in T-SQL programming, Replication and PowerShell You can connect me via https://social.technet.microsoft.com/profile/prashanth jayaram/ http://www.sqlshack.com/author/prashanth/ https://www.tumblr.com/blog/prashantjayaram http://www.sqlservercentral.com/blogs/powersql-by-prashanth-jayaram/ http://www.toadworld.com/members/prashanthjayaram/ My Articles are published in following sites http://www.ssas-info.com/analysis-services-articles/ http://db-pub.com/ http://www.sswug.org/sswugresearch/community/
This entry was posted in PowerShell and tagged , , , . Bookmark the permalink.

2 Responses to Top 10 Process Listing By Memory Consumption – GUI Tool

  1. Jim says:

    Prashanth … excellent, excellent work. This is a tough one to get information on and you did it wonderfully. Thank you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s