GalleryTest.psm1

<#
    .SYNOPSIS
        Creates a Authenticated Session Token
    
    .DESCRIPTION
        Connect-NPrinting creates the NPEnv Script Variable used to Authenticate Requests
        $Script:NPEnv
    
    .PARAMETER Prefix
        http/s prefix for the connection
    
    .PARAMETER Computer
        The NPrinting Server to connect to
    
    .PARAMETER Port
        The Port to connect on (Default: 4993)
    
    .PARAMETER Return
        Returns the Authenticated User ID
    
    .PARAMETER Credentials
        Provide a Credential to authenticate the connection with
    
    .PARAMETER TrustAllCerts
        Trust all Certificates
    
    .PARAMETER AuthScheme
        Authentication type to use, NTLM or buildin NPrinting

#>





function Connect-NPrinting
{
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param
    (
        [Parameter(ParameterSetName = 'Default')]
        [ValidateSet('http', 'https')]
        [string]$Prefix = 'https',
        [Parameter(ParameterSetName = 'Default',
                   Position = 0)]
        [string]$Computer = $($env:computername),
        [Parameter(ParameterSetName = 'Default',
                   Position = 1)]
        [string]$Port = '4993',
        [switch]$Return,
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'Creds')]
        [pscredential]$Credentials,
        [Parameter(ParameterSetName = 'Default')]
        [switch]$TrustAllCerts,
        [ValidateSet('ntlm', 'NPrinting')]
        [string]$AuthScheme = "ntlm"
    )
    
    $APIPath = "api"
    $APIVersion = "v1"
    
    if ($PSVersionTable.PSVersion.Major -gt 5 -and $TrustAllCerts.IsPresent -eq $true)
    {
        $Script:SplatRest.Add("SkipCertificateCheck", $TrustAllCerts)
    }
    else
    {
        if ($TrustAllCerts.IsPresent -eq $true)
        {
            if (-not ("CTrustAllCerts" -as [type]))
            {
                add-type -TypeDefinition @"
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public static class CTrustAllCerts {
    public static bool ReturnTrue(object sender,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors sslPolicyErrors) { return true; }

    public static RemoteCertificateValidationCallback GetDelegate() {
        return new RemoteCertificateValidationCallback(CTrustAllCerts.ReturnTrue);
    }
}
"@

                Write-Verbose -Message "Added Cert Ignore Type"
            }
            
            [System.Net.ServicePointManager]::ServerCertificateValidationCallback = [CTrustAllCerts]::GetDelegate()
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
            Write-Verbose -Message "Server Certificate Validation Bypass"
        }
    }
    
    if ($Computer -eq $($env:computername))
    {
        $NPService = Get-Service -Name 'QlikNPrintingWebEngine'
        if ($null -eq $NPService)
        {
            Write-Error -Message "Local Computer Name used and Service in not running locally"
            break
        }
    }
    
    if ($Computer -match ":")
    {
        If ($Computer.ToLower().StartsWith("http"))
        {
            $Prefix, $Computer = $Computer -split "://"
        }
        
        if ($Computer -match ":")
        {
            $Computer, $Port = $Computer -split ":"
        }
    }
    $CookieMonster = New-Object System.Net.CookieContainer
    $script:NPEnv = @{
        TrustAllCerts = $TrustAllCerts.IsPresent
        Prefix          = $Prefix
        Computer      = $Computer
        Port          = $Port
        API              = $APIPath
        APIVersion    = $APIVersion
        URLServerAPI  = ""
        URLServerNPE  = ""
        URLServerBase = ""
        WebRequestSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
    }
    if ($null -ne $Credentials)
    {
        $NPEnv.Add("Credentials", $Credentials)
    }
    $NPEnv.URLServerBase = "$($NPEnv.Prefix)://$($NPEnv.Computer):$($NPEnv.Port)"
    $NPEnv.URLServerAPI = "$($NPEnv.URLServerBase)/$($NPEnv.API)/$($NPEnv.APIVersion)"
    $NPEnv.URLServerNPE = "$($NPEnv.URLServerBase)/npe"
    
    $WRS = $NPEnv.WebRequestSession
    $WRS.UserAgent = "Windows"
    $WRS.Cookies = $CookieMonster
    
    switch ($PsCmdlet.ParameterSetName)
    {
        'Default' {
            $WRS.UseDefaultCredentials = $true
            $APIAuthScheme = "ntlm"
            break
        }
        'Creds' {
            $WRS.Credentials = $Credentials
            $APIAuthScheme = "ntlm"
            break
        }
    }
    
    if ($AuthScheme -eq "Nprinting")
    {
        $URLServerLogin = "$($NPEnv.URLServerBase)"
    }
    else
    {
        $URLServerLogin = "$($NPEnv.URLServerAPI)/login/$($APIAuthScheme)"
    }
    
    Write-Verbose -Message $URLServerLogin
    $paramInvokeNPRequest = @{
        Path   = $URLServerLogin
        method = 'get'
    }
    if ($PSBoundParameters.Debug.IsPresent)
    {
        $paramInvokeNPRequest.Debug = $true
    }
    $AuthToken = Invoke-NPRequest @paramInvokeNPRequest
    
    if ($AuthScheme -eq "NPrinting")
    {
        #With NPrinting Auth, we first have to get the X-XSRF-Token
        #then submit the credentials.
        $body = @{
            username = $Credentials.UserName
            password = $Credentials.GetNetworkCredential().Password
        } | ConvertTo-Json
        $URLServerLogin = "$($NPEnv.URLServerBase)/login"
        $paramInvokeNPRequest = @{
            Path   = $URLServerLogin
            method = 'post'
            Data   = $body
        }
        if ($PSBoundParameters.Debug.IsPresent)
        {
            $paramInvokeNPRequest.Debug = $true
        }
        $AuthToken = Invoke-NPRequest @paramInvokeNPRequest
        $body = $null
    }
        
    if ($PSBoundParameters.Debug.IsPresent) { $Global:NPEnv = $script:NPEnv }
    
    if ($Return -eq $true)
    {
        $AuthToken
    }
}

#Compatibility Alias Prior to renaming
#Set-Alias -Name Get-NPSession -Value Connect-NPrinting

function Get-XSRFToken
{
    [CmdletBinding()]
    param
    (
        [switch]$Raw
    )
    
    $token = $script:NPenv.WebRequestSession.Cookies.GetCookies($script:NPEnv.URLServerBase) | Where-Object{ $_.name -eq "NPWEBCONSOLE_XSRF-TOKEN" }
    $Header = New-Object 'System.Collections.Generic.Dictionary[String,String]'
    $Header.Add("X-XSRF-TOKEN", $token.Value)
    if ($Raw.IsPresent)
    {
        return $token.Value
    }
    else
    {
        return $Header
    }
}
function Invoke-NPRequest
{
    param
    (
        [Parameter(Mandatory = $true,
                   Position = 0)]
        [string]$Path,
        [ValidateSet('Get', 'Post', 'Patch', 'Delete', 'Put')]
        [string]$method = 'Get',
        $Data,
        [Parameter(ParameterSetName = 'NPE',
                   Mandatory = $false)]
        [switch]$NPE,
        [Parameter(ParameterSetName = 'NPE')]
        [int]$Count = -1,
        [Parameter(ParameterSetName = 'NPE')]
        [string]$OrderBy = 'Name',
        [Parameter(ParameterSetName = 'NPE')]
        [int]$Page = 1,
        [system.IO.FileInfo]$OutFile
    )
    
    $NPEnv = $script:NPEnv
    
    if ($null -eq $NPEnv)
    {
        Write-Warning "Attempting to establish Default connection"
        Connect-NPrinting
    }
    if ([uri]::IsWellFormedUriString($path, [System.UriKind]::Absolute))
    {
        $URI = $path
    }
    else
    {
        if ($NPE.IsPresent -eq $true)
        {
            $NPEPath = $Path
            if ($NPEPath.Contains("?"))
            {
                $join = "&"
            }
            else
            {
                $join = "?"
            }
            if (!($NPEPath.Contains("count=")))
            {
                $NPEPath = "$($NPEPath)$($join)count=$($Count)"
                $join = "&"
            }
            if (!($NPEPath.Contains("orderBy=")))
            {
                $NPEPath = "$($NPEPath)$($join)orderBy=$($OrderBy)"
                $join = "&"
            }
            if (!($NPEPath.Contains("page=")))
            {
                $NPEPath = "$($NPEPath)$($join)page=$($Page)"
                $join = "&"
            }
            $URI = "$($NPEnv.URLServerNPE)/$($NPEPath)"
        }
        else
        {
            $URI = "$($NPEnv.URLServerAPI)/$($path)"
        }
    }
    
    $Script:SplatRest = @{
        URI = $URI
        WebSession = $($NPEnv.WebRequestSession)
        Method = $method
        ContentType = "application/json;charset=UTF-8"
        Headers = Get-XSRFToken
    }
    
    if ("" -eq $NPEnv.WebRequestSession.Cookies.GetCookies($NPEnv.URLServerAPI) -and ($null -ne $NPEnv.Credentials))
    {
        $SplatRest.Add("Credential", $NPEnv.Credentials)
    }
    
    #Convert Data to Json and add to body of request
    if ($null -ne $data)
    {
        if ($Data.GetType().name -like "Array*")
        {
            $jsondata = Convertto-Json -InputObject $Data -Depth 5
        }
        elseif ($Data.GetType().name -ne "string")
        {
            $jsondata = Convertto-Json -InputObject $Data -Depth 5
        }
        else
        {
            $jsondata = $Data
        }
        
        #Catch All
        if (!(($jsondata.StartsWith('{') -and $jsondata.EndsWith('}')) -or ($jsondata.StartsWith('[') -and $jsondata.EndsWith(']'))))
        {
            $jsondata = Convertto-Json -InputObject $Data -Depth 5
        }
        
        $SplatRest.Add("Body", $jsondata)
    }
    
    if ($PSBoundParameters.Keys.Contains("OutFile"))
    {
        $SplatRest.outFile = $OutFile
    }
    
    if ($PSBoundParameters.Debug.IsPresent)
    {
        $Global:NPSplat = $SplatRest
    }
    
    try
    {
        $Result = Invoke-RestMethod @SplatRest
    }
    catch [System.Net.WebException]{
        $EXCEPTION = $_.Exception
        $EXCEPTION
        Write-Warning -Message "From: $($Exception.Response.ResponseUri.AbsoluteUri) `nResponse: $($Exception.Response.StatusDescription)"
        break
    }
    
    if ($PSBoundParameters.Debug.IsPresent)
    {
        Write-Warning "Session XSRF Token: $(Get-XSRFToken -Raw)"
    }
    
    if ($PSBoundParameters.keys.Contains("OutFile"))
    {
        Return
    }
    elseif ($Null -ne $Result)
    {
        if ($NPE.IsPresent -eq $true -or $null -ne $Result.result)
        {
            $Result = $Result.Result
        }
        if ((($Result | Get-Member -MemberType Properties).count -eq 1 -and ($null -ne $Result.data)))
        {
            if ($null -ne $Result.data.items)
            {
                $Result.data.items
            }
            else
            {
                $Result.data
            }
        }
        else
        {
            $Result
        }
    }
    else
    {
        Write-Error -Message "no Results received"
    }
}