ps/Modules/Alkami.PowerShell.IIS/Public/Ping-AlkamiWebSites.ps1
2023-05-30 22:51:22 -07:00

199 lines
8.6 KiB
PowerShell

function Ping-AlkamiWebSites {
<#
.SYNOPSIS
Warms up web tier web services
#>
[CmdletBinding()]
[OutputType([System.Object])]
Param(
[Parameter(Mandatory = $false)]
[Alias("SkipIPSTS")]
[switch]$doSkipIPSTS,
# 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("SkipServerCheck")]
[switch]$skipCheck
)
$logLead = (Get-LogLeadName)
if ((Test-IsAppServer) -and !($skipCheck.IsPresent)) {
# Exit Early
Write-Host ("$logLead : This is not a valid function for an app server")
return
}
$siteArray = @()
$testPattern = "text/javascript"
$maxJobs = 3
$jobs = @()
$mgr = New-Object Microsoft.Web.Administration.ServerManager
$functionStopWatch = [System.Diagnostics.Stopwatch]::StartNew()
if ($doSkipIPSTS) {
$sites = $mgr.Sites | Where-Object { $_.State -eq "Started" } | Where-Object { $_.Applications["/"].VirtualDirectories["/"].PhysicalPath -notlike "*IPSTS" -and $_.Name -notlike "*Eagle*" }
} else {
$sites = $mgr.Sites | Where-Object { $_.State -eq "Started" } | Where-Object { $_.Name -notlike "*Eagle*" }
}
$sites = @($sites)
if (@($sites).Length -eq 0) {
Write-Warning "No sites were found to install!!"
Write-Warning "Please make sure the ConfigurationValues.ps1 got updated correctly!!"
return
}
$sites | Where-Object { $_.Name -ne "Default Web Site" } | ForEach-Object {
$httpBinding = $_.Bindings | Where-Object { $_.Protocol -like "https" } | Select-Object -First 1
if ($null -eq $httpBinding) {
Write-Warning ("$logLead : Could not find any https binding for site {0}" -f $_.Name)
} else {
$hostName = "localhost"
if ($httpBinding.Protocol -eq "https") {
$hostName = $httpBinding.Host
}
$urlString = "{0}://{1}" -f $httpBinding.Protocol, $hostName, $_.Name
# IPSTS has to be tested a different way
if ($_.Applications["/"].VirtualDirectories["/"].PhysicalPath -like "*IPSTS") {
# We have to fish for the admin site URL here to construct the IPSTS test URL
$domainArray = $urlString.Split(".") | Select-Object -Last 2
$domainString = $domainArray -join "."
$adminSites = $sites | Where-Object { $_.Applications["/"].VirtualDirectories["/"].PhysicalPath -like "*Admin" }
$adminMatch = $adminSites | Where-Object { $_.Bindings | Where-Object { $_.Host -like "*$domainString" } } | Select-Object -First 1
if ($null -eq $adminMatch) {
# We couldn't match on admin, so we'll at least warm up the site, but it'll fail
$siteArray += @{Name = $_.Name; Url = $urlString; Ipsts = $true; Admin = $false; Client = $false }
} else {
# Craft the IPSTS test URL using the admin match.
# The page that will actually be loaded is admin, via IPSTS
$adminHttpsBinding = $adminMatch.Bindings | Where-Object { $_.Protocol -like "https" }
$adminHostName = "localhost"
if ($adminHttpsBinding.Protocol -eq "https") {
$adminHostName = $adminHttpsBinding.Host
}
# Generate a GUID to add as the activationId
$guid = [System.GUID]::NewGuid()
$adminMatchUrlString = "{0}://{1}" -f $httpBinding.Protocol, $adminHostName
$siteArray += @{Name = $_.Name; Url = $urlString + "?wa=wsignin1.0&wtrealm=" + $adminMatchUrlString + "&activationId=" + $guid; Ipsts = $true; Admin = $false; Client = $false }
}
} elseif ($_.Applications["/"].VirtualDirectories["/"].PhysicalPath -like "*Admin") {
$siteArray += @{Name = $_.Name; Url = $urlString; Ipsts = $false; Admin = $true; Client = $false }
} else {
# Add Site to Cover CUFX / ORBFX / Mobile Auth
$siteArray += @{Name = $_.Name; Url = $urlString; Ipsts = $false; Admin = $false; Client = $true }
$cleanUrl = $urlString.TrimEnd("/")
$siteArray += @{Name = $_.Name; Url = ($cleanUrl + "/CUFX"); Ipsts = $false; Admin = $false; Client = $true }
$siteArray += @{Name = $_.Name; Url = ($cleanUrl + "/ORBFX"); Ipsts = $false; Admin = $false; Client = $true }
$siteArray += @{Name = $_.Name; Url = ($cleanUrl + "/Mobile/Authentication"); Ipsts = $false; Admin = $false; Client = $true }
}
}
}
$scriptBlock = {
param ($site, $testPattern)
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 $site.Url -UseBasicParsing
$stopWatch.Stop()
if ($response.StatusCode -ne 200 -or $response.Content -notmatch $testPattern) {
return New-Object -TypeName PSObject -Property @{
Name = $site.Name
URL = $site.Url.ToLowerInvariant()
Success = $false
StatusCode = $response.StatusCode
Elapsed = $stopWatch.Elapsed.ToString()
}
} else {
return New-Object -TypeName PSObject -Property @{
Name = $site.Name
URL = $site.Url.ToLowerInvariant()
Success = $true
StatusCode = "200"
Elapsed = $stopWatch.Elapsed.ToString()
}
}
} catch {
return New-Object -TypeName PSObject -Property @{
Name = $site.Name
URL = $site.Url.ToLowerInvariant()
Success = $false
StatusCode = "Error"
Elapsed = $stopWatch.Elapsed.ToString()
}
}
}
$siteResults = @()
if (!(Test-IsCollectionNullOrEmpty $siteArray)) {
Write-Host ("$logLead : Starting Site Warmup")
foreach ($site in $siteArray) {
$jobs += Start-Job -ScriptBlock $scriptBlock -ArgumentList $site, $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' })
}
}
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 {
$siteResults += $_ | Receive-Job | Select-Object URL, Success, StatusCode, Elapsed
}
$functionStopWatch.Stop()
if ($skipOutput) {
return $siteResults
} else {
if ($null -ne ($siteResults | Where-Object { $_.Success -eq $false })) {
Write-Warning ("$logLead : One or more URLs failed the test case:`n")
}
$results = ($siteResults | 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 $results
Write-Host ("Total Execution Time: {0}" -f $functionStopWatch.Elapsed.ToString())
return $siteResults
}
} else {
Write-Host "No sites Configured, skipping warmup"
}
}