Formatted and colored HTML-table based on a filtered property

Just published a great script to generate a fully colored and formatted HTML-table output from an input PSObject.
Sometimes needed a colored report e.g. disk storage space, CPU or memory usage to warning and/or critical issues.
There are some examples here:

Get-Process | ConvertTo-HtmlTable -Property WS -Warning 1724416 -Critical 2007040 | Out-File test.html
$PSObject = Get-Process
ConvertTo-HtmlTable -PSObject $PSObject -Property WS -Warning 1724416 -Critical 2007040 | Out-File test.html

example

Get-Process | Sort-Object -Property WS -Descending | ConvertTo-HtmlTable -Property WS -Warning 1724416 -Critical 2007040 | Out-File test.html

More formatted Html-Table:

Get-Process | Select Name, Id, PM, VM, WS | ConvertTo-HtmlTable -Property WS -Warning 8712192  -Critical 12984320 -Title "WS Report" -BorderStyle double -HeaderBackgroundColor grey -BackgroundColor lightgrey -Padding 10px | Out-File test.html

example2

Testing site collection availability per content database randomly

I’ve got a task to write a script to test and measure request time on a site collection per content database. However there is a cmdlet Invoke-WebRequest to do do it simple way, I decided to create a function as Get-SPWebRequest to do it, because previous one is not available in Powershell v2.

Where we have Powershell 3v we can start an Invoke-WebRequest with a site url and measure the command with Measure-Command cmdlet.

$result = Measure-Command {Invoke-WebRequest -Uri  -UseDefaultCredentials}
"{0:N2}ms" -f [double]$result.TotalMilliseconds

Anyway there is a function to do the WebRequest:

# Web request with default credentials
Function Get-SPWebRequest ($Url)
    {
        Try
            { 
                $request = [System.Net.WebRequest]::Create($Url)
                $request.UseDefaultCredentials="true"
                $request.method="get"
                $request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED","f")
                $request.TimeOut=120000
                $response = $request.GetResponse()
                return $response
            }
        Catch 
            {
                $regex = [regex]("\d{3}")
                return New-Object PSCustomObject -property @{
                    "StatusDescription" = (($_.exception.innerexception.message -split ":")[1]).Trim()
                    "StatusCode" = [int]$regex.Match($_.exception.innerexception.message).value}
            }
     }

The WebRequest using default credentials, because during the test usually we use farm admin or admin account which has full control permission for all web application on the SharePoint farm. Method is a get method, we just testing and not modifying anything on the site.
During my test I ran into a problem where my request always gave back error code 403 (forbidden) on sites where we use forms base authentication. There is the reason to added (“X-FORMS_BASED_AUTH_ACCEPTED”,”f”) header. It is programmatically access a SharePoint site which uses multiple authentication providers by using Windows credentials. Here is for the MS article which give you the explanation: Retrieving Data from a Multiple-Authentication Site Using the Client Object Model and Web Services in SharePoint 2010.
Try-catch method integrated to catch any other http error code and set them into a custom object as StatusDescription and StatusCode as the request result when it successfully. From the inner exception message I get the status code by regex which is mainly useful to provide outputs based on a pattern from a string. Regex is difficult, but there are lots of help which can be found on the Internet to generate and test for your needs.

After that, when we have the engine for the script, and we only need to collect all content databases and choose one site collection from all randomly to generate the output like this.

Get-SPContentDatabase | %{Get-SPWebRequest -Url $($_.sites[$(Get-Random $_.sites.count)]).url}

And measure the command like this.

Get-SPContentDatabase | 
%{(Measure-Command {Get-SPWebRequest -Url $($_.sites[$(Get-Random $_.sites.count)]).url}).TotalMilliseconds}

Yes, but we would like to see the result nicely and convertible into e.g. .csv or .html format. So, we need have to create a PSCustomObject and put into all properties which needed.
Additionally, I do the request twice to warmup the site before the real measurement and created a DefaultDisplayPropertySet to show only those values which are more important. Any others can be filtered or displayed if needed.
Here is the full script which is also can be found in the MS TechNet Gallery here: Testing a random site collection WebRequest per content database.

# Get all content databases
Function Get-SPContentDatabase
    {
        return $databases = [Microsoft.SharePoint.Administration.SPFarm]::Local | 
            select -expand services | 
                ?{$_ -is [Microsoft.SharePoint.Administration.SPWebService]} |
                    select -expand webapplications | select -expand contentdatabases
    }

# Web request with default credentials
Function Get-SPWebRequest ($Url)
    {
        Try
            { 
                $request = [System.Net.WebRequest]::Create($Url)
                $request.UseDefaultCredentials="true"
                $request.method="get"
                $request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED","f")
                $request.TimeOut=120000
                $response = $request.GetResponse()
                return $response
            }
        Catch 
            {
                $regex = [regex]("\d{3}")
                return New-Object PSCustomObject -property @{
                    "StatusDescription" = (($_.exception.innerexception.message -split ":")[1]).Trim()
                    "StatusCode" = [int]$regex.Match($_.exception.innerexception.message).value}
            }
     }

# Load Microsoft.SharePoint assemly  
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | Out-Null

#Get all content database
$ContentDatabases = Get-SPContentDatabase

$i = 1

#Get database from all content databases
foreach($Database in $ContentDatabases)
    {
        #Progress bar
        Write-Progress -Activity "Gathering WebRequest status per content database" -Status "From $Database" -PercentComplete ($i/$ContentDatabases.count*100)

        #Get random site from content database
        $Site = $Database.Sites[$(Get-Random $Database.Sites.Count)]
        
        #WarmUp
        $WarmUP = Measure-Command {Get-SPWebRequest -Url $Site.Url}

        #Measure command
        $Result = Measure-Command {$Request = Get-SPWebRequest -Url $Site.Url}

        [string[]]$defaultProperties = 'DateTime','Url','RequestTime','StatusCode'
        $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultProperties)
        $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)

        #Create PSCustomObject
        New-Object PSCustomObject -Property @{
            "DateTime" = "{0:dd/MM/yyy HH:mm:ss}" -f [datetime]::Now
            "ContentDatabase" = $Site.ContentDatabase.Name
            "Url" = $Site.Url
            "WarmUpRequestTime" = "{0:N2}ms"-f [double]$WarmUp.TotalMilliseconds
            "RequestTime" = "{0:N2}ms"-f [double]$Result.TotalMilliseconds
            "StatusCode" = [int]$Request.Statuscode
            "StatusDescription" = $Request.StatusDescription
            "ContentLength" = "{0:N2} MB" -f ($Request.ContentLength/1Mb)
            "ResponseUri" = $Request.ResponseUri
            "IsFromCache" = $Request.IsFromCache} | 
                Add-Member -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers -PassThru
        $i++
    }

I get content databases via Microsoft.SharePoint reflection and therefore my code portable between different SharePoint versions.