πŸ’» Powershell : User Functionality Testing

So there was a requirement to test websites that laptops would be using before and after changing a proxy solution so ensure the websites worked as desired, so for this we will need a control laptop and a test laptop and it looks like this:

Control Laptop : Normal laptop with the new proxy solution
Test Laptop : Laptop with the updated proxy solution installed for testing

Scripting is all about consistency, Humans make mistakes because they’re human, scripts on the other hand, do the same task over and over again, which gives you a very consistent and stable way of testing

This will then test the following sections against websites from a static TXT file in the folder with the scripts:

  1. HTTP Reponse Codes and Connection validation
  2. Certificate Issuer headers (helpful for HTTP inspection interception issues)
  3. Synthetic User Metrics - monitor response times for the websites in question
This is required to give the users a authentic and valid experience or alert you to problem that may occur when actual users try to use websites and web services.

Variables

Note : Any user based updates will be shown in bold in the scripts below

The only variable to update for all the scripts will be the one called "address_list.txt" this will need to be updated with the name of the file you have that contains all your websites in a TXT file.

I also require TLS v1.2 so I have defined this in all the scripts, however if this is not required you can disable this, if you wish to disable it remove this line : [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Test 1 : HTTP Responses

This is the first script and will look at the connection to the remote server and analyse the response headers to ensure that this would work in normal circumstances, this is the script:

# Set TLS 1.2 as the default security protocol for .NET
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Read the list of addresses from a text file, one address per line
$addresses = Get-Content -Path "address_list.txt"

foreach ($remoteAddress in $addresses) {
    try {
        $response = Invoke-WebRequest -Uri "https://$remoteAddress" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop    

        if ($response.StatusCode -eq 200) {

            Write-Host "Connection to $remoteAddress on port 443 is successful, HTTP 200 OK." -ForegroundColor Green

        } else {

            Write-Host "Connection to $remoteAddress on port 443 succeeded, but received an HTTP $($response.StatusCode) response." -ForegroundColor Yellow
        }
    } catch {

Write-Host "Connection to $remoteAddress on port 443 failed. Error: $($_.Exception.Message)" -ForegroundColor Red

    }
}

This is the response you get, here you can see all is healthy with the HTTP status of 200 which is fabulous:


Test 2 : SSL Certificates Headers

Note : If you would not like to see the certificate data then remove the following from this code: 

This is required as many services do not like or allow HTTPS inspection so it needs to be disabled, this will tell you if this is setup correctly, however at the moment it just reports the issuer which should be the "normal" issuer not a "custom internal" one, this is the script:

 param(
    [string]$filePath = 'address_list.txt',
    [int]$port = 443
)

function Check-SSL {
    param(
        [string]$fqdn,
        [int]$port
    )

    # Allow connection to sites with an invalid certificate:

    [Net.ServicePointManager]::ServerCertificateValidationCallback = {$True}
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

    $timeoutMilliseconds = 5000
    $url = "https://$fqdn"
    Write-Host "`nChecking $url" -ForegroundColor Green
    $req = [Net.HttpWebRequest]::Create($url)
    $req.Timeout = $timeoutMilliseconds
    try {

        $response = $req.GetResponse()
        $certinfo = New-Object security.cryptography.x509certificates.x509certificate2($req.ServicePoint.Certificate)

# Extract the subject from the certificate

        $subject = $certinfo.Subject
        if ($subject -match 'zscaler') {
            Write-Host "Found 'zscaler' in the subject of $fqdn" -ForegroundColor Yellow
        }
        else {
            Write-Host "Did not find 'zscaler' in the subject of $fqdn" -ForegroundColor Green
        }
        $certinfo | Format-List
    }
    catch {}
}

# Read website URLs from the text file
$websites = Get-Content -Path $filePath
foreach ($website in $websites) {
    if (Test-NetConnection -Port $port -ComputerName $website -InformationLevel Quiet) {
        Check-SSL -fqdn $website -port $port
    }
    else {
        Write-Host "Unable to connect to FQDN '$website' on port $port" -ForegroundColor Red
    }
}

This is the response from the script which shows you the issuer quite clearly and will tell you if it find the string specified in the subject as you can see below, here we use the string "zscaler"


However if you remove the $certinfo | Format-List from the code above its easier to look for abnormalities, this is the section in the code that is bold and red:



Test 3 : Synthetic User Metrics

This is required to access the load time of the website from a HTTP session point of view, or more specifically how long does the website take to load, that is load not interact with, scripting is not user activity obviously.

You may also need to update the values that set the yellow and red colors, The values below are in seconds, so below 0.4 is 0.4 seconds!!

This is the script:

# Set TLS 1.2 as the default security protocol for .NET
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Function to measure response time and apply color based on thresholds
function Measure-ResponseTime {
    param (
        [string]$url
    )

    try {
        $start_time = Get-Date
        $response = Invoke-WebRequest -Uri $url -TimeoutSec 10
        $end_time = Get-Date
        $response_time = ($end_time - $start_time).TotalSeconds

        if ($response_time -gt 0.4) {
            $color = "Red"
        }
        elseif ($response_time -gt 0.2) {
            $color = "Yellow"
        }
        else {
            $color = "Green"
        }

        $response_time_formatted = "{0:F2}" -f $response_time
        Write-Host "Website: $url, Response Time: $($response_time_formatted) seconds" -ForegroundColor $color
    }
    catch {
        Write-Host "Website: $url, Error: Unable to fetch response" -ForegroundColor Red
    }
}

# Read websites from a text file
$websites = Get-Content -Path 'address_list.txt'

# Measure response time for each website
foreach ($website in $websites) {
    Measure-ResponseTime -url $website
}

This is the output, couple of things to note, the "red" errors are actually because this sites redirect to another site or require other strings or authentication to work, and you cannot analyse the session based on that, this only tests the loading experience.

The red errors will also point you to site issues as well that you may not know about!!


Its synthetic as if you run the same test on the same website you will get different results as below:



Then the same test again with tweaked variables to show the point:


Anyway that is all for now.
Previous Post Next Post

Ω†Ω…ΩˆΨ°Ψ¬ Ψ§Ω„Ψ§ΨͺΨ΅Ψ§Ω„