LodasoftPS.psm1

$Script:PSModuleRoot = $PSScriptRoot
$Script:ModuleName = "HubSpotPS"
$Script:LSAppDataPath = [Environment]::GetFolderPath('ApplicationData')
$Script:ModuleDataRoot = (Join-Path -Path $Script:LSAppDataPath -ChildPath $Script:ModuleName)
$Script:ModuleDataPath = (Join-Path -Path $Script:ModuleDataRoot -ChildPath "ModuleData.json")
if (-not (Test-Path $Script:ModuleDataRoot)) {New-Item -ItemType Directory -Path $Script:ModuleDataRoot -Force}
# Imported from [D:\a\1\s\LodasoftPS\Private]
# Get-LSApiEndpoint.ps1
function Get-LSApiEndpoint
{    
    <#
    .SYNOPSIS
 
    Returns the api uri endpoint.
 
    .DESCRIPTION
 
    Returns the api uri endpoint base on the api type.
 
    .PARAMETER ApiType
 
    Type of the api endpoint to use.
 
    .OUTPUTS
 
    String, The uri endpoint that will be used by Set-LSUri.
 
    .EXAMPLE
 
    Returns the api endpoint for 'release-releases'
 
    Get-LSApiEndpoint -ApiType release-releases
 
    .LINK
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [string]
        $ApiType
    )

    begin
    {
    }

    process
    {
        Switch ($ApiType)
        {
            'account-token'
            {
                return 'api/Account/Token'
            }
            'borrower-allBorrowers'
            {
                return 'api/Borrower/AllBorrower'
            }
            'publicapi-reporting-data'
            {
                return 'api/PublicApi/reporting-data'
            }
            default
            {
                Write-Error "[$($MyInvocation.MyCommand.Name)]: [$ApiType] is not supported" -ErrorAction Stop
            }
        }
    }

    end
    {
    }
}

# Set-LSAuthenticationType.ps1
function Set-LSAuthenticationType
{    
    <#
    .SYNOPSIS
 
    Sets the authentication type used by Invoke-LSRestMethod.
 
    .DESCRIPTION
 
    Sets the authentication type used by Invoke-LSRestMethod.
    Default authentication will use the pesonal access token that is stored in session data, unless a credential is provided.
 
    .PARAMETER InputObject
     
    The splat parameters used by Invoke-LSRestMethod.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request.
     
    .OUTPUTS
 
    PSObject, The modifed inputobject.
 
    .EXAMPLE
 
    Set-LSAuthenticationType -InputObject $inputObject
 
    .EXAMPLE
 
    Sets the AP authentication to the credential provided for the input object.
     
    Set-LSAuthenticationType -InputObject $inputObject -Credential $pscredential
 
    .EXAMPLE
 
    Sets the AP authentication to the personal access token provided for the input object.
     
    Set-LSAuthenticationType -InputObject $inputObject -PersonalAccessToken $mySecureToken
 
    .LINK
 
    #>

    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory)]
        [PSObject]
        $InputObject,

        [Parameter()]
        [Security.SecureString]
        $PersonalAccessToken,

        [Parameter()]
        [pscredential]
        $Credential
    )

    begin
    {
    }

    process
    {
        If ($Credential)
        {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with the provided credential."
            $InputObject.Credential = $Credential
        }
        ElseIf ($PersonalAccessToken)
        {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with the stored personal access token."
            $PersonalAccessTokenToken = Unprotect-LSSecurePersonalAccessToken -PersonalAccessToken $PersonalAccessToken
            $encodedPersonalAccessToken = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$PersonalAccessTokenToken"))
            $InputObject.Headers = @{Authorization = "Basic $encodedPersonalAccessToken" }
        }
        Else
        {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Authenticating with default credentials"
            $InputObject.UseDefaultCredentials = $true
        }
    }

    end
    {
        Return $InputObject
    }
}

# Set-LSUri.ps1
function Set-LSUri
{
    <#
    .SYNOPSIS
 
    Sets the uri used by Invoke-LSRestMethod.
 
    .DESCRIPTION
 
    Sets the uri used by Invoke-LSRestMethod.
 
    .PARAMETER Instance
 
    The Team Services account or TFS server.
 
    .PARAMETER Query
 
    Url query parameter.
 
    .PARAMETER ApiEndpoint
 
    The api endpoint provided by Get-LSApiEndpoint.
 
    .PARAMETER ApiVersion
 
    Version of the api to use.
 
    .OUTPUTS
 
    Uri, The uri that will be used by Invoke-LSRestMethod.
 
    .EXAMPLE
 
    Set-LSUri -Instance 'https://prodapi.lodasoft.com' -ApiEndpoint '_apis/Release/releases/4'
 
    .LINK
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter()]
        [uri]
        $Instance,

        [Parameter()]
        [string]
        $Query,

        [Parameter(Mandatory)]
        [string]
        $ApiEndpoint
    )

    begin
    {
    }

    process
    {
        If ($Instance.AbsoluteUri -and $ApiEndpoint)
        {
            return '{0}{1}' -f $Instance.AbsoluteUri, $ApiEndpoint
        }
    }

    end
    {
    }
}

# Unprotect-LSSecurePersonalAccessToken.ps1
Function Unprotect-LSSecurePersonalAccessToken
{
    <#
    .SYNOPSIS
 
    Returns decrypted personal access token.
 
    .DESCRIPTION
 
    Returns decrypted personal access token that is stored in the session data.
 
    .PARAMETER PersonalAccessToken
 
    Personal access token used to authenticate that has been converted to a secure string.
         
    .OUTPUTS
 
    String, unsecure personal access token.
 
    .EXAMPLE
 
    Unprotects the personal access token from secure string to plain text.
 
    Unprotect-SecurePersonalAccessToken -PersonalAccessToken $mySecureToken
 
    .LINK
 
    #>


    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [Security.SecureString]
        $PersonalAccessToken
    )
    Process
    {
        $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PersonalAccessToken)
        $plainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
        Return $plainText
    }
}

# Imported from [D:\a\1\s\LodasoftPS\Public]
# Get-LSAccountToken.ps1
Function Get-LSAccountToken
{
    <#
    .SYNOPSIS
 
    Returns a Lodasoft account token.
 
    .DESCRIPTION
 
    Returns a Lodasoft account token either from cache or requests a new token.
 
    .PARAMETER Instance
 
    The Lodasoft api instance.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER GrantType
 
    The type of grant to use.
 
    .PARAMETER Scope
 
    The scope of token to request.
 
    .PARAMETER Origin
 
    The DNS entry for the company name.
 
    .PARAMETER Referer
 
    The DNS entry for the company name.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, LS account token.
 
    .EXAMPLE
 
    Returns reporting data for 'mySession'
 
    Get-LSAccountToken -Session 'mySession'
 
    .LINK
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [uri]
        $Instance,

        [Parameter()]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory)]
        [string]
        $GrantType,

        [Parameter(Mandatory)]
        [string]
        $Scope,

        [Parameter(Mandatory)]
        [string]
        $Origin,

        [Parameter(Mandatory)]
        [string]
        $Referer
    )
    begin
    {

    }
    process
    {
        If ($Script:TokenAccessExpiration)
        {
            If ((Get-Date $Script:TokenAccessExpiration) -lt (Get-Date 11-05-2020))
            {
                return $Script:TokenAccessData
            }
        }
        else
        {
            $Script:TokenAccessData = New-LSAccountToken -Instance $Instance -Credential $Credential -Proxy $Proxy -ProxyCredential $ProxyCredential -GrantType $GrantType -Scope $Scope -Origin $Origin -Referer $Referer
            return $Script:TokenAccessData
        }
    }
    end
    {

    }
}

# Get-LSBorrowerList.ps1
function Get-LSBorrowerList
{
    <#
    .SYNOPSIS
 
    Returns a list of Lodasoft borrowers.
 
    .DESCRIPTION
 
    Returns a list of Lodasoft borrowers.
 
    .PARAMETER Session
 
    Lodasoft session, created by New-LSSession.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, List of Lodasoft borrowers.
 
    .EXAMPLE
 
    Returns a list of borrowers for 'mySession'
 
    Get-LSBorrowerList -Session 'mySession'
 
    .LINK
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [object]
        $Session
    )

    begin
    {
        $currentSession = $Session | Get-LSSession
        If ($currentSession)
        {
            $instance = $currentSession.Instance
            $credential = $currentSession.Credential
            $proxy = $currentSession.Proxy
            $proxyCredential = $currentSession.ProxyCredential
            $token = $currentSession.token
        }
    }
        
    process
    {
        $headers = @{
            Authorization = "bearer " + $token
        }
        $apiEndpoint = Get-LSApiEndpoint -ApiType 'borrower-allBorrowers'
        $setAPUriSplat = @{
            Instance    = $instance
            ApiEndpoint = $apiEndpoint
        }
        [uri] $uri = Set-LSUri @setAPUriSplat
        $invokeAPRestMethodSplat = @{
            Method          = 'GET'
            Uri             = $uri
            Credential      = $credential
            Headers         = $headers
            ContentType     = 'application/json'
            Proxy           = $proxy
            ProxyCredential = $proxyCredential
        }
        $results = Invoke-LSRestMethod @invokeAPRestMethodSplat 
        If ($results)
        {
            $results
        }
    }
    
    end
    {
    }
}
# Get-LSReportingData.ps1
function Get-LSReportingData
{
    <#
    .SYNOPSIS
 
    Returns the LoadSoft reporting data.
 
    .DESCRIPTION
 
    Returns the LoadSoft reporting data.
 
    .PARAMETER Session
 
    Lodasoft session, created by New-LSSession.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, LS account token.
 
    .EXAMPLE
 
    Returns the LoadSoft reporting data.
 
    Get-LSReportingData -Session 'mySession'
 
    .LINK
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [object]
        $Session
    )

    begin
    {
        $currentSession = $Session | Get-LSSession
        If ($currentSession)
        {
            $instance = $currentSession.Instance
            $credential = $currentSession.Credential
            $proxy = $currentSession.Proxy
            $proxyCredential = $currentSession.ProxyCredential
            $token = $currentSession.token
        }
    }
        
    process
    {
        $headers = @{
            Authorization = "bearer " + $token
        }
        $apiEndpoint = Get-LSApiEndpoint -ApiType 'publicapi-reporting-data'
        $setAPUriSplat = @{
            Instance    = $instance
            ApiEndpoint = $apiEndpoint
        }
        [uri] $uri = Set-LSUri @setAPUriSplat
        $invokeAPRestMethodSplat = @{
            Method          = 'GET'
            Uri             = $uri
            Credential      = $credential
            Headers         = $headers
            ContentType     = 'application/json'
            Proxy           = $proxy
            ProxyCredential = $proxyCredential
        }
        $results = Invoke-LSRestMethod @invokeAPRestMethodSplat 
        If ($results)
        {
            $results
        }
    }
    
    end
    {
    }
}
# Get-LSSession.ps1
Function Get-LSSession
{
    <#
    .SYNOPSIS
 
    Returns LodasoftPS session data.
 
    .DESCRIPTION
 
    Returns LodasoftPS session data that has been stored in the users local application data.
    Use Save-LSSession to persist the session data to disk.
    The sensetive data is returned encrypted.
 
    .PARAMETER Id
     
    Session id.
 
    .PARAMETER SessionName
     
    The friendly name of the session.
 
    .PARAMETER Path
     
    The path where session data will be stored, defaults to $Script:ModuleDataPath.
 
    .LINK
 
    Save-LSSession
    Remove-LSSession
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Get-LSSession returns a PSObject that contains the following:
        Instance
        Collection
        PersonalAccessToken
 
    .EXAMPLE
 
    Returns all AP sessions saved or in memory.
 
    Get-LSSession
 
    .EXAMPLE
 
    Returns AP session with the session name of 'myFirstSession'.
 
    Get-LSSession -SessionName 'myFirstSession'
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(ValueFromPipeline,
            ValueFromPipelineByPropertyName)]
        [string]
        $SessionName,

        [Parameter(ParameterSetName = 'ById',
            ValueFromPipelineByPropertyName)]
        [int]
        $Id,

        [Parameter()]
        [string]
        $Path = $Script:ModuleDataPath
    )
    Process
    {
        # Process memory sessions
        $_sessions = @()
        If ($null -ne $Global:_LSSessions)
        {
            Foreach ($_memSession in $Global:_LSSessions)
            {
                $_sessions += $_memSession
            }
        }
        
        # Process saved sessions
        If (Test-Path $Path)
        {
            $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
            Foreach ($_data in $data.SessionData)
            {
                $_object = New-Object -TypeName PSCustomObject -Property @{
                    Id          = $_data.Id
                    SessionName = $_data.SessionName
                    Instance    = $_data.Instance
                    Token       = $_data.Token
                    Expiration  = $_data.'.expires'
                    GrantType   = $_data.GrantType
                    Scope       = $_data.Scope
                    Origin      = $_data.Origin
                    Referer     = $_data.Referer
                    Saved       = $_data.Saved
                }
                If ($_data.Credential)
                {
                    $_psCredentialObject = [pscredential]::new($_data.Credential.Username, ($_data.Credential.Password | ConvertTo-SecureString))
                    $_object | Add-Member -NotePropertyName 'Credential' -NotePropertyValue $_psCredentialObject
                }
                If ($_data.Proxy)
                {
                    $_object | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $_data.Proxy
                }
                If ($_data.ProxyCredential)
                {
                    $_psProxyCredentialObject = [pscredential]::new($_data.ProxyCredential.Username, ($_data.ProxyCredential.Password | ConvertTo-SecureString))
                    $_object | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $_psProxyCredentialObject
                }
                $_sessions += $_object
            }
        }
        If ($PSCmdlet.ParameterSetName -eq 'ById')
        {
            $_sessions = $_sessions | Where-Object { $PSItem.Id -eq $Id }
        }
        If ($SessionName)
        {
            $_sessions = $_sessions | Where-Object { $PSItem.SessionName -eq $SessionName }
        }
        If ($_sessions)
        {
            return $_sessions
        }
        elseIf($ErrorActionPreference -ne 'SilentlyContinue')
        {
            Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate any Lodasoft sessions in memory or stored at [$Path]" -ErrorAction 'Stop'
        }
    }
}
# Invoke-LSRestMethod.ps1
function Invoke-LSRestMethod
{
    <#
    .SYNOPSIS
 
    Invokes a rest method.
 
    .DESCRIPTION
 
    Invokes a rest method.
 
    .PARAMETER Method
     
    Specifies the method used for the web request.
 
    .PARAMETER Body
     
    Specifies the body of the request. The body is the content of the request that follows the headers.
 
    .PARAMETER ContentType
     
    Specifies the content type of the web request. If this parameter is omitted and the request method is POST, Invoke-RestMethod sets the content type to application/x-www-form-urlencoded. Otherwise, the content type is not specified in the call.
 
    .PARAMETER Headers
 
    The headers to append to the invocation.
 
    .PARAMETER Uri
 
    Specifies the Uniform Resource Identifier (URI) of the Internet resource to which the web request is sent. This parameter supports HTTP, HTTPS, FTP, and FILE values.
 
    .PARAMETER PersonalAccessToken
 
    Personal access token used to authenticate that has been converted to a secure string.
     
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request. The default is the Personal Access Token if it is defined, otherwise it is the current user.
 
    .PARAMETER Proxy
     
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
     
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Path
 
    The directory to output files to.
     
    .OUTPUTS
 
    System.Int64, System.String, System.Xml.XmlDocument, The output of the cmdlet depends upon the format of the content that is retrieved.
 
    .OUTPUTS
 
    PSObject, If the request returns JSON strings, Invoke-RestMethod returns a PSObject that represents the strings.
 
    .EXAMPLE
 
    Invoke-LSRestMethod -Method PATCH -Body $Body -ContentType 'application/json' -Uri 'https://myURL/api/endpoint'
 
    .LINK
 
    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-6
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [string]
        $Method,

        [Parameter()]
        [psobject]
        $Body,

        [Parameter(Mandatory)]
        [uri]
        $Uri,

        [Parameter()]
        [string]
        $ContentType,

        [Parameter()]
        [psobject]
        $Headers,

        [Parameter()]
        [Security.SecureString]
        $PersonalAccessToken,

        [Parameter()]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential, 

        [Parameter()]
        [string]
        $Path
    )

    begin
    {
    }
    
    process
    {
        $invokeRestMethodSplat = @{
            ContentType     = $ContentType
            Method          = $Method
            UseBasicParsing = $true
            Uri             = $uri.AbsoluteUri
        }
        If ($Body)
        {
            $invokeRestMethodSplat.Body = $Body
        }
        If ($Headers)
        {
            $invokeRestMethodSplat.Headers = $Headers
        }
        If ($Proxy)
        {
            $invokeRestMethodSplat.Proxy = $Proxy
            If ($ProxyCredential)
            {
                $invokeRestMethodSplat.ProxyCredential = $ProxyCredential
            }
            else
            {
                $invokeRestMethodSplat.ProxyUseDefaultCredentials = $true
            }
        }
        If ($Path)
        {
            $invokeRestMethodSplat.OutFile = $Path
        }
        $authenticatedRestMethodSplat = Set-LSAuthenticationType -InputObject $invokeRestMethodSplat -Credential $Credential -PersonalAccessToken $PersonalAccessToken
        $results = Invoke-RestMethod @authenticatedRestMethodSplat
        Return $results
    }
    
    end
    {
    }
}

# New-LSAccountToken.ps1
function New-LSAccountToken
{
    <#
    .SYNOPSIS
 
    Creates a new LS account token.
 
    .DESCRIPTION
 
    Creates an Lodasoft account token.
 
    .PARAMETER Instance
 
    The Lodasoft api instance.
    Example: prodapi.lodasoft.com
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request.
 
    .PARAMETER Proxy
     
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
     
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    Lodasoft session, created by New-LSSession.
 
    .PARAMETER GrantType
 
    The type of grant to use.
 
    .PARAMETER Scope
 
    The scope of token to request.
 
    .PARAMETER Origin
 
    The DNS entry for the company name.
 
    .PARAMETER Referer
 
    The DNS entry for the company name.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, LS account token.
 
    .EXAMPLE
 
    Returns an access token with a 'password' grant for the 'Admin' scope for the 'myCompand.lodasoft.com'.
    New-LSAccountToken -Session 'mySession' -GrantType 'password' -Scope 'Admin' -Origin 'https://myCompany.lodasoft.com' -Referer 'https://myCompany.lodasoft.com'
 
    .LINK
 
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    Param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Instance,

        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [string]
        $GrantType,

        [Parameter(Mandatory)]
        [string]
        $Scope,

        [Parameter(Mandatory)]
        [string]
        $Origin,

        [Parameter(Mandatory)]
        [string]
        $Referer
    )

    begin
    {
        If ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-LSSession
            If ($currentSession)
            {
                $Instance = $currentSession.Instance
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $Scope = $currentSession.Scope
                $GrantType = $currentSession.GrantType
                $Origin = $currentSession.Origin
                $Referer = $currentSession.Referer
            }
        }
    }
        
    process
    {
        $headers = @{
            origin  = $Origin
            referer = $Referer
        }
        $body = @{
            'grant_type' = $GrantType
            scope        = $Scope
            username     = $Credential.UserName
            password     = $Credential.GetNetworkCredential().Password
        }
        $apiEndpoint = Get-LSApiEndpoint -ApiType 'account-token'
        $setAPUriSplat = @{
            Instance    = $Instance
            ApiEndpoint = $apiEndpoint
        }
        [uri] $uri = Set-LSUri @setAPUriSplat
        $invokeAPRestMethodSplat = @{
            Method          = 'POST'
            Uri             = $uri
            Credential      = $Credential
            Headers         = $headers
            Body            = $body
            ContentType     = 'application/x-www-form-urlencoded'
            Proxy           = $Proxy
            ProxyCredential = $ProxyCredential
        }
        $results = Invoke-LSRestMethod @invokeAPRestMethodSplat 
        If ($results)
        {
            return $results
        }
    }
    
    end
    {
    }
}
# New-LSSession.ps1
Function New-LSSession
{
    <#
    .SYNOPSIS
 
    Creates a Lodasoft session.
 
    .DESCRIPTION
 
    Creates a Lodasoft session.
    Use Save-LSSession to persist the session data to disk.
    Save the session to a variable to pass the session to other functions.
 
    .PARAMETER SessionName
 
    The session name.
 
    .PARAMETER Instance
 
    The Lodasoft api instance.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER GrantType
 
    The type of grant to use.
 
    .PARAMETER Scope
 
    The scope of token to request.
 
    .PARAMETER Origin
 
    The DNS entry for the company name.
 
    .PARAMETER Referer
 
    The DNS entry for the company name.
 
    .PARAMETER Path
 
    The path where module data will be stored, defaults to $Script:ModuleDataPath.
 
    .LINK
 
    Save-LSSession
    Remove-LSSession
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. New-LSSession returns a PSObject.
 
    .EXAMPLE
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [string]
        $SessionName,

        [Parameter(Mandatory)]
        [uri]
        $Instance,

        [Parameter(Mandatory)]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory)]
        [string]
        $GrantType,

        [Parameter(Mandatory)]
        [string]
        $Scope,

        [Parameter(Mandatory)]
        [string]
        $Origin,

        [Parameter(Mandatory)]
        [string]
        $Referer,
        
        [Parameter()]
        [string]
        $Path = $Script:ModuleDataPath
    )
    Process
    {
        [int] $_sessionIdcount = (Get-LSSession -ErrorAction 'SilentlyContinue' | Sort-Object -Property 'Id' | Select-Object -Last 1 -ExpandProperty 'Id') + 1
        $splat = @{
            Instance        = $Instance 
            Credential      = $Credential
            Proxy           = $Proxy
            ProxyCredential = $ProxyCredential
            GrantType       = $GrantType
            Scope           = $Scope
            Origin          = $Origin
            Referer         = $Referer
            ErrorAction     = 'Stop'
        }
        $tokenData = New-LSAccountToken @splat 
        $_session = New-Object -TypeName PSCustomObject -Property @{
            SessionName = $SessionName
            Instance    = $Instance
            Credential  = $Credential
            Token       = $tokenData.access_token
            Expiration  = $tokenData.'.expires'
            GrantType   = $GrantType
            Scope       = $Scope
            Origin      = $Origin
            Referer     = $Referer
            Id          = $_sessionIdcount
        }
        If ($Proxy)
        {
            $_session | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $Proxy
        }
        If ($ProxyCredential)
        {
            $_session | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $ProxyCredential
        }
        If ($null -eq $Global:_LSSessions)
        {
            $Global:_LSSessions = @()
        }
        $Global:_LSSessions += $_session
        Return $_session
    }
}

# Remove-LSSession.ps1
Function Remove-LSSession
{
    <#
    .SYNOPSIS
 
    Removes a Lodasoft session.
 
    .DESCRIPTION
 
    Removes a Lodasoft session.
    If the session is saved, it will be removed from the saved sessions as well.
 
    .PARAMETER Id
     
    Session id.
 
    .PARAMETER Path
     
    The path where session data will be stored, defaults to $Script:ModuleDataPath.
 
    .LINK
 
    Save-LSSession
    Remove-LSSession
 
    .INPUTS
 
    PSObject. Get-LSSession
 
    .OUTPUTS
 
    None. Does not supply output.
 
    .EXAMPLE
 
    Deletes AP session with the id of '2'.
 
    Remove-LSSession -Id 2
 
    .EXAMPLE
 
    Deletes all AP sessions in memory and stored on disk.
 
    Remove-LSSession
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory,
            ValueFromPipelineByPropertyName)]
        [int]
        $Id,
       
        [Parameter()]
        [string]
        $Path = $Script:ModuleDataPath
    )
    Process
    {
        $sessions = Get-LSSession -Id $Id
        Foreach ($session in $sessions)
        {
            If ($session.Saved -eq $true)
            {
                $newData = @{SessionData = @() }
                $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
                Foreach ($_data in $data.SessionData)
                {
                    If ($_data.Id -eq $session.Id)
                    {
                        Continue
                    }       
                    else
                    {
                        $newData.SessionData += $_data
                    }
                }
                $newData | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path
            }
            [array] $Global:_LSSessions = $Global:_LSSessions | Where-Object { $PSItem.Id -ne $session.Id }
        }
    }
}
# Save-LSSession.ps1
Function Save-LSSession
{
    <#
    .SYNOPSIS
 
    Saves an LodasoftPS session to disk.
 
    .DESCRIPTION
 
    Saves an LodasoftPS session to disk.
    The sensetive data is encrypted and stored in the users local application data.
    These saved sessions will be available next time the module is imported.
 
    .PARAMETER Session
 
    LodasoftPS session, created by New-LSSession.
 
    .PARAMETER Path
     
    The path where session data will be stored, defaults to $Script:ModuleDataPath.
 
    .PARAMETER PassThru
     
    Returns the saved session object.
     
    .INPUTS
 
    PSbject. Get-LSSession, New-LSSession
 
    .OUTPUTS
 
    None. Save-LSSession does not generate any output.
 
    .EXAMPLE
     
    #>


    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory,
            ValueFromPipeline)]
        [object]
        $Session,
       
        [Parameter()]
        [string]
        $Path = $Script:ModuleDataPath
    )
    Begin
    {
        If (-not(Test-Path $Path))
        {
            $data = @{SessionData = @() }
        }
        else 
        {
            $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
        }
    }
    Process
    {
        If ($data.SessionData.Id -notcontains $session.Id)
        {
            $_object = @{
                Id          = $Session.Id
                SessionName = $Session.SessionName
                Instance    = $Session.Instance
                Token       = $Session.Token
                Expiration  = $Session.'.expires'
                GrantType   = $Session.GrantType
                Scope       = $Session.Scope
                Origin      = $Session.Origin
                Referer     = $Session.Referer
                Saved       = $true
            }
            If ($Session.PersonalAccessToken)
            {
                $_object.PersonalAccessToken = ($Session.PersonalAccessToken | ConvertFrom-SecureString) 
            }
            If ($Session.Credential)
            {
                $_credentialObject = @{
                    Username = $Session.Credential.UserName
                    Password = ($Session.Credential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                }
                $_object.Credential = $_credentialObject
            }
            If ($Session.Proxy)
            {
                $_object.Proxy = $Session.Proxy
            }
            If ($Session.ProxyCredential)
            {
                $_proxyCredentialObject = @{
                    Username = $Session.ProxyCredential.UserName
                    Password = ($Session.ProxyCredential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                }
                $_object.ProxyCredential = $_proxyCredentialObject
            }
            $data.SessionData += $_object
            $session | Remove-LSSession -Path $Path
        }
    }
    End
    {
        $data | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path
        Write-Verbose "[$($MyInvocation.MyCommand.Name)]: [$SessionName]: Session data has been stored at [$Path]"
    }
}

# Update-LSSession.ps1
Function Update-LSSession
{
    <#
    .SYNOPSIS
 
    Creates a Lodasoft session.
 
    .DESCRIPTION
 
    Creates a Lodasoft session.
    Use Save-LSSession to persist the session data to disk.
    Save the session to a variable to pass the session to other functions.
 
    .PARAMETER SessionName
 
    The name of the session.
 
    .PARAMETER Id
 
    The id of the session.
 
    .PARAMETER Instance
 
    The Lodasoft api instance.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Path
 
    The path where module data will be stored, defaults to $Script:ModuleDataPath.
 
    .PARAMETER GrantType
 
    The type of grant to use.
 
    .PARAMETER Scope
 
    The scope of token to request.
 
    .PARAMETER Origin
 
    The DNS entry for the company name.
 
    .PARAMETER Referer
 
    The DNS entry for the company name.
 
    .LINK
 
    Save-LSSession
    Remove-LSSession
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. New-LSSession returns a PSObject.
 
    .EXAMPLE
 
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory,
            ValueFromPipelineByPropertyName)]
        [string]
        $SessionName,

        [Parameter()]
        [string]
        $Id,

        [Parameter()]
        [uri]
        $Instance,

        [Parameter()]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        [string]
        $GrantType,

        [Parameter()]
        [string]
        $Scope,

        [Parameter()]
        [string]
        $Origin,

        [Parameter()]
        [string]
        $Referer,
        
        [Parameter()]
        [string]
        $Path = $Script:ModuleDataPath
    )
    Begin
    {

    }
    Process
    {
        $getLSSessionSplat = @{
            SessionName = $SessionName
        }
        If ($Id)
        {
            $getLSSessionSplat.Id = $Id
        }
        $existingSessions = Get-LSSession @getLSSessionSplat
        If ($existingSessions)
        {
            Foreach ($existingSession in $existingSessions)
            {
                $newLSSessionSplat = @{
                    SessionName = $SessionName
                }
                If ($Instance)
                {
                    $newLSSessionSplat.Instance = $Instance
                }
                else
                {
                    If ($existingSession.Instance)
                    {
                        $newLSSessionSplat.Instance = $existingSession.Instance
                    }
                }
                If ($Credential)
                {
                    $_credentialObject = @{
                        Username = $Session.Credential.UserName
                        Password = ($Session.Credential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                    }
                    $newLSSessionSplat.Credential = $_credentialObject
                }
                else
                {
                    If ($existingSession.Credential)
                    {
                        $newLSSessionSplat.Credential = $existingSession.Credential
                    }
                }
                If ($Proxy)
                {
                    $newLSSessionSplat.Proxy = $Session.Proxy
                }
                else
                {
                    If ($existingSession.Proxy)
                    {
                        $newLSSessionSplat.Proxy = $existingSession.Proxy
                    }
                }
                If ($ProxyCredential)
                {
                    $_proxyCredentialObject = @{
                        Username = $Session.ProxyCredential.UserName
                        Password = ($Session.ProxyCredential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                    }
                    $newLSSessionSplat.ProxyCredential = $_proxyCredentialObject
                }
                else
                {
                    If ($existingSession.ProxyCredential)
                    {
                        $newLSSessionSplat.ProxyCredential = $existingSession.ProxyCredential
                    }
                }
                If ($GrantType)
                {
                    $newLSSessionSplat.GrantType = $Session.GrantType
                }
                else
                {
                    If ($existingSession.GrantType)
                    {
                        $newLSSessionSplat.GrantType = $existingSession.GrantType
                    }
                }
                If ($Scope)
                {
                    $newLSSessionSplat.Scope = $Session.Scope
                }
                else
                {
                    If ($existingSession.Scope)
                    {
                        $newLSSessionSplat.Scope = $existingSession.Scope
                    }
                }
                If ($Origin)
                {
                    $newLSSessionSplat.Origin = $Session.Origin
                }
                else
                {
                    If ($existingSession.Origin)
                    {
                        $newLSSessionSplat.Origin = $existingSession.Origin
                    }
                }
                If ($Referer)
                {
                    $newLSSessionSplat.Referer = $Session.Referer
                }
                else
                {
                    If ($existingSession.Referer)
                    {
                        $newLSSessionSplat.Referer = $existingSession.Referer
                    }
                }
                If ($existingSession.Saved)
                {
                    $existingSession | Remove-LSSession -Path $Path
                    $session = New-LSSession @newLSSessionSplat 
                    $session | Save-LSSession
                    return $session
                }
                else
                {
                    $existingSession | Remove-LSSession -Path $Path
                    $session = New-LSSession @newLSSessionSplat 
                    return $session
                }
            }
        }
        else
        {
            Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate an AP session with the name [$SessionName]." -ErrorAction Stop
        }
    }
    End
    {
    }
}

# Imported from [D:\a\1\s\LodasoftPS\Tests]