Public/SEPPmailAPI-Webmail.ps1


<#
.SYNOPSIS
    Retrieve a specific GINA (webmail) user.
.DESCRIPTION
    This CmdLet performs a GET request against the 'webmail/user' API endpoint and
    returns the detailed properties of a single GINA (webmail) user identified by
    its e-mail address. Use Find-SMAGinaUser to search for multiple users.
.PARAMETER email
    E-mail address of the GINA user to retrieve. Mandatory and accepts pipeline input.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the properties of the requested GINA user.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
.LINK
    Find-SMAGinaUser
.LINK
    New-SMAGinaUser
.LINK
    Set-SMAGinaUser
.LINK
    Remove-SMAGinaUser
.EXAMPLE
    PS C:\> Get-SMAGinaUser -email john.doe@contoso.com
    Retrieves the GINA user with the e-mail address john.doe@contoso.com.
#>

function Get-SMAGinaUser {
    [CmdLetBinding()]
    param(
        #region REST-API call path and query parameters
        [Parameter(
            Mandatory                       = $true,
            ValueFromPipeline               = $true,
            HelpMessage                     = 'Enter an e-mail address in correct format i.e. john doe@domain.com'
        )]
        [ValidateNotNullorEmpty()]
        [String]$email,
        #endregion API Params

        #region Config parameters block
        [Parameter(
            Mandatory = $false
            )]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(
            Mandatory = $false
            )]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(
            Mandatory = $false
            )]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(
            Mandatory=$false
            )]
            [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,

        [Parameter(
            Mandatory=$false
            )]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList))
        {
            Throw($missingVarsMessage);
        }
        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {
        Write-Verbose "Creating URL path"
        $uriPath = "{0}/{1}" -f 'webmail', 'user'
        Write-Verbose "Building full request uri with query parameters"
        $boundParam = @{
            email = $email
        }

        $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams
        Write-verbose "Crafting InvokeParam for Invoke-SMARestMethod"
        $invokeParam = @{
            Uri         = $uri 
            Method      = 'GET'
            Cred        =  $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }

        Write-Verbose "Replace wrong '%40' value with '@'"
        $invokeParam.Uri = ($invokeParam.Uri).Replace('%40','@')
        Write-Verbose "Call Invoke-SMARestMethod $($invokeParam.Uri)" 
        $ginaUserRaw = Invoke-SMARestMethod @invokeParam

        Write-Verbose 'Converting Umlauts from ISO-8859-1'
        $ginaUser = ConvertFrom-SMAPIFormat -inputObject $GinaUserRaw #|convertfrom-Json -AsHashtable
        if ($ginaUser) {
            $customerLevel = $ginaUser.PSObject.Properties.Value | Select-Object -First 1
            if ($customerLevel -and $customerLevel.PSObject.Properties) {
                $userData = $customerLevel.PSObject.Properties.Value | Select-Object -First 1
                return $userData
            }        
        }       
    }
}


<#
.SYNOPSIS
    Search for GINA (webmail) users.
.DESCRIPTION
    This CmdLet performs a GET request against the 'webmail/user' API endpoint with the
    'list' query parameter set and returns the matching GINA (webmail) users. You can
    narrow the result down by e-mail, name, customer/tenant or mobile number. Wildcards
    are supported by the API for these filters.
.PARAMETER email
    Filter by e-mail address. Optional. Accepts pipeline input.
.PARAMETER name
    Filter by GINA user display name (case sensitive, wildcards allowed). Optional.
    Has the alias 'DisplayName'.
.PARAMETER customer
    Filter by case sensitive tenant/customer name. Optional. Has the alias 'tenant'.
.PARAMETER mobile
    Filter by mobile number beginning with 00 (wildcards allowed). Optional.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the list of matching GINA users.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
.LINK
    Get-SMAGinaUser
.LINK
    New-SMAGinaUser
.LINK
    Set-SMAGinaUser
.LINK
    Remove-SMAGinaUser
.EXAMPLE
    PS C:\> Find-SMAGinaUser
    Lists all GINA users.
.EXAMPLE
    PS C:\> Find-SMAGinaUser -mobile 0049*
    Filter GINA users by mobile phone. Wildcards are allowed.
.EXAMPLE
    PS C:\> Find-SMAGinaUser -name Sieg*
    Filter GINA users by display name. Wildcards are allowed.
#>

function Find-SMAGinaUser {
    [CmdLetBinding()]
    param(
        #region REST-API call path and query parameters
        [Parameter(
            Mandatory                       = $false,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage                     = 'Enter an e-mail address in correct format i.e. john doe@domain.com'
        )]
        [ValidateNotNullorEmpty()]
        [String]$email,

        [Parameter(
            Mandatory                       = $false,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage                     = 'Enter the GINA user display name (case sensitive). Wildcards are allowed'
        )]
        [ValidateNotNullorEmpty()]
        [alias('DisplayName')]
        [String]$name,

        [Parameter(
            Mandatory                       = $false,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage                     = 'Enter the GINA user display name (case sensitive). Wildcards are allowed'
        )]
        [ValidateNotNullorEmpty()]
        [alias('tenant')]
        [String]$customer,

        [Parameter(
            Mandatory                       = $false,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage                     = 'Enter the GINA users mobile numbner beginning with 00. Wildcards are allowed'
        )]
        [ValidateNotNullorEmpty()]
        [string]$mobile,
        #endregion API Params

        #region Config parameters block
        [Parameter(
            Mandatory = $false
            )]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(
            Mandatory = $false
            )]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(
            Mandatory = $false
            )]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(
            Mandatory=$false
            )]
            [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,

        [Parameter(
            Mandatory=$false
            )]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList))
        {
            Throw($missingVarsMessage);
        }
        $smaParams = @{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {
        Write-Verbose "Creating URL path"
        $uriPath = "{0}/{1}" -f 'webmail', 'user'
        Write-Verbose "Building full request uri with query parameters"
        $boundParam = @{
            list = $true
        }
        if ($customer) {$boundParam.customer = $customer}
        if ($email) {$boundParam.email = $email}
        if ($name) {$boundParam.name = $name}
        if ($mobile) {$boundParam.mobile = $mobile}

        $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams
        Write-verbose "Crafting InvokeParam for Invoke-SMARestMethod"
        $invokeParam = @{
            Uri         = $uri 
            Method      = 'GET'
            Cred        =  $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }

        Write-Verbose "Replace wrong '%40' value with '@'"
        $invokeParam.Uri = ($invokeParam.Uri).Replace('%40','@')
        Write-Verbose "Call Invoke-SMARestMethod $($invokeParam.Uri)" 
        $ginaUserRaw = Invoke-SMARestMethod @invokeParam

        Write-Verbose 'Converting Umlauts from ISO-8859-1'
        $ginaUser = ConvertFrom-SMAPIFormat -inputObject $GinaUserRaw #|convertfrom-Json -AsHashtable
        return $ginaUser
    }
}

<#
.SYNOPSIS
    Create a new GINA (webmail) user.
.DESCRIPTION
    This CmdLet performs a POST request against the 'webmail/user' API endpoint and
    creates a new GINA (webmail) user from the supplied values. Mandatory values are
    e-mail, name and password; all other values are optional. On success the e-mail
    address of the new user is returned.
.PARAMETER email
    E-mail address of the GINA user. Mandatory.
.PARAMETER name
    Full name (or display name) of the GINA user. Mandatory.
.PARAMETER password
    GINA password as a secure string. Mandatory.
.PARAMETER creationInfo
    Note describing why this user was created. Optional.
.PARAMETER customer
    Case sensitive tenant/customer name. Optional.
.PARAMETER mobile
    Mobile number beginning with 00 (spaces allowed, e.g. 0049 123 456789). Optional.
.PARAMETER language
    GINA interface display language. Optional. Valid values: 'd','e','s','i','f'.
    Has the alias 'lg'.
.PARAMETER zipAttachment
    Whether zip attachments are allowed. Optional.
.PARAMETER mustChangePassword
    Whether the GINA user must change the password at next logon. Optional.
.PARAMETER question
    Password reset question. Optional.
.PARAMETER answer
    Password reset answer. Optional.
.PARAMETER accountStatus
    Account status of the GINA user. Valid values: 'enabled','locked'. Defaults to 'enabled'.
.PARAMETER externalAuthentication
    Whether external authentication is used. Optional.
.PARAMETER passwordSecurityLevel
    Available password reset options for this GINA user. Valid values: 'Default',
    'Reset by e-mail verification','no reminder question/answer','Reset by hotline',
    'Reset by hotline, no reminder question/answer','Reset by SMS',
    'Reset by SMS, no reminder question/answer','Let user choose between hotline and SMS'.
    Defaults to 'Default'.
.PARAMETER authToken
    Authentication token for external authentication. Optional.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the e-mail address of the newly created GINA user.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAGinaUser
.LINK
    Find-SMAGinaUser
.LINK
    Set-SMAGinaUser
.LINK
    Remove-SMAGinaUser
.EXAMPLE
    PS C:\> $secpwd = 'TheGinaPassword'|ConvertTo-SecureString -AsPlainText -Force
    PS C:\> New-SMAGinaUser -email john.doe@contoso.com -name 'John Doe' -password $secpwd
    These are the minimum values to create a GINA user. Password must be a securestring.
.EXAMPLE
    PS C:\> $ginaParam = @{email='john.doe@contoso.com';name='John Doe';password=$secpwd;}
    PS C:\> New-SMAGinaUser @ginaParam
    To create a Gina User with more than the minimum values, you may add all needed values as parameters. Beginning with a certain amount of values (>4) the use of a parameter hashtable makes sense.
#>

function New-SMAGinaUser {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        #region REST-API Data parameters
        #mandatory params

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'E-mail address of the GINA user'
        )]
        [ValidateNotNullorEmpty()]
        [string]$email,

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Full Name (or Display Name)'
        )]
        [ValidateNotNullorEmpty()]
        [string]$name,

        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'GINA Password as secure string'
        )]
        [ValidateNotNullorEmpty()]
        [secureString]$password,
        
        #non-mandatory params
        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Notes why this user has been created (Default: PowerShell Module)'
        )]
        [string]$creationInfo,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Case sensitive tenant/customer name'
        )]
        [string]$customer,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'mobile number beginning with 00 (spaces are allowed inbetween, i.e. 0049 123 456789)'
        )]
        [string]$mobile,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'GINA interface display language'
        )]
        [ValidateSet('d','e','s','i','f')]
        [alias('lg')]
        [string]$language,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Zip attachment allowed ?'
        )]
        [bool]$zipAttachment,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Gina user must change the password at next logon'
        )]
        [bool]$mustChangePassword,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Password reset question, i.e. name of first pet ...'
        )]
        [string]$question,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Password reset answer, i.e. biff ...'
        )]
        [string]$answer,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Active or inactive Gina user ?'
        )]
        [ValidateSet('enabled','locked')]
        [string]$accountStatus = 'enabled',

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'External Authentication'
        )]
        [bool]$externalAuthentication,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'What password reset options are possible for this GINA user ?'
        )]
        [ValidateSet(
            'Default', 
            'Reset by e-mail verification',
            'Reset by e-mail verification',
            'no reminder question/answer',
            'Reset by hotline',
            'Reset by hotline, no reminder question/answer',
            'Reset by SMS',
            'Reset by SMS, no reminder question/answer',
            'Let user choose between hotline and SMS'
            )]
        [string]$passwordSecurityLevel = 'Default',

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'External Authentication'
        )]
        [string]$authToken,
        #endregion

        #region Host configuration parameters
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(
            Mandatory=$false
            )]
            [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,

        [Parameter(
                Mandatory=$false
            )]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList))
        {
            Throw($missingVarsMessage);
        }; # end if

        try {
            Write-Verbose "Creating URL path"
            $uriPath = "{0}/{1}" -f 'webmail', 'user'

            Write-Verbose "Building full request uri"
            $smaParams=@{
                Host=$SMAHost;
                Port=$SMAPort;
                Version=$SMAVersion;
            }

            $uri = New-SMAQueryString -uriPath $uriPath @smaParams;
        }
        catch {
            Write-Error "Error $error.CategoryInfo occured"
        }
    }
    process {
        Write-Verbose 'Crafting mandatory $body JSON'
        $bodyHt = @{
            email = $email
            name = $name
            password = $password|ConvertFrom-SecureString -AsPlainText
        }
<# Write-Verbose 'Adding optional values to $body JSON'
        if ($PSBoundParameters.customer) {$bodyHt.customer = $customer}
        if ($PSBoundParameters.creationInfo) {$bodyHt.creationInfo = $creationInfo}
        if ($PSBoundParameters.mobile) {$bodyHt.mobile = $mobile}
        if ($PSBoundParameters.language) {$bodyHt.language = $language}
        if ($PSBoundParameters.zipAttachment -ne $null) {$bodyHt.zipAttachment = $zipAttachment}
        if ($PSBoundParameters.mustChangePassword -ne $null) {$bodyHt.mustChangePassword = $mustChangePassword}
        if ($PSBoundParameters.question) {$bodyHt.question = $question}
        if ($PSBoundParameters.answer) {$bodyHt.answer = $answer}
        if ($PSBoundParameters.accountStatus) {$bodyHt.accountStatus = $accountStatus}
        if ($PSBoundParameters.externalAuthentication -ne $null) {$bodyHt.externalAuthentication = $externalAuthentication}
        if ($PSBoundParameters.passwordSecurityLevel) {$bodyHt.passwordSecurityLevel = $passwordSecurityLevel}
        if ($PSBoundParameters.authToken) {$bodyHt.authToken = $authToken}
#>

        $apiParams = @( 
                'customer',
                'creationInfo',
                'mobile',
                'language',
                'zipAttachment',
                'mustChangePassword',
                'question',
                'mobile',
                'answer',
                'accountStatus',
                'externalAuthentication',
                'passwordSecurityLevel',
                'authToken' 
            )
        foreach ($param in $apiParams) {
            if ($PSBoundParameters.ContainsKey($param)) {
                $bodyHt[$param] = $PSBoundParameters[$param]
            }
        }
        $body = $bodyHt|ConvertTo-JSON
        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
            Uri             = $uri 
            Method          = 'POST'
            body            = $body
            Cred            =  $SMACred
            SkipCertCheck   = $SMASkipCertCheck
        }
        if ($PSCmdLet.ShouldProcess($($bodyHt.Email),"Create user with e-mail $email")) {
            
            Write-Verbose "Call Invoke-SMARestMethod $uri"
            $ginaUserRaw = Invoke-SMARestMethod @invokeParam
            
            Write-Verbose 'Returning e-Mail address of new users'
            return ($ginaUserRaw.message -split ' ')[4]
        }

    }
    end {}
    
}

<#
.SYNOPSIS
    Update an existing GINA (webmail) user.
.DESCRIPTION
    This CmdLet performs a PUT request against the 'webmail/user/{email}' API endpoint
    and updates an existing GINA (webmail) user with the supplied values, for example a
    new password. Only the e-mail and customer are mandatory; all other values are
    optional and only sent when provided.
.PARAMETER email
    E-mail address of the GINA user to update. Mandatory. Accepts pipeline input.
.PARAMETER customer
    Case sensitive tenant/customer name the GINA user currently belongs to. Mandatory.
    Defaults to '[default]'.
.PARAMETER name
    Full name (or display name) of the GINA user. Optional.
.PARAMETER password
    New GINA password as a secure string. Optional.
.PARAMETER mobile
    Mobile number beginning with 00 (spaces allowed, e.g. 0049 123 456789). Optional.
.PARAMETER newCustomer
    New tenant/customer the GINA user shall be assigned to. Optional.
.PARAMETER language
    GINA interface display language. Valid values: 'd','e','s','i','f'. Defaults to 'd'.
    Has the alias 'lg'.
.PARAMETER zipAttachment
    Whether zip attachments are allowed. Optional.
.PARAMETER mustChangePassword
    Whether the GINA user must change the password at next logon. Optional.
.PARAMETER question
    Password reset question. Optional.
.PARAMETER answer
    Password reset answer. Optional.
.PARAMETER accountStatus
    Account status of the GINA user. Valid values: 'enabled','disabled'. Defaults to 'enabled'.
.PARAMETER externalAuthentication
    Whether external authentication is used. Optional.
.PARAMETER passwordSecurityLevel
    Available password reset options for this GINA user. Valid values: 'Default',
    'Reset by e-mail verification','no reminder question/answer','Reset by hotline',
    'Reset by hotline, no reminder question/answer','Reset by SMS',
    'Reset by SMS, no reminder question/answer','Let user choose between hotline and SMS'.
    Defaults to 'Default'.
.PARAMETER authToken
    Authentication token for external authentication. Optional.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the e-mail address of the updated GINA user.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAGinaUser
.LINK
    Find-SMAGinaUser
.LINK
    New-SMAGinaUser
.LINK
    Remove-SMAGinaUser
.EXAMPLE
    PS C:\> $newpw = 'NewGinaPassword'|ConvertTo-SecureString -AsPlainText -Force
    PS C:\> Set-SMAGinaUser -email john.doe@contoso.com -password $newpw
    Change the password of a Gina user.
.EXAMPLE
    PS C:\> $ginaParam = @{email='john.doe@contoso.com';name='John Doe';password=$newpw;}
    PS C:\> Set-SMAGinaUser @ginaParam
    To update a Gina user with more than >4 values the use of a parameter hashtable makes sense.
#>

function Set-SMAGinaUser {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        #region REST-API Data parameters
        #mandatory params

        [Parameter(
            Mandatory = $true,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'E-mail address of the GINA user'
        )]
        [ValidateNotNullorEmpty()]
        [string]$email,

        [Parameter(
            Mandatory = $true,
            ValueFromPipeline               = $true,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Case sensitive tenant/customer name'
        )]
        [string]$customer = '[default]',

        #non-mandatory params

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Full Name (or Display Name)'
        )]
        [ValidateNotNullorEmpty()]
        [string]$name,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'GINA Password as secure string'
        )]
        [ValidateNotNullorEmpty()]
        [secureString]$password,
        

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'mobile number beginning with 00 (spaces are allowed inbetween, i.e. 0049 123 456789)'
        )]
        [string]$mobile,

        [Parameter(
            Mandatory                       = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'tenant/customer the GINA User sall be assigned to'
        )]
        [string]$newCustomer,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'GINA interface display language'
        )]
        [ValidateSet('d','e','s','i','f')]
        [alias('lg')]
        [string]$language = 'd',

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Zip attachment allowed ?'
        )]
        [bool]$zipAttachment,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Gina user must change the password at next logon'
        )]
        [bool]$mustChangePassword,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Password reset question, i.e. name of first pet ...'
        )]
        [string]$question,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
            HelpMessage = 'Password reset answer, i.e. biff ...'
        )]
        [string]$answer,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'Active or inactive Gina user ?'
        )]
        [ValidateSet('enabled','disabled')]
        [string]$accountStatus = 'enabled',

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'External Authentication'
        )]
        [bool]$externalAuthentication,

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'What password reset options are possible for this GINA user ?'
        )]
        [ValidateSet(
            'Default', 
            'Reset by e-mail verification',
            'Reset by e-mail verification',
            'no reminder question/answer',
            'Reset by hotline',
            'Reset by hotline, no reminder question/answer',
            'Reset by SMS',
            'Reset by SMS, no reminder question/answer',
            'Let user choose between hotline and SMS'
            )]
        [string]$passwordSecurityLevel = 'Default',

        [Parameter(
            Mandatory = $false,
            ValueFromPipelineByPropertyName = $false,
            HelpMessage = 'External Authentication'
        )]
        [string]$authToken,
        #endregion

        #region Host configuration parameters
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(
            Mandatory=$false
            )]
            [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,

        [Parameter(
                Mandatory=$false
            )]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList))
        {
            Throw($missingVarsMessage);
        }; # end if
        Write-Verbose "Building full request uri"
        $smaParams=@{
            Host=$SMAHost;
            Port=$SMAPort;
            Version=$SMAVersion;
        }
    }
    process {
        Write-Verbose "Creating URL path"
        $uriPath = "{0}/{1}/{2}" -f 'webmail', 'user', $email

        Write-Verbose "Building full request uri including all bound parameters"
        $boundParam = @{
                   'customer' = $customer
        }
        $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams;

        Write-Verbose 'Crafting $body JSON'
        $bodyHt = @{}
        $apiParams = @( 
                'name',
                'password',
                'mobile',
                #'customer', is managed below as newCustomer !!
                'language',
                'zipAttachment',
                'mustChangePassword',
                'question',
                'answer',
                'accountStatus',
                'externalAuthentication',
                'passwordSecurityLevel',
                'authToken' 
            )
        foreach ($param in $apiParams) {
            if ($PSBoundParameters.ContainsKey($param)) {
                $bodyHt[$param] = $PSBoundParameters[$param]
            }
        }
        if ($bodyHt.password) {$bodyHt.password = $bodyHt.password | ConvertFrom-SecureString -AsPlainText}
        if ($newCustomer) {$bodyHt.customer = $newCustomer}         
        
        $body = $bodyHt|ConvertTo-JSON
        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
            Uri             = $uri 
            Method          = 'PUT'
            body            = $body
            Cred            = $SMACred
            SkipCertCheck   = $SMASkipCertCheck
        }
        if ($PSCmdLet.ShouldProcess($($bodyHt.Email),"Update user with e-mail $email")) {
            Write-Verbose "Call Invoke-SMARestMethod $uri"
            $ginaUserRaw = Invoke-SMARestMethod @invokeParam
            
            return ($ginaUserRaw.message -split ' ')[4]
            #Write-Verbose 'Returning e-Mail address of new users'
            #($ginaUserraw.message -split ' ')[3]
        }
    }
    end {}
    
}

<#
.SYNOPSIS
    Remove an existing GINA (webmail) user.
.DESCRIPTION
    This CmdLet performs a DELETE request against the 'webmail/user/{email}' API
    endpoint and deletes an existing GINA (webmail) user.
.PARAMETER eMail
    E-mail address of the GINA user to delete. Mandatory. Accepts pipeline input.
.PARAMETER customer
    Case sensitive tenant/customer name. Optional.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the e-mail address of the removed GINA user.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAGinaUser
.LINK
    Find-SMAGinaUser
.LINK
    New-SMAGinaUser
.LINK
    Set-SMAGinaUser
.EXAMPLE
    PS C:\> Remove-SMAGinaUser -email john.doe@contoso.com
    Delete Gina user john.doe@contoso.com.
#>

function Remove-SMAGinaUser {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        #region REST-API Data parameters
        #mandatory params

        [Parameter(
                                  Mandatory = $true,
                          ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
                                HelpMessage = 'E-mail address of the GINA user'
        )]
        [ValidateNotNullorEmpty()]
        [string]$eMail,

        [Parameter(
                                  Mandatory = $false,
            ValueFromPipelineByPropertyName = $true,
                                HelpMessage = 'Case sensitive tenant/customer name'
        )]
        [string]$customer,
        #endregion

        #region Host configuration parameters
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(
            Mandatory=$false
            )]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,

        [Parameter(
                Mandatory=$false
            )]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        if (! (verifyVars -VarList $Script:requiredVarList))
        {
            Throw($missingVarsMessage);
        }
        Write-Verbose "Building full request uri"
        $smaParams=@{
            Host=$SMAHost;
            Port=$SMAPort;
            Version=$SMAVersion;
        }
    }
    process {
        Write-Verbose "Creating URL path"
        $uriPath = "{0}/{1}/{2}" -f 'webmail', 'user', $email
        Write-Verbose "Building full request uri including all bound parameters"
        $boundParam = @{
            'customer' = $customer
        }
        $uri = New-SMAQueryString -uriPath $uriPath -qParam $boundParam @smaParams;

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
            Uri           = $uri 
            Method        = 'DELETE'
            Cred          = $SMACred
            SkipCertCheck = $SMASkipCertCheck
        }
        if ($PSCmdLet.ShouldProcess($($bodyHt.Email),"Remove user with e-mail $email")) {
            Write-Verbose "Call Invoke-SMARestMethod $uri"
            $ginaUserRaw = Invoke-SMARestMethod @invokeParam
            if ($ginaUserRaw) {
                $ginauser = ConvertFrom-SMAPIFormat -inputObject $ginaUserRaw
                return ($ginauser.message -split ' ')[4]
            }
        }
    }
    end {}   
}


<#
.SYNOPSIS
    Retrieve a specific webmail (GINA) domain.
.DESCRIPTION
    This CmdLet performs a GET request against the 'webmail/domain' API endpoint and
    returns the configuration of a specific webmail domain. Use Find-SMAWebMailDomain
    to list all available webmail domains.
.PARAMETER customer
    Limit the query to a specific customer/tenant (case sensitive). Optional.
.PARAMETER domainName
    Name of the webmail domain to retrieve. Mandatory and accepts pipeline input.
.PARAMETER host
    Limit the query to a specific host. Optional.
.PARAMETER password
    Password (secure string) used to query the domain configuration. Optional.
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns the configuration object of the requested webmail domain.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Find-SMAWebMailDomain
.EXAMPLE
    PS C:\> Get-SMAWebMailDomain -domainName webmail.contoso.com
    Retrieves the configuration of the webmail domain webmail.contoso.com.
.EXAMPLE
    PS C:\> Get-SMAWebMailDomain -domainName webmail.contoso.com -customer Contoso
    Retrieves the webmail domain limited to the customer/tenant Contoso.
#>

function Get-SMAWebMailDomain
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'limit to a specific customer (case sensitive, default: [default]'
        )]
        [SMARestType('query')]
        [string]$customer, 

        [Parameter(
                            Mandatory       = $true,
                            HelpMessage     = 'limit to a specific domain',
                          ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [SMARestType('query')]
        [string]$domainName, 

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'limit to a specific host'
        )]
        [SMARestType('query')]
        [string]$host, 

        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'hostname shown in System / Hostname'
        )]
        [SMARestType('query')]
        [SMAParamFilter('password')]
        [secureString]$password,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'webmail', 'domain'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($myInvocation.Mycommand.Parameters.Values)"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"

        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return object
            if ($RestResult) {
                $returnData = Format-SMARestResult $RestResult -object #TODO: object, StringPos3, StringPos2to4, StringPos2to6, StringPos0to3,StringPos0to9, objectArray, nattiveJson
                return $returnData
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }
}

<#
.SYNOPSIS
    List webmail (GINA) domains.
.DESCRIPTION
    This CmdLet performs a GET request against the 'webmail/domain' API endpoint with
    the 'list' query parameter set and returns a flat, sorted and unique list of all
    webmail domain names across all customers. Use Get-SMAWebMailDomain to fetch a
    specific domain.
.PARAMETER limit
    Limit the result to a specific number of entries. Defaults to 0 (all entries are returned).
.PARAMETER SMAHost
    SEPPmail API hostname. Defaults to the configured value.
.PARAMETER SMAPort
    SEPPmail API port. Defaults to the configured value.
.PARAMETER SMAVersion
    SEPPmail API version. Defaults to the configured value.
.PARAMETER SMACred
    API credentials (PSCredential). Defaults to the configured value.
.PARAMETER SMASkipCertCheck
    Skip SSL certificate validation. Use only in test environments.
.OUTPUTS
    System.Management.Automation.PSCustomObject
        Returns a sorted, unique list of webmail domain names.
.NOTES
    - Requires an active SEPPmail API session (New-SMAConfiguration).
    - Supports -WhatIf and -Confirm.
.LINK
    Get-SMAWebMailDomain
.EXAMPLE
    PS C:\> Find-SMAWebMailDomain
    Lists all webmail domains.
.EXAMPLE
    PS C:\> Find-SMAWebMailDomain -limit 10
    Lists at most 10 webmail domains.
#>

function Find-SMAWebMailDomain
{
    [CmdletBinding(
        SupportsShouldProcess = $true
    )]
    param (
        #region API params
        [Parameter(
            Mandatory       = $false,
            HelpMessage     = 'limit to a specific amount of entries (default: 0 = all entries are returned)'
        )]
        [SMARestType('query')]
        [int]$limit = 0,
        #endregion API params
        
        #region Config parameters block
        [Parameter(Mandatory = $false)]
        [String]$SMAHost = $Script:activeCfg.SMAHost,

        [Parameter(Mandatory = $false)]
        [int]$SMAPort = $Script:activeCfg.SMAPort,

        [Parameter(Mandatory = $false)]
        [String]$SMAVersion = $Script:activeCfg.SMAPIVersion,

        [Parameter(Mandatory=$false)]
        [System.Management.Automation.PSCredential]$SMACred=$Script:activeCfg.SMACred,
        
        [Parameter(Mandatory=$false)]
        [switch]$SMASkipCertCheck=$Script:activeCfg.SMAskipCertCheck
        #endregion
    )

    begin {
        Write-verbose "Verifying required variables from SMA Config"
        if (! (verifyVars -VarList $Script:requiredVarList)) {Throw($missingVarsMessage)} # end if

        Write-verbose "Rest methdod is $restMethod"
        $RestMethod = 'GET'

        Write-Verbose "Creating URL base path"
        $uriPath = "{0}/{1}" -f 'webmail', 'domain'

        Write-Verbose "Adding SMA Params"
        $smaParams=@{
            Host    = $SMAHost
            Port    = $SMAPort
            Version = $SMAVersion
        }
    }
    process {   
        Write-Verbose "Getting parameter arrays for Body, Path and Query from $($($myInvocation.Mycommand.Parameters.Values))"
        $paramArrays = Get-SMAParameterArray -ParentPSBoundParameters $PSBoundParameters -ParentInvocation $MyInvocation.MyCommand.Parameters.Values
        Write-Debug "ParamArrays: $($paramArrays | Out-String)"

        Write-verbose "Initializing REST-Data structures"
        [string]$uri                = $null
        [hashtable]$bodyHt          = @{}
        [hashtable]$queryParamHt    = @{}

        Write-verbose "Adding optional path to basepath based on $($paramArrays.Path) parameters"
        if ($paramArrays.Path.Count -gt 0) {
            Foreach ($pathParam in $paramArrays.Path) {
                $uriPath = "{0}/{1}" -f $uriPath, $PSBoundParameters[$pathParam]
            }
        }
        Write-Debug "Final uri path is: $uriPath"

        Write-verbose "Building body HashTable based on $($paramArrays.Body) parameters"
        if ($paramArrays.Body.Count -gt 0) {
            Foreach ($bodyParam in $paramArrays.Body) {
                $bodyHt[$bodyParam] = $PSBoundParameters[$bodyParam]
            }
        }
        if ($paramArrays.password.Count -gt 0) {
            Foreach ($passwordParam in $paramArrays.password) {
                $secureString = $PSBoundParameters[$passwordParam]
                $plainText = ConvertFrom-SecureString $secureString -AsPlainText
                $bodyHt[$passwordParam] = $plainText
            }
        }
        $body = $bodyHt | ConvertTo-Json
        Write-Debug "Body JSON: $body"

        Write-Verbose "Hardcoding 'List' as query parameter for Find CmdLet"
        $queryParamHt['list'] = 'true'

        Write-verbose "Building query string based on $($paramArrays.Query) parameters"
        if ($paramArrays.Query.Count -gt 0) {
            Foreach ($queryArrayParam in $paramArrays.Query) {
                $queryParamHt[$queryArrayParam] = $PSBoundParameters[$queryArrayParam]
            }
        }
        Write-Debug "QueryParams: $($queryParamHt | Out-String)"


        Write-Verbose "Constructing full URI based on parameters"
        if ($queryParamHt) {
            $uri = New-SMAQueryString -uriPath $uriPath -qParam $queryParamHt @smaParams
        }
        else {
            $uri = New-SMAQueryString -uriPath $uriPath @smaParams
        }
        Write-Debug "Final URI: $uri"

        Write-verbose "Crafting Invokeparam for Invoke-SMARestMethod"
        $invokeParam = @{
                      Uri = $uri 
                   Method = $RestMethod
                     Cred = $SMACred
                     body = $body
            SkipCertCheck = $SMASkipCertCheck
        }
        Write-Debug "InvokeParam: $($invokeParam | Out-String)"

        # Prepare WhatIf message based on invokeParam
        $whatIfTarget = $invokeParam.Uri
        $whatIfAction = "$($invokeParam.Method) request"
        if ($invokeParam.body) {
            $whatIfAction += " with body: $($invokeParam.body)"
        }

        if ($PSCmdlet.ShouldProcess($whatIfTarget, $whatIfAction)) {
            Write-Verbose "Call Invoke-SMARestMethod $uri" 
            $RestResult = Invoke-SMARestMethod @invokeParam
            # Return flat list of webmail domain names across all customers
            if ($RestResult) {
                $domainList = @()
                foreach ($customerProp in $RestResult.PSObject.Properties) {
                    foreach ($domName in $customerProp.Value) {
                        $domainList += $domName
                    }
                }
                return ($domainList | Sort-Object -Unique)
            }
            else {
                Write-Information 'Nothing to return'
            }
        }
        else {
            Write-Verbose "WhatIf: Operation skipped by user"
        }
    }
    end {
    }
}



# Create Alias GU for GINAUser
Write-Verbose 'Create CmdLet Alias for GINA users' 
$custVerbs = ('Get','New','Remove','Find','Set')

Foreach ($custverb in $custVerbs) {
    $aliasname = $custverb + '-SMAGU'
    $cmdName = $custverb + '-SMAGinaUser'
    New-Alias -Name $aliasName -Value $cmdName
}



# SIG # Begin signature block
# MIIVyAYJKoZIhvcNAQcCoIIVuTCCFbUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDKlwDGjlOFCaGO
# oBUtOIK7IKlvrI3IsvGHoS4g1WBRnaCCEgQwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggZvMIIE16ADAgECAhBIqMP3CCLHOHtOKuaWNyeFMA0GCSqG
# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
# HhcNMjYwNDE1MDAwMDAwWhcNMjcwNzE0MjM1OTU5WjBmMQswCQYDVQQGEwJERTEP
# MA0GA1UECAwGQmF5ZXJuMSIwIAYDVQQKDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBH
# bWJIMSIwIAYDVQQDDBlTRVBQbWFpbCBEZXV0c2NobGFuZCBHbWJIMIICIjANBgkq
# hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvAFzE8MbJpvQt+IdIh1M+bKYsJBFDk4b
# 9ySe25IrCi00B9o5XmQtIw42MqyIKbUq1tDARtp9KTQedEP9W+rflAF2l+0Z046J
# kiqumU9/enbqWLDyln1aS/p7HOgwZFMhnsR9zH0MfFckiklUmkzJO+vmzYAK7ZmD
# xajNLJs0gkGRU2/BecAx/TSvLXMaKONsKZCyMKQCnwo1mCY/tFl5EgUz7YQFrPOR
# BQGfQke/hkdBfQDqNRsi/J6+KhJWc6LvgQihdRg/INQbQsTxlow18NWvyFsjjueH
# 7kG6HR4YKfbv07xgrsIh8xvq9ZJ1SBhLXmkg4SdoQGASjqR6o3keAX+bDRFf+hml
# WWJp/FqVHR5QomF3vbK2/bbz4jAclYSPx/sPasNJ0YnKFkgmowZ7Ysa0KA0/egBg
# tI4gJ+8V7zrqIVEG3rMQh9KCdMnJqP2aM9o4gUzQvE1M4x606liX9EWwdLLS+fe7
# 9o+Fzo5oH4wBE/En6hQQkzseHHu+TXCDd6zUUZ/PlTK0gTaDIRXt6UzPNqJ4RiRC
# W2pNFcPt078qqVTuwKUXoE4ufxGgXKFrZlCYST/9eG1TnW2oq19nz8A333GCsL3g
# poNIKvfmDyGMMNzvx2aeqn2v6e75z8kH19iGSNZ51xT+WgS9F1aIvjz08/T7XAv7
# iDPF1/gPIp8CAwEAAaOCAakwggGlMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1Sm
# KaoXpM0MMB0GA1UdDgQWBBS30/Tq+alF3j2BY5up8n5zpAU23DAOBgNVHQ8BAf8E
# BAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAE
# QzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp
# Z28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2Ny
# bC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmww
# eQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28u
# Y29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcw
# AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETc3VwcG9ydEBz
# ZXBwbWFpbC5jaDANBgkqhkiG9w0BAQwFAAOCAYEAi7fmb5UYoemWG3CC4K2UZWVr
# R6GOfi8gbJKgjPbKO4zrCrU/x6cOdyp6scKZfUEGFDf8KH6pP4pAQv1Hsbi49gU2
# kxoUWLlCiipn05qJY663DHx9hlStej/ZdEatou0wyCDiG5xD7kmG+1t6iLyyCBgE
# B88tJpzTjI61qXmBTS/FGEOAsB4SDEW1ngA7bc5FOv4IUKA43hp8M+N3GeYFzDqw
# JELYEfVVYheBW3o7q4VrCdfFEuaQihOtvfDfYpP6ANgekNn8HdsMT8rx9D1I50Rl
# i/qQFo2BOuPyb2SIQPzJvCs5wgi5qgp1nHiN6igumu2Cz7BmGjOazGUgCSUY5Qwy
# E8+F+R2tVM+2O15rfX01+e56ZfojBEiEjMwfPHs3fa3V3gokWWNwUMkton/v0R/n
# l2zjmOr2okohOINZEDh9frg21zUCN5ZD8Y4zQWuiJLCvvvBZs0JR4c9xl2k2wtw/
# QLPhGU69zM3smGpRoLE8M6zvUvSU7jXjvefazUniMYIDGjCCAxYCAQEwaDBUMQsw
# CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJT
# ZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhBIqMP3CCLHOHtOKuaW
# NyeFMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw
# GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG
# AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIEhWckOuwQB53ycqd7ZJNLUMMZQ70zHc
# MO/njxriPnMgMA0GCSqGSIb3DQEBAQUABIICAFnjVwP1j1k+1ArSqlL8C/yocM4p
# GJ+QMDWmD80a7djPRjWRQG0QgMjFIPTIVIllw/49mHekFVHFGY7RuM8YZc1PBUy2
# ukr4pz7PSP1NE4CE1uoz7gToBc3sv4SXwIdi4gOHyqbuTQhByV3xsPE57+cvkS6F
# USDGEngwSyr9DeRrGbbzvK1+2oJLFzqdL0OCTQybdvlbdtH/WrSIKVybs0S5PS7R
# QefXJPzgJI0H5jH07Zsvf1U49U5AzWmB99bCwxrYZt9EJ+mhpCUVZDbJKS9tEfbr
# v4/MBrjkVLaVuxTwUMejPPPPbT/2tMyf5OGIdydYpPPbKkvXPtmO6xK3reWYkgoQ
# J+nlaa8OW88eSeE6AI3SNECQ9fvLDSLxduB6XWNdAqQFLEUCvFtM40C0JKxL9N/c
# gcOwpqjAZnGO7L85fdijpWhLJp1Bs/JXTY7kxEeD3hmfPjXSvgpEHPdhkKOGFhNr
# eL9jCcAdGqB9+TC40zZigMHHio0V5QaG4tJJGu1CYZectsM4dczF2yROA9F0Q3gX
# oyPwT1hm3+fZ9jYo+L9H3qHuJbDrI2jOJQjmy8+JsiIYhqcx70aE3S/U3oz5wJiD
# 0Z6bqxyMke3j4AVKGfKgOiSAUkHT5srf28W3LPsuXVjOtuU3KWI2AqB9TPVThpdz
# djY2aXGw6zM4LuEd
# SIG # End signature block