Home > Uncategorized > Build SCOM *Like* SharePoint Dashboards with PowerShell (Utilization, HTTP Response, App Pool Status)

Build SCOM *Like* SharePoint Dashboards with PowerShell (Utilization, HTTP Response, App Pool Status)

I recently blogged about how to build a SCOM Like dashboard for SharePoint by pulling statistics from our network load balancer application (F5 – Big IP). You can find the blog here – https://shipoint.com/2017/03/01/scom-like-reports-for-sharepoint-using-powershell-f5-big-ip/

Now i’m going to show you how to build SCOM *like* dashboards for SharePoint by displaying information regarding Server Utilization (Memory, CPU, Storage), HTTP Responses, and App Pool Status for all servers in the farm. Since SCOM is not fully integrated into our systems yet I had to turn to Powershell to get the results I want. This helps to get a snapshot of current statitics from the SharePoint servers instead of having to visit each server to grab what is needed. These reports are generated into HTM pages that can be viewed in a browser.

Below is the script I generted to get the dashboards and displays results.

Remove-Item c:\scripts\SharePoint-Server-Health.htm

[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.Web.Administration')

$ServerListFile = "c:\temp\ServerList.txt"
$ServerList = Get-Content $ServerListFile -ErrorAction SilentlyContinue
$ServerListAppsFile = "c:\temp\ServerList_Apps.txt"
$ServerListApps = Get-Content $ServerListAppsFile -ErrorAction SilentlyContinue
$URLListFile = "c:\temp\URLList.txt"
$URLList = Get-Content $URLListFile -ErrorAction SilentlyContinue

$Result = @()
$Result_HTTP = @()
#$Result_AppPools = @()
$Date = Get-Date -format g

ForEach($computername in $ServerList)
{
	$AVGProc = Get-WmiObject -computername $computername win32_processor | Measure-Object -propert LoadPercentage -Average | Select Average
	$OS = gwmi -Class win32_operatingsystem -computername $computername |
	select-object @{Name = "MemoryUsage"; Expression = {"{0:N2}" -f
	((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/$_.TotalVisibleMemorySize)}}
	$vol = Get-WmiObject -Class win32_Volume -ComputerName $computername -Filter "DriveLetter = 'C:'" |
	select-object @{Name = "C PercentFree"; Expression = {"{0:N2}" -f (($_.FreeSpace / $_.Capacity)*100) }}

	$result += [PSCustomObject] @{
	ServerName = "$computername"
	CPULoad = "$($AVGProc.Average)%"
	MemLoad = "$($OS.MemoryUsage)%"
	CDrive = "$($vol.'C PercentFree')%"
	}

	$Outputreport = "<HTLM><HEAD><META HTTP-EQUIV=""refresh"" content=""240""><TITLE> SharePoint Server Health Reports </TITLE></HEAD>
		<BODY background-color:peachpuff vlink=""black"" link=""black"" alink=""black"">
		<font color =""#99000"" face=""Microsoft Tai le"">
		<center><H2> SharePoint Server Health Report </H2></font>
		*Statistics refresh every 5 mins.  Page automatically refreshes every 90 seconds.
		</br>
		<U>Last Update:</U> $Date (Server Time)</center></br>
		<font color =""#99000"" face=""Microsoft Tai le"">
		<H2>SharePoint Utilization Status</H2></font>
		<Table border=1 cellpadding=0 cellspacing=0>
		<TR bgcolor=gray align=center>
		<TD><B>Server Name</B></TD>
		<TD><B>CPU Utilization</B></TD>
		<TD><B>Memory Utilization</B></TD>
		<TD><B>C Drive Utilization</B></TD></TR>"

	Foreach($Entry in $Result)
	{
		if((($Entry.CPULoad) -and ($Entry.MemLoad)) -ge "80")
		{
			#$Ouputreport += "<TD bgcolor=red>"
			#$Outputreport += "<TD>$($Entry.Servername)</TD><TD bgcolor=red align=center>$($Entry.CPULoad)</TD><TD bgcolor=red align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.CDrive)</TD></TR>"
		}
		else
		{
			#$Ouputreport += "<TR>"
			#$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.CDrive)</TD></TR>"
		}
		$Outputreport += "<TD>$($Entry.Servername)</TD><TD align=center>$($Entry.CPULoad)</TD><TD align=center>$($Entry.MemLoad)</TD><TD align=center>$($Entry.CDrive)</TD></TR>"
	}
	$Outputreport += "</Table>"
}


#Build Table for HTTP Status#

ForEach ($url in $URLList)
{
	$xHTTP = New-Object -com msxml2.xmlhttp;
	$xHTTP.open("GET", $url, $false)
	$xHTTP.send();
	write-host $url
	$HTTPStatus = $xHTTP.status

	$HTTPStatusText = $xHTTP.statusText

	if ($HTTPStatus -eq 400)
	{
		$HTTPStatusText = "Bad Request"
	}
	if ($HTTPStatus -eq 403)
	{
		$HTTPStatusText = "Forbidden"
	}
	if ($HTTPStatus -eq 401)
	{
		$HTTPStatusText = "Unauthorized"
	}
	if ($HTTPStatus -eq 404)
	{
		$HTTPStatusText = "Not Found"
	}
	if ($HTTPStatus -eq 500)
	{
		$HTTPStatusText = "Internal Server Error"
	}

	$Request = New-Object System.Net.WebClient
	$Request.UseDefaultCredentials = $true
	$Start = Get-Date
	$PageRequest = $Request.DownloadString($url)
	$TimeTaken = ((Get-Date) - $Start).TotalSeconds
	$Request.Dispose()

	
	$result_http += [PSCustomObject] @{
		URL = "$url"
		Status = "$HTTPStatus"
		StatusText = "$HTTPStatusText"
		LoadTime = "$TimeTaken"
		}

		$Outputreport2 = "<font color =""#99000"" face=""Microsoft Tai le"">
		<H2> SharePoint HTTP Status </H2></font>
		<Table border=1 cellpadding=0 cellspacing=0>
		<TR bgcolor=gray align=center>
		<TD><B>URL</B></TD>
		<TD><B>StatusCode</B></TD>
		<TD><B>Status</B></TD>
		<TD><B>Est. Load Times</B></TD></TR>"

		Foreach($Entry in $Result_HTTP)
		{
			if($Entry.Status -eq 200)
			{
				$Outputreport2 += "<TR><TD><a href=$($Entry.URL) target=""_blank"">$($Entry.URL)</a></TD><TD bgcolor=green align=center>$($Entry.Status)</TD><TD align=center>$($Entry.StatusText)</TD><TD align=center>$($Entry.LoadTime)(s)</TD></TR>"
			}
			else
			{
				$Outputreport2 += "<TR><TD>$($Entry.URL)</TD><TD align=center>$($Entry.Status)</TD><TD align=center>$($Entry.StatusText)</TD><TD align=center>$($Entry.LoadTime)(s)</TD></TR>"
			}
	
		}
		$Outputreport2 += "</Table>"	

}
ForEach ($s in $ServerListApps)
{
	$ServerMgr = [Microsoft.Web.Administration.ServerManager]::OpenRemote($s)
	$AppPoolColl = $ServerMgr.ApplicationPools

	$Result_AppPools = "Result_AppPools_" + $s
	$Result_AppPools = @()

	foreach($AppPool in $AppPoolColl)
	{
		$appPoolState = $AppPool.State
		$appPoolName = $AppPool.Name
		#write-host $AppPool.Name
		#Write-Host $appPoolState
	
		$result_apppools += [PSCustomObject] @{
		ServerName = "$s"
		AppPoolName = "$appPoolName"
		AppPoolState = "$appPoolState"
		}

		$Outputreport_apppools = "Outputreport_" + $s

		$Outputreport_apppools = "<font color =""#99000"" face=""Microsoft Tai le"">
		<H2> SharePoint Application Pool Status $s </H2></font>
		<Table border=1 cellpadding=0 cellspacing=0>
		<TR bgcolor=gray align=center>
		<TD><B>Server Name</B></TD>
		<TD><B>AppPoolName</B></TD>
		<TD><B>AppPoolState</B></TD>
		<TD><B>Notes</B></TD></TR>"

		Foreach($Entry in $Result_AppPools)
		{
			if($Entry.AppPoolState -eq "Stopped")
			{
				if ($Entry.AppPoolName -eq "DefaultAppPool" -or $Entry.AppPoolName -eq "SharePoint Web Services Root")
				{
					$notes = "Please Ignore"
				}
				else
				{
					$notes = "Address Immediately"
				}
				$Outputreport_apppools += "<TR><TD>$($Entry.ServerName)</TD><TD align=center>$($Entry.AppPoolName)</TD><TD bgcolor=red align=center>$($Entry.AppPoolState)</TD><TD align=center>$notes</TD></TR>"
				
			}
			else
			{
				$notes = ""
				$Outputreport_apppools += "<TR><TD>$($Entry.ServerName)</TD><TD align=center>$($Entry.AppPoolName)</TD><TD align=center>$($Entry.AppPoolState)</TD><TD align=center>$notes</TD></TR>"
				
			}
						
	
		}
		
		$Outputreport_apppools += "</TABLE>"
	}
	$Outputreport_AppPools_Final += $Outputreport_apppools += "</BODY></HTML>"

}

$final = $Outputreport += $Outputreport2 += $Outputreport_AppPools_Final
$final | out-file c:\scripts\SharePoint-Server-Health.htm
Advertisements
Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

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

%d bloggers like this: