awsNetSec.psm1

function Start-awsTray {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)][string]$Course
    )
    Begin {
        if ($Course) {
            $Keyword = ($Course -replace ('-? ?(chapter [0-9]{0,2}|final|exam|answers)+ *','')).TrimEnd()
            $Qualifier = ($Course -replace ("$Keyword ?-? ?",'')).TrimEnd()
            if ([string]::IsNullOrWhiteSpace($Qualifier)) {
                $Qualifier = 'final exam answers'
            }
            $SearchURI = "https://itexamanswers.net/?s=%22$Keyword%22+%22$Qualifier%22".Replace(' ','+')
            $Links = (Invoke-WebRequest -Uri $SearchURI)
            $LinkMatches = $Links.links | Where-Object {$_.Title -match $Keyword -and $_.Title -match $Qualifier}
            $BestMatch = $LinkMatches | Sort-Object @{Expression ={(($_.Title -replace($Keyword,'')) -replace("$qualifier",'')).Length}} | Select-Object -First 1
            $URL = $BestMatch.href
        }
        else {
            Return 'No course specified'
        }

        $ScriptBlock = {                          
        Try {
            Import-Module -Name PSParseHTML -ErrorAction Stop
        } Catch {
            Try {
                Install-Module -Name PSParseHTML -Force -AllowClobber -Scope CurrentUser -ErrorAction Stop
                Import-Module -Name PSParseHTML -ErrorAction Stop
            } Catch {
                Write-Output 'Failed to install PSParseHTML module'
                Exit
            }
        }

        $Array = @()
        $HTMLSplit = (Invoke-WebRequest -Uri '<INPUTURL>').Content -split '<nav class='
        foreach ($HTML in $HTMLSplit) {
            $ParsedHTML = (((ConvertFrom-HTMLTag -Content $HTML -Tag 'strong') -join "`n") -split ("`n[0-9]{1,3}\. +")) | Select-Object -Skip 1
            $i = 0
            $ParsedHTML | ForEach-Object {
                $ParsedHTML[$i] = ($ParsedHTML[$i] -split "`n" | Where-Object {$_ -notmatch '^Explanation:' -and $_ -notmatch '^Download PDF File' }) -join "`n"
                $i++
            }
            $Array += $ParsedHTML
        }

        $QA_Array = @()

        $Array | ForEach-Object {
            $Entry = $_ -split "`n"
            $QA_Array += [PSCustomObject]@{
                Question = $Entry | Select-Object -First 1
                Answer = $Entry | Select-Object -Skip 1
            }
        }

            Remove-Item $env:TEMP\netsectray.ps1 -Force

            function Get-Answer {
                param (
                )
                $Qtext = (Get-Clipboard | Out-String).trim()                    
                $Answer = @()
                try {
                    $Answer += ($Script:QA_Array | Where-Object { $_.Question -match [RegEx]::Escape("$Qtext") }).Answer
                    while ($Answer.count -lt 3) {
                        $Answer += ''
                    }
                } catch {
                    $Answer = 'No_answer'
                }

                if (($Answer[0]+$Answer[1]+$Answer[2]).length -gt 123) {
                    $CharAllotment = 41
                    $NewAnswer = @()
                    $SpareChars = 0
                    foreach ($SubAnsw in $Answer) {
                        if ($SubAnsw.length -lt $CharAllotment) {
                            $SpareChars += ($CharAllotment - ($SubAnsw.length))
                            $NewAnswer += $SubAnsw
                        }
                    }
                    foreach ($SubAnsw in ($Answer | Where-Object { $_.length -gt $CharAllotment})) {
                        $MaxChars = $CharAllotment + ($SpareChars / ($Answer | Where-Object { $_.length -gt $CharAllotment}).count)
                        $SubAnswShort = $SubAnsw.Substring(0, $MaxChars)
                        $NewAnswer += $SubAnswShort
                    }
                    $Answer = $NewAnswer
                }

                Return $Answer
            }

            [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
            [System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework') | Out-Null

            $Form = [System.Windows.Forms.Form] @{
                ShowInTaskbar   = $false
                WindowState     = 'Minimized'
                FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedToolWindow
                Opacity         = 0
            }
            [Void]$Form.Hide()

            $Icon = [System.Drawing.Icon]::ExtractAssociatedIcon("$Env:WinDir\explorer.exe")

            [System.GC]::Collect()

            $Output = Get-Answer

            $Menu_Exit = New-Object System.Windows.Forms.ToolStripMenuItem
            $Menu_Exit.Text = 'Exit'
            $Menu_Exit.Add_Click({ $Main_Tool_Icon.Dispose(); $form.dispose(); Exit -ErrorAction SilentlyContinue ; ```  })

            $Main_Tool_Icon = New-Object System.Windows.Forms.NotifyIcon
            $Main_Tool_Icon.ContextMenuStrip = New-Object System.Windows.Forms.ContextMenuStrip
            $Main_Tool_Icon.ContextMenuStrip.items.Add($Menu_Exit) | Out-Null
            $Main_Tool_Icon.Text = 'click for stuff'
            $Main_Tool_Icon.Icon = $icon
            $Main_Tool_Icon.Add_Click({
                    $Output = Get-Answer
                    if ($Output -ne 'No_answer') {
                        $Main_Tool_Icon.Text = "$($Output[0])`n$($Output[1])`n$($Output[2])"
                    } })
            $Main_Tool_Icon.Visible = $true

            $RefreshTimer = New-Object System.Windows.Forms.Timer
            $RefreshTimer.Interval = 2000
            $RefreshTimer.Add_Tick({
                    $Output = Get-Answer
                    if ($Output -ne 'No_answer') {
                        $Main_Tool_Icon.Text = "$($Output[0])`n$($Output[1])`n$($Output[2])"
                    }
                })
            $RefreshTimer.Enabled = $true

            [void][System.Windows.Forms.Application]::Run($Form)
        }

        ($ScriptBlock | Out-String).Replace('<INPUTURL>',$URL) | Out-File $env:TEMP\netsectray.ps1 -Width 2000 -Force
    }
    Process {
        try {
            Start-Process pwsh.exe -WindowStyle hidden -ArgumentList "$env:TEMP\netsectray.ps1"
        } catch {
            Start-Process powershell.exe -WindowStyle hidden -ArgumentList "$env:TEMP\netsectray.ps1"
        }
    }
    End {
        Return $BestMatch.Title
    }
}