# Many printers only have self-signed ssl certs. This type is used to 
# disable the ssl checking (basically clicking "Proceed to unsecure website")
if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertsPolicy').Type) {
    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;
}
}
"@
}
 
function ScanToEmail {
    param (
        [string]$printer
    )

    $DNSServers = [ordered]@{
        'Sam Square/Walnut' = @{
            'Primary' = '10.98.2.45'
            'Secondary' = '10.98.2.74'
        }
        'AGH' = @{
            'Primary' = '10.10.15.11'
            'Secondary' = '10.30.15.18'
        }
        'SPCH' = @{
            'Primary' = '10.50.15.25'
            'Secondary' = '10.60.15.14'
        }
        'GSRMC' = @{
            'Primary' = '10.20.15.16'
            'Secondary' = '10.98.2.74'
        }
        'SLCH' = @{
            'Primary' = '10.30.15.18'
            'Secondary' = '10.10.15.11'
        }
        'SNLH' = @{
            'Primary' = '10.60.15.14'
            'Secondary' = '10.50.15.25'
        }
    }

    $SMTPServer = "shssmtp01.int.samhealth.net"

    <#
    Typically SNMP is set to read-only on most printers so we'll have to 
    replicate web requests. There isn't really a standard so this support 
    will have to be added for each new scheme. We can determine which scheme
    to use based on the model number
    #>
    $snmp = New-Object -ComObject olePrn.OleSNMP
    $printerip = (Resolve-DnsName $printer).IPAddress
    $snmp.open($printerip, 'public', 2, 3000)
    try { $model = $snmp.Get('.1.3.6.1.2.1.25.3.2.1.3.1') } catch { $model = $null } 
    $ModelSetupFunction = switch -Regex ($model) {
        '^HP LaserJet MFP M5\d\d' { $function:ScanToEmailHPFutureSmart }
        '^HP LaserJet MFP M6\d\d' { $function:ScanToEmailHPFutureSmart }
        default { $null }
    }
    if ($null -eq $ModelSetupFunction) {
        Write-Host -ForegroundColor Yellow "Printer model $model not supported at this time. Manual configuration required."
        return
    }
    for ($i = 0; $i -lt $DNSServers.Count; $i++) {
        Write-Host "[$i] $($DNSServers[$i])"
    }
    [int]$site = Read-Host "Select site: "
    if ($null -eq $site) {
        Write-Host -ForegroundColor Yellow "Unsupported site selected"
        return
    }
    & $ModelSetupFunction $printer.DomainName $DNSServers.$site
}

# hp 400 series mfps
Function ScanToEmailHPLJM400 {
    param (
        [string]$PrinterDomainName,
        $DNSServers
    )
    # No server certificate so overwrite checking
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
    Invoke-WebRequest "https://$PrinterDomainName/IoMgmt/Adapters/Eth0/Profiles/Active" -Method PUT -Body @"
<?xml version="1.0" encoding="UTF-8"?> 
<io:Profile xmlns:io="http://www.hp.com/schemas/imaging/con/ledm/iomgmt/2008/11/30" xmlns:dd="http://www.hp.com/schemas/imaging/con/dictionaries/1.0/" xmlns:wifi="http://www.hp.com/schemas/imaging/con/wifi/2009/06/26" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="     http://www.hp.com/schemas/imaging/con/ledm/iomgmt/2008/11/30 ../../schemas/IoMgmt.xsd     http://www.hp.com/schemas/imaging/con/dictionaries/1.0/ ../../schemas/dd/DataDictionaryMasterLEDM.xsd"> 
    <io:NetworkProfile>
        <io:IPv4Network> 
            <dd:DNSServerIPAddress>
                $($DNSServers.Primary)
            </dd:DNSServerIPAddress> 
            <dd:SecondaryDNSServerIPAddress>
                $($DNSServers.Secondary)
            </dd:SecondaryDNSServerIPAddress> 
        </io:IPv4Network> 
    </io:NetworkProfile> 
</io:Profile>
"@ -ContentType 'text/xml' 
}

# HP printers with Future Smart firmware
# Developed for HP FutureSmart 5
# Tested on 
# 5.4
Function ScanToEmailHPFutureSmart {
    param (
        [string]$PrinterDomainName,
        $DNSServers
    )
    $printerName = if ($PrinterDomainName -match '^[^.]*(?=\.)') { $Matches[0] }
    $printerEmail = "$printerName@samhealth.org"

    # No server certificate so overwrite checking
    $savePolicy = [System.Net.ServicePointManager]::CertificatePolicy
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

    $res = Invoke-WebRequest "https://$PrinterDomainName/network_id.htm" -Method GET -SessionVariable WebSession
    if ($res.Content -match 'id="CSRFToken".*VALUE="(.+)"') { $CSRFToken = [uri]::EscapeDataString($Matches[1]) }

    Invoke-WebRequest "https://$PrinterDomainName/network_id.htm/config" `
    -Method POST `
    -WebSession $WebSession `
    -ContentType 'application/x-www-form-urlencoded' `
    -Body "IPv4_DnsServerId=$($DNSServers.Primary)&IPv4_Sec_DnsServerId=$($DNSServers.Secondary)&Apply=Apply&CSRFToken=$CSRFToken" 

    #New csrf token?
    #$res = Invoke-WebRequest "https://$PrinterDomainName/hp/device/BasicSend/Index" -Method GET -SessionVariable WebSession
    #if ($res.Content -match 'id="CSRFToken".*VALUE="(.+)"') { $CSRFToken = [uri]::EscapeDataString($Matches[1]) }

    # Enable smtp and set email
    Invoke-WebRequest "https://$PrinterDomainName/hp/device/BasicSend/Save" `
    -Method POST `
    -WebSession $WebSession `
    -ContentType 'application/x-www-form-urlencoded' `
    -Body "FilterUsage=SendToEmail&EmailFromAddress=$printerEmail&FormButtonSubmit=Apply&CSRFToken=$CSRFToken" 

    # Set smtp server
    Invoke-WebRequest "https://$PrinterDomainName/hp/device/SmtpWizard/Save" `
    -Method POST `
    -WebSession $WebSession `
    -ContentType 'application/x-www-form-urlencoded' `
    -Body "FilterUsage=SendToEmail&StepId=4&SmtpSelection=1&SmtpServerName=$SMTPServer&SmtpServerPort=25&SmtpSplitEmail=0&FormButtonSubmit=Next&CSRFToken=$CSRFToken" 

    # Set authentication (none)
    Invoke-WebRequest "https://$PrinterDomainName/hp/device/SmtpWizard/Save" `
    -Method POST `
    -WebSession $WebSession `
    -ContentType 'application/x-www-form-urlencoded' `
    -Body "FilterUsage=SendToEmail&StepId=5&SmtpAuthentication=False&FormButtonSubmit=Next&CSRFToken=$CSRFToken" 

    # Set usage (just scan to email)
    Invoke-WebRequest "https://$PrinterDomainName/hp/device/SmtpWizard/Save" `
    -Method POST `
    -WebSession $WebSession `
    -ContentType 'application/x-www-form-urlencoded' `
    -Body "FilterUsage=SendToEmail&StepId=6&SmtpUsage=SendToEmail&FormButtonSubmit=Next&CSRFToken=$CSRFToken" 


    [System.Net.ServicePointManager]::CertificatePolicy = $savePolicy
}