function Ping-AlkamiServices { <# .SYNOPSIS Warms up app tier web services .PARAMETER SkipOutput Suppresses function output .PARAMETER SkipCheck When passed, doesn't check to determine if the calling machine is a web server #> [CmdletBinding()] [OutputType([System.Object])] Param( # This can be used to consume the output as an object in a downstream function # If not included the output is formatted for review by a human [Parameter(Mandatory = $false)] [Alias("NoOutput")] [switch]$skipOutput, [Parameter(Mandatory = $false)] [Alias("Force")] [switch]$skipCheck ) $logLead = Get-LogLeadName if ((Test-IsWebServer) -and !($skipCheck)) { # Exit Early Write-Host "$logLead : This is not a valid function for a web server" return } $maxJobs = 3 $jobs = @() $testPattern = "mexHttpBinding" # Ensure we can actually hit the services before we try to warm them up # If we can not hit them, this will throw, as currently written, so we should not proceed Test-KnownWCFServicesResolvable # Needed for local testing #Import-Module WebAdministration #[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration") $mgr = New-Object Microsoft.Web.Administration.ServerManager $functionStopWatch = [System.Diagnostics.Stopwatch]::StartNew() $applicationsToWarmUp = @() # $appTierApplications is a global variable. foreach ($service in $appTierApplications) { $targetSite = $mgr.Sites | Where-Object { ($_ | Select-Object -ExpandProperty Applications | Select-Object -ExpandProperty Path) -match $service.Name } | Select-Object -First 1 if ($null -eq $targetSite) { Write-Warning ("{1} : Could not find any website which contains application {0}" -f $service.Name, $logLead) continue } $httpBinding = $targetSite.Bindings | Where-Object { $_.Protocol -ne "net.tcp" } | Select-Object -First 1 if ($null -eq $httpBinding) { Write-Warning ("{2} : Could not find any http/https binding for site {0} hosting application {1}" -f $targetSite.Name, $service.Name, $logLead) continue } $hostName = "localhost" if ($httpBinding.Protocol -eq "https") { $hostName = $httpBinding.Host } $urlString = "{0}://{1}/{2}/{3}" -f $httpBinding.Protocol, $hostName, $service.WebAppName, $service.Endpoint Write-Host ("{2} : Preparing to warm up application {0} with URL {1}" -f $service.WebAppName, $urlString, $logLead) $applicationsToWarmUp += @{ Url = $urlString; Endpoint = $service.Endpoint; WebAppName = $service.WebAppName } } $scriptBlock = { param ($service, $testPattern) $logLead = "[Ping-AlkamiServices]" try { add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy $stopWatch = [System.Diagnostics.Stopwatch]::StartNew() $response = Invoke-WebRequest -Uri $service.Url -UseBasicParsing -TimeoutSec 300 $stopWatch.Stop() if ($response.StatusCode -ne 200 -or $response.Content -notmatch $testPattern) { return New-Object -TypeName PSObject -Property @{ URL = $service.Url.ToLowerInvariant() ServiceEndpoint = $service.Endpoint.ToLowerInvariant() Success = $false StatusCode = $response.StatusCode Elapsed = $stopWatch.Elapsed.ToString() WebAppName = $service.WebAppName } } else { return New-Object -TypeName PSObject -Property @{ URL = $service.Url.ToLowerInvariant() ServiceEndpoint = $service.Endpoint.ToLowerInvariant() Success = $true StatusCode = $response.StatusCode Elapsed = $stopWatch.Elapsed.ToString() WebAppName = $service.WebAppName } } } catch { Write-Warning "$logLead : Exception caught! $(Resolve-Error $_)" return New-Object -TypeName PSObject -Property @{ URL = $service.Url.ToLowerInvariant() ServiceEndpoint = $service.Endpoint.ToLowerInvariant() Success = $false StatusCode = $response.StatusCode Elapsed = $stopWatch.Elapsed.ToString() WebAppName = $service.WebAppName } } } $serviceResults = @() foreach ($service in ($applicationsToWarmUp | Where-Object { $null -ne $_.Url })) { $jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList $service, $testPattern $running = @($jobs | Where-Object { $_.State -eq 'Running' }) while ($running.Count -ge $maxJobs -and $running.Count -ne 0) { (Wait-Job -Job $jobs -Any) | Out-Null $running = @($jobs | Where-Object { $_.State -eq 'Running' }) } } if ($jobs) { Wait-Job -Job $jobs > $null } $failed = @($jobs | Where-Object { $_.State -eq 'Failed' }) if ($failed.Count -gt 0) { $failed | ForEach-Object { $_.ChildJobs[0].JobStateInfo.Reason.Message } } $jobs | ForEach-Object { $serviceResults += $_ | Receive-Job | Select-Object URL, ServiceEndpoint, Success, StatusCode, Elapsed, WebAppName } $functionStopWatch.Stop() if ($skipOutput) { return $serviceResults } else { if ($null -ne ($serviceResults | Where-Object {$_.Success -eq $false})) { Write-Warning "$logLead : One or more URLs failed the test case:`n" } $result = ($serviceResults | Sort-Object -Property Success | Format-Table -Property @{Label="URL";Width=70;e={$_.URL};Alignment="Left"}, @{Label="Success";Width=15;e={$_.Success};Alignment="Right"},@{Label="Elapsed";Width=25;e={$_.Elapsed};Alignment="Right"} | Out-String) Write-Host $result Write-Host ("{1} : Total Execution Time: {0}" -f $functionStopWatch.Elapsed.ToString(), $logLead) return $serviceResults } }