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 |