ps/Modules/Alkami.PowerShell.Services/Public/Ping-AlkamiServices.ps1

174 lines
6.8 KiB
PowerShell
Raw Normal View History

2023-05-30 22:51:22 -07:00
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
}
}