FastTrack-KeyVaultRequests.psm1

Add-Type -AssemblyName System.Web -ErrorAction SilentlyContinue

Function Get-ResponseError {
<#
.SYNOPSIS
    Get-ResponseError converts HtmlWebResponse error to HtmlWebResponseObject for output
.DESCRIPTION
    Get-ResponseError inputs HtmlWebResponse error and converts to HtmlWebResponseObject for output
.PARAMETER
    Response is the error response returned from webrequest
.EXAMPLE
    Get-ResponseError $_.Exception.Response
.INPUTS
    System.Net.HttpWebResponse
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param([System.Net.HttpWebResponse]$Response)
    $streamReader = New-Object System.IO.StreamReader($Response.GetResponseStream())
    $streamReader.BaseStream.Position = 0
    $streamReader.DiscardBufferedData()
    $body = ConvertFrom-Json($streamReader.ReadToEnd())
    if([string]::IsNullOrEmpty($body))
    {
        $body = ConvertFrom-Json("{}")
    }
    Add-Member -InputObject $body -MemberType NoteProperty -Name "StatusCode" -Value $_.Exception.Response.StatusCode
    $body
}

Function Invoke-GetRequest {
<#
.SYNOPSIS
    Call Rest API with input variables to retrieve appropriate response
.DESCRIPTION
    The Invoke-GetRequest cmdlet utilizes the header parameter to perform the REST API call to modify a FastTrack migration. The REST API is defined in the URI parameter and returns the API's webresponse.
.PARAMETER
    Uri as the endpoint HTML address for the REST API
    Headers is a collection of header keys and values required by the API to return results
.EXAMPLE
    $JsonResult = Invoke-GetRequest -Uri ([System.String]::Format("{0}/{1}/DSR/Status/TransactionId/{2}?{3}", $global:CsiApiBaseUriFormat, $TenantId, $TransactionId, $query)) -Headers $header
.INPUTS
    System.String
    System.Collections.Hashtable
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param([String]$Uri, [hashtable]$Headers)
    $response = try {
        Invoke-RestMethod -Method GET -Uri $Uri -ContentType 'application/json' -Headers $Headers
    } catch {
        Get-ResponseError $_.Exception.Response
    }

    return $response
}

Function Invoke-PostRequest {
<#
.SYNOPSIS
    Call Rest API with input variables to retrieve appropriate response
.DESCRIPTION
    The Invoke-PostRequest cmdlet utilizes the body and header parameters to perform the REST API call to modify a FastTrack migration. The REST API is defined in the URI parameter and returns the API's webresponse.
.PARAMETER
    Uri as the endpoint HTML address for the REST API
    Headers is a collection of header keys and values required by the API to return results
    Body is the collected form data required by the API to return results
.EXAMPLE
.INPUTS
    System.String
    System.Collections.Hashtable
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param([String]$Uri, [hashtable]$Headers, [String]$Body)
    $response = try {
    Invoke-RestMethod -Method POST -Uri $Uri -ContentType 'application/json;charset=utf-8'  -Headers $Headers -Body ([System.Text.Encoding]::UTF8.GetBytes($Body))
    } catch {
    Get-ResponseError $_.Exception.Response
    }

    return $response
}

Function Invoke-PutRequest {
<#
.SYNOPSIS
    Call Rest API with input variables to retrieve appropriate response
.DESCRIPTION
    The Invoke-DeleteRequest cmdlet utilizes the body and header parameters to perform the REST API call to delete a FastTrack migration. The REST API is defined in the URI parameter and returns the API's webresponse.
.PARAMETER
    Uri as the endpoint HTML address for the REST API
    Headers is a collection of header keys and values required by the API to return results
    Body is the collected form data required by the API to return results
.EXAMPLE
.INPUTS
    System.String
    System.Collections.Hashtable
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param([String]$Uri, [hashtable]$Headers, [String]$Body)
    $response = try {
    Invoke-RestMethod -Method PUT -Uri $Uri -ContentType 'application/json' -Headers $Headers -Body $Body
    } catch {
    Get-ResponseError $_.Exception.Response
    }

    return $response
}

Function Invoke-DeleteRequest {
<#
.SYNOPSIS
    Deletes Transaction
.DESCRIPTION
    The Invoke-DeleteRequest cmdlet utilizes the body and header parameters to perform the REST API call to delete a FastTrack migration. The REST API is defined in the URI parameter and returns the API's webresponse.
.PARAMETER
    Uri as the endpoint HTML address for the REST API
    Headers is a collection of header keys and values required by the API to return results
    Body is the collected form data required by the API to return results
.EXAMPLE
    $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("{0}KeyVault",$global:CsiApiBaseUriFormat)) -Headers $header -Body $serializedJson
.INPUTS
    System.String
    System.Collections.Hashtable
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param([String]$Uri, [hashtable]$Headers, [String]$Body)
    $response = try {
    Invoke-RestMethod -Method DELETE -Uri $Uri -ContentType 'application/json' -Headers $Headers -Body $Body
    } catch {
    Get-ResponseError $_.Exception.Response
    }

    return $response
}

Function Waiting-TransactionComplete() {
<#
.SYNOPSIS
    Find status of Transaction
.DESCRIPTION
    The Waiting-TransactionComplete cmdlet takes a TransactionId, as a string object, invoking the REST API to retrieve the transaction's status. While the status of the transaction is not "completed" or "failed," the Get-FastTrackMigrationTransactionStatus is called and checked for an updated status. Once comleted or failed, the transaction is returned to the caller.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
.PARAMETER
    TransactionId is the GUID representing the specified transaction
.EXAMPLE
    Waiting-TransactionComplete -TransactionID ($JsonResult.TransactionId)
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
.LINK
#>

    param([string] $TransactionID = $(throw "Transaction ID unable to find, Please try again."))

    [array]$FinalResults = "Completed","Failed"

    $current = $previous = 1;
    do {
        $Transaction = Get-FastTrackMigrationTransactionStatus -TransactionID $TransactionID

        for ($j = 1; (!$FinalResults.Contains($Transaction.Status) -and $j -le $current); $j++) {
            sleep -Milliseconds 1000
            Write-Progress -Id 1 -Activity Waiting -Status 'Next attempt will start ' -PercentComplete ($j/$current*100) -SecondsRemaining ($current-$j)
        }
        $current,$previous = ($current + $previous),$current

    } while ($current -lt 60 -and !$FinalResults.Contains($Transaction.Status))
    return $Transaction
}

Function SetBaseRequestValues {
<#
.SYNOPSIS
    Set object initial values for Request
.DESCRIPTION
    The SetBaseRequestValues cmdlet is used to create a CustomerObject that holds the customer's administrative credentials, and FastTrack migration Id. Once created the CustomerObject is returned to the caller.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
.PARAMETER
    TenantId is the GUID of the Customer
    CompanyName is the name of the customer company
    LogonUserEmail is the customer email utilized for customer account login
.EXAMPLE
    $jsonObj = SetBaseRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"] `
        -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
        -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account
.INPUTS
    System.String
.OUTPUTS
    Powershell Object CustomerObject
.LINK
#>

    param
    (
        [string] $TenantID,
        [string] $CompanyName,
        [string] $LogonUserEmail
    )
        $TransactionId = New-Guid

        $CustomerIdentity = (New-Object PSObject |
        Add-Member -PassThru NoteProperty TenantId $TenantID |
        Add-Member -PassThru NoteProperty CompanyName $CompanyName |
        Add-Member -PassThru NoteProperty LogOnUserEmail $LogonUserEmail)

        $CustomerObject = (New-Object PSObject |
        Add-Member -PassThru NoteProperty TransactionId $TransactionId |
        Add-Member -PassThru NoteProperty Customer $CustomerIdentity)

        return $CustomerObject
}

Function SetKvRequestValues {
<#
.SYNOPSIS
    Generate RequestObject to input keyvault secret for customer
.DESCRIPTION
    The SetKvRequestValues cmdlet is utilized to create a custom object that shall be used to add or edit a keyvault secret. The secret is defined by the KeyVaultSecretValue paramter and is placed or edited in the keyvault using the key defined by the KeyVaultSecretName parameter. SetKvNewUpdateRequestValues returns a customer powershell object to the caller.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
.PARAMETER
    RequestObject
    KeyVaultSecretName key used for keyvault secret
    KeyVaultSecretValue secret to be stored in keyvault
    MigrationType defines type of migration for request submitted
    Region Azure region used for transaction
.EXAMPLE
    $deleteJson = SetKvRequestValues -RequestObject:$jsonObj `
        -KeyVaultSecretName:$SecretName `
        -Region:$Region `
        -MigrationType:$MigrationType
.INPUTS
    PSObject
    System.String
.OUTPUTS
    PSObject RequestObject
.LINK
#>

    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject] $RequestObject,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $KeyVaultSecretName,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $KeyVaultSecretValue,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $MigrationType = "Notes",
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject] $Region
    )

    return ($RequestObject |
                Add-Member -PassThru NoteProperty Name $KeyVaultSecretName |
                Add-Member -PassThru NoteProperty Value $KeyVaultSecretValue |
                Add-Member -PassThru NoteProperty Region $Region |
                Add-Member -PassThru NoteProperty EnvironmentType $global:MsoComOrGov |
                Add-Member -PassThru NoteProperty MigrationType $MigrationType)
}

Function SetKvNewUpdateRequestValues {
<#
.SYNOPSIS
.DESCRIPTION
    The SetKvNewUpdateRequestValues cmdlet is utilized to create a custom object that shall be used to add or edit a keyvault secret. The secret is defined by the KeyVaultSecretValue paramter and is placed or edited in the keyvault using the key defined by the KeyVaultSecretName parameter. SetKvNewUpdateRequestValues returns a customer powershell object to the caller.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
.PARAMETER
    RequestObject
    KeyVaultSecretName key used for keyvault secret
    KeyVaultSecretValue secret to be stored in keyvault
    MigrationType defines type of migration for request submitted
    Region Azure region used for transaction
    Comment used to define additional information for credentials
    CredType established credentials type used to define credentials
.EXAMPLE
    $updateJsonObj = SetKvNewUpdateRequestValues -RequestObject:$jsonObj `
        -KeyVaultSecretName:$SecretName `
        -KeyVaultSecretValue:$SecretValue `
        -Region:$Region `
        -MigrationType:$MigrationType `
        -Comment: $Comment `
        -CredType $CredentialType
.INPUTS
    PSObject
    System.String
.OUTPUTS
    HttpWebResponseObject
.LINK
#>

    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject] $RequestObject,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $KeyVaultSecretName,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $KeyVaultSecretValue,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $MigrationType = "Notes",
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $Region,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $Comment = $null,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $CredType
    )

    $CredTypeob =(New-Object PSObject |
                Add-Member -PassThru NoteProperty CredType $CredType |
                Add-Member -PassThru NoteProperty Comments $Comment)

    $result = ($RequestObject |
                Add-Member -PassThru NoteProperty Name $KeyVaultSecretName |
                Add-Member -PassThru NoteProperty Value $KeyVaultSecretValue |
                Add-Member -PassThru NoteProperty Region $Region |
                Add-Member -PassThru NoteProperty EnvironmentType $global:MsoComOrGov |
                Add-Member -PassThru NoteProperty MigrationType $MigrationType |
                Add-Member -PassThru NoteProperty CredType $CredTypeob)

    return $result
}

Function SetKvGetRequestValues {
<#
.SYNOPSIS
   Define PSObject to get KeyVault secrets
.DESCRIPTION
    The SetKvGetRequestValues cmdlet is utilized to create a custom object that defines a powershell custom object to contain the KeyVault request object, type of migration, account region, and the administrator login credentials. SetKvGetRequestValues returns the custom object to the caller.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
.PARAMETER
    RequestObject
    MigrationType defines type of migration for request submitted
    Region Azure region used for transaction
    CredType established credentials type used to define credentials
.EXAMPLE
    $updateJsonObj = SetKvGetRequestValues -RequestObject:$jsonObj `
        -Region:$Region `
        -MigrationType:$MigrationType `
        -CredType $CredentialType
.INPUTS
    PSObject
    System.String
.OUTPUTS
    HtmlWebResponseObject
.LINK
#>

    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject] $RequestObject,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $MigrationType = "Notes",
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $Region,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $CredType
    )

    $result = ($RequestObject |
                Add-Member -PassThru NoteProperty Region $Region |
                Add-Member -PassThru NoteProperty EnvironmentType $global:MsoComOrGov |
                Add-Member -PassThru NoteProperty MigrationType $MigrationType |
                Add-Member -PassThru NoteProperty CredType $CredType)

    return $result
}

function New-FastTrackMigrationSecret {
    <#
    .SYNOPSIS
         Create a new FastTrack Migration secret
    .DESCRIPTION
        The New-FastTrackMigrationSecret cmdlet invokes the REST API to add a secret to the customer's secrets in keyvault. New-FastTrackMigrationSecret calls Waiting-TransactionComplete to repeat until a "completed" or "failed" transaction is returned from the REST API.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
 
        Please Note: Passwords should contain at least 1 lower case letter.
                     Passwords should contain at least 1 upper case letter.
                     Passwords should contain at least 1 number.
                     Passwords should contain at least 3 special characters.
                     Passwords must be at least 15 characters long.
 
        Access Notes: RDG and VPN credentials can only be created/accessed/modified through the Fast Track Migration Portal / AKV tab.
    .PARAMETER SecretName
        Unique name for new Secret.
    .PARAMETER SecretValue
        Value for new Secret.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .PARAMETER CredentialType
        The type of credential.
        Valid options are:
            Admin,
            Certificate,
            Migration_Account,
            Mig_Sched,
            Sharepoint,
            SAS,
            VPN,
            Encrypted,
            PowerBI
    .PARAMETER Comment
        Any comment related to credential.
    .EXAMPLE
        New-FastTrackMigrationSecret -SecretName:"NewSecret" -SecretValue:"NewSecretValue" -Region:"Region" -MigrationType:"Mig-ExHybrid" -CredentialType "Admin"
        This will create a new Secret named as NewSecret and value as NewSecretValue.
    .INPUTS
        System.String
    .OUTPUTS
        System.Management.Automation.PSObject
            This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
    .LINK
        Set-FastTrackMigrationSecret
        Remove-FastTrackMigrationSecret
        Get-FastTrackMigrationSecrets
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $SecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $SecretValue,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Mig-ExHybrid","Mig-ExSimpleMRS","Mig-ExCutover","Mig-ExStaged","Mig-IMAP","Mig-GmailCutover","Mig-GmailStaged","Mig-GroupWise","Mig-GoogleDrive","Mig-GoogleSites","Mig-Box","Mig-FileSharesToOneDrive","Mig-FileSharesToTeamSites","Mig-Domino-BAM","Mig-Domino-ODME","MIG-SPOnPrem")]
            [string] $MigrationType,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Admin", "Certificate", "Migration_Account", "Mig_Sched", "Sharepoint", "SAS", "VPN", "Encrypted", "PowerBI")]
            [string] $CredentialType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [string] $Comment
        )

    if($global:MsoAdminProperties.Count -eq 0)
    {
        Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
        return
    }

    $jsonObj = SetBaseRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"]  `
                                -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account

    $updateJsonObj = SetKvNewUpdateRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$SecretName `
                                        -KeyVaultSecretValue:$SecretValue `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType `
                                        -Comment: $Comment `
                                        -CredType $CredentialType

    $serializedJson = $updateJsonObj | ConvertTo-Json -Compress: $true

    $header = @{}
    if($global:v2FeatureFlag -eq $true){
    $header.Add("Authorization", $global:MsoAdminProperties["AuthorizationResult"].CreateAuthorizationHeader())}
    else{
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)}
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending Secret Create Request..."

    $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("{0}KeyVault/Set",$global:CsiApiBaseUriFormat)) -Headers $header -Body $serializedJson

    if($JsonResult.StatusCode -ne $null)
    {
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Waiting-TransactionComplete -TransactionID ($JsonResult.TransactionId)
    }

}

function Set-FastTrackMigrationSecret {
    <#
    .SYNOPSIS
        Update an existing FastTrack Migration Secret
    .DESCRIPTION
        The New-FastTrackMigrationSecret cmdlet is utilized to update a keyvault secret for the FastTrack account. The secret is defined by the SecretValue paramter and is placed in the keyvault using the key defined by the SecretName parameter.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
 
        Please Note: Passwords should contain at least 1 lower case letter.
                     Passwords should contain at least 1 upper case letter.
                     Passwords should contain at least 1 number.
                     Passwords should contain at least 3 special characters.
                     Passwords must be at least 15 characters long.
 
        Access Notes: RDG and VPN credentials can only be created/accessed/modified through the Fast Track Migration Portal / AKV tab.
    .PARAMETER SecretName
        Unique name for already existing Secret.
    .PARAMETER SecretValue
        New value for specified Secret.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .PARAMETER CredentialType
        The type of credential.
        Valid options are:
            Admin,
            Certificate,
            Migration_Account,
            Mig_Sched,
            Sharepoint,
            SAS,
            VPN,
            Encrypted,
            PowerBI
    .PARAMETER Comment
        Any comment related to credential.
    .EXAMPLE
        Set-FastTrackMigrationSecret -SecretName:"SecretValueName" -SecretValue:"ChangedSecretValue" -Region:"Region" -MigrationType:"Mig-ExHybrid" -CredentialType "Admin"
        This will update the value of SecretValueName as ChangedSecretValue.
    .INPUTS
        System.String
    .OUTPUTS
        System.Management.Automation.PSObject
            This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
    .LINK
        New-FastTrackMigrationSecret
        Remove-FastTrackMigrationSecret
        Get-FastTrackMigrationSecrets
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $SecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $SecretValue,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Mig-ExHybrid","Mig-ExSimpleMRS","Mig-ExCutover","Mig-ExStaged","Mig-IMAP","Mig-GmailCutover","Mig-GmailStaged","Mig-GroupWise","Mig-GoogleDrive","Mig-GoogleSites","Mig-Box","Mig-FileSharesToOneDrive","Mig-FileSharesToTeamSites","Mig-Domino-BAM","Mig-Domino-ODME","MIG-SPOnPrem")]
            [string] $MigrationType,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Admin", "Certificate", "Migration_Account", "Mig_Sched", "Sharepoint", "SAS", "VPN", "Encrypted", "PowerBI")]
            [string] $CredentialType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [string] $Comment
        )

    if($global:MsoAdminProperties.Count -eq 0)
    {
        Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
        return
    }

    $jsonObj = SetBaseRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"]  `
                                -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account

    $updateJsonObj = SetKvNewUpdateRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$SecretName `
                                        -KeyVaultSecretValue:$SecretValue `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType `
                                        -Comment: $Comment `
                                        -CredType $CredentialType

    $serializedJson = $updateJsonObj | ConvertTo-Json -Compress: $true

    $header = @{}
    if($global:v2FeatureFlag -eq $true){
    $header.Add("Authorization", $global:MsoAdminProperties["AuthorizationResult"].CreateAuthorizationHeader())}
    else{
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)}
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending Secret Update Request..."

    $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("{0}KeyVault/Set",$global:CsiApiBaseUriFormat)) -Headers $header -Body $serializedJson

    if($JsonResult.StatusCode -ne $null)
    {
        # Error?
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Waiting-TransactionComplete -TransactionID ($JsonResult.TransactionId)
    }

}

function Remove-FastTrackMigrationSecret {
    <#
    .SYNOPSIS
        Remove an existing FastTrack Migration secret
    .DESCRIPTION
        The Remove-FastTrackMigrationSecret cmdlet invokes the REST API to remove a secret from the customer's secrets in keyvault. Remove-FastTrackMigrationSecret calls Waiting-TransactionComplete to repeat until a "completed" or "failed" transaction is returned from the REST API.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
    .PARAMETER SecretName
        Unique name for already existing secret.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .EXAMPLE
        Remove-FastTrackMigrationSecret -SecretName:"SecretValueName" -Region:"Region" -MigrationType:"Mig-ExHybrid"
        This will remove the SecretValueName.
    .INPUTS
        System.String
    .OUTPUTS
        System.Management.Automation.PSObject
            This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
    .LINK
        New-FastTrackMigrationSecret
        Set-FastTrackMigrationSecret
        Get-FastTrackMigrationSecrets
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $SecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Mig-ExHybrid","Mig-ExSimpleMRS","Mig-ExCutover","Mig-ExStaged","Mig-IMAP","Mig-GmailCutover","Mig-GmailStaged","Mig-GroupWise","Mig-GoogleDrive","Mig-GoogleSites","Mig-Box","Mig-FileSharesToOneDrive","Mig-FileSharesToTeamSites","Mig-Domino-BAM","Mig-Domino-ODME","MIG-SPOnPrem")]
            [string] $MigrationType
        )

    if($global:MsoAdminProperties.Count -eq 0)
    {
        Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
        return
    }

    $jsonObj = SetBaseRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"]  `
                                -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account

    $deleteJson = SetKvRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$SecretName `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType

    $serializedJson = $deleteJson | ConvertTo-Json -Compress: $true

    $header = @{}
    if($global:v2FeatureFlag -eq $true){
    $header.Add("Authorization", $global:MsoAdminProperties["AuthorizationResult"].CreateAuthorizationHeader())}
    else{
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)}
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending KeyVault Delete Request..."

    $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("{0}KeyVault",$global:CsiApiBaseUriFormat)) -Headers $header -Body $serializedJson

    if($JsonResult.StatusCode -ne $null)
    {
        # Error?
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Waiting-TransactionComplete -TransactionID ($JsonResult.TransactionId)
    }

}

function Get-FastTrackMigrationSecrets {
    <#
    .SYNOPSIS
        Get a list of secrets for a FastTrack migration customer
    .DESCRIPTION
        The Get-FastTrackMigrationSecrets cmdlet invokes the REST API to retrieve the customer's secrets from keyvault, as a list. Get-FastTrackMigrationSecrets returns recovered secrets as a json-object that is returned to the caller.
 
        This cmdlet is used by customers to retrieve a list of secret names.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackMigrationAccount cmdlet.
 
        Access Notes: RDG and VPN credentials can only be created/accessed/modified through the Fast Track Migration Portal / AKV tab.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        Type of migration.
        Mig-ExHybrid
            Exchange to Exchange hybrid migration
        Mig-ExSimpleMRS
            Exchange to Exchange hybrid migration
        Mig-ExCutover
            Cutover Migration
        Mig-ExStaged
            Staged Migration
        Mig-IMAP
            IMAP Migration
        Mig-GmailCutover
            Gmail Cutover Migration
        Mig-GmailStaged
            Gmail staged Migration
        Mig-GroupWise
            GroupWise Migration
        Mig-GoogleDrive
            Google drive to OneDrive migration
        Mig-GoogleSites
            GoogleSites Migration
        Mig-Box
            Box drive to OneDrive migration
        Mig-FileSharesToOneDrive
            FileShare to OneDrive migration
        Mig-FileSharesToTeamSites
            FileShare to TeamSite migration
        Mig-Domino-BAM
            Notes user documents into BAM (Binary Tree Application Manager) migration
        Mig-Domino-ODME
            Notes user documents into ODME migration
        MIG-SPOnPrem
            Sharepoint Migration
    .PARAMETER CredentialType
        The type of credential.
        Valid options are:
            Admin,
            Certificate,
            Migration_Account,
            Mig_Sched,
            Sharepoint,
            SAS,
            VPN,
            Encrypted,
            PowerBI,
            All
    .EXAMPLE
        Get-FastTrackMigrationSecrets -Region "India" -MigrationType "Mig-ExCutover" -CredentialType "Admin"
    .INPUTS
        System.String
    .OUTPUTS
        System.Management.Automation.PSObject
            This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
    .LINK
        New-FastTrackMigrationSecret
        Remove-FastTrackMigrationSecret
        Set-FastTrackMigrationSecret
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [ValidateSet("Mig-ExHybrid","Mig-ExSimpleMRS","Mig-ExCutover","Mig-ExStaged","Mig-IMAP","Mig-GmailCutover","Mig-GmailStaged","Mig-GroupWise","Mig-GoogleDrive","Mig-GoogleSites","Mig-Box","Mig-FileSharesToOneDrive","Mig-FileSharesToTeamSites","Mig-Domino-BAM","Mig-Domino-ODME","MIG-SPOnPrem")]
            [string] $MigrationType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("Admin", "Certificate", "Migration_Account", "Mig_Sched", "Sharepoint", "SAS",  "VPN", "Encrypted", "PowerBI", "All")]
            [string] $CredentialType = "All"
        )

    if($global:MsoAdminProperties.Count -eq 0)
    {
        Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackMigrationAccount] function."
        return
    }

    $jsonObj = SetBaseRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"]  `
                                -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account

    $updateJsonObj = SetKvGetRequestValues -RequestObject:$jsonObj `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType `
                                        -CredType $CredentialType

    $serializedJson = $updateJsonObj | ConvertTo-Json -Compress: $true

    $header = @{}
    if($global:v2FeatureFlag -eq $true){
    $header.Add("Authorization", $global:MsoAdminProperties["AuthorizationResult"].CreateAuthorizationHeader())}
    else{
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)}
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Fetching Secrets ..."

    $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("{0}KeyVault/List",$global:CsiApiBaseUriFormat)) -Headers $header -Body $serializedJson


    if($JsonResult.StatusCode -ne $null)
    {
        # Error?
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
      if($JsonResult.Secrets.Count -eq 0)
        {
            Write-Host "No Secrets Found"

        }
        else
        {
            Write-Host "`nSecrets`n-------"
            return $JsonResult.Secrets
        }
    }
}
# SIG # Begin signature block
# MIIkbwYJKoZIhvcNAQcCoIIkYDCCJFwCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDgnp+IHlu8pE3f
# Cve89MEGxRavb80hM6AEeQ5XJARRkKCCDYEwggX/MIID56ADAgECAhMzAAABA14l
# HJkfox64AAAAAAEDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMTgwNzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDRlHY25oarNv5p+UZ8i4hQy5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU5
# 3Rt+M2wR/Dsm85iqXVNrqsPsE7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94S
# nYW/fHaGfXKxdpth5opkTEbOttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjR
# hIjiATwi/K+WCMxdmcDt66VamJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8A
# DwH+S15UD8rEZT8K46NG2/YsAzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0
# NIZ5rCrVXzCRO+QUauuxygQjAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8w
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhu
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJ
# Uw0/DSbsokTYDdGfY5YGSz8eXMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHn
# wya0rPUn00iThoj+EjWRZCLRay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjY
# DBu2KWAndjQkm925l3XLATutghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs
# 1JPyZ6vic8g9o838Mh5gHOmwGzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCy
# RhxdXnYqWJ/U7vL0+khMtWGLsIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuy
# bR/5WcF9ttE5yXnggxxgCto9sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpD
# MYLa2ISuubAfdfX2HX1RETcn6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy
# 2TUxuNty+rR1yIibar+YRcdmstf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v4
# 6Mp79mwV+QMZDxGFqk+av6pX3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOla
# P470I3gwsvKmOMs1jaqYWSRAuDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6Iwh
# SkHC3uuOW+4Dwx1ubuZUNWZncnwa6lL2IsRyP64wggd6MIIFYqADAgECAgphDpDS
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIWRDCCFkACAQEwgZUwfjELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAQNeJRyZH6MeuAAAAAABAzAN
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg7/v/MUvS
# h8EluSnknQp4lEE115WKK9JprqV75rn+FrEwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
# BgkqhkiG9w0BAQEFAASCAQCz7RO741Ut4RsdA5zk9OP1ExhinvOYgFiPt+CyMhIZ
# HNcXRoZ07AEWPyoiENCg0FxU/h1GRAj9TdW/z5t+5PYHoAEIsZvw+0HXQaE0vUcW
# 5T3QVMEMfjKqgzn5xGfGfrPqGFG0cN7CUBhrgRUhF5FkOjw3I/w87TmAf1XH/rzC
# sPhI58WGKApYqf9KLNij1hE+LXX2108KRlQwE1pFI6l3pJ9/cgv4f+lLcpRLou5c
# gMeXnLEg4ZV6aEv1S+fyXZ7qZQlvfWGjaAbtKMQ5zOeBI9jglzSqQLKllqblSbZJ
# JqUMTAB5jtSC+UVu2PswWPkNGqCflN81uV6gRwO8n/TEoYITzjCCE8oGCisGAQQB
# gjcDAwExghO6MIITtgYJKoZIhvcNAQcCoIITpzCCE6MCAQMxDzANBglghkgBZQME
# AgEFADCCAVgGCyqGSIb3DQEJEAEEoIIBRwSCAUMwggE/AgEBBgorBgEEAYRZCgMB
# MDEwDQYJYIZIAWUDBAIBBQAEIISHttpvuXavg9rKvQ4hVJzNFnn5W9znbV3UVG85
# +RxiAgZcSeuZ5l4YEzIwMTkwMjA2MTgzMDU2LjA2NVowBwIBAYACAfSggdSkgdEw
# gc4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsT
# IE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFs
# ZXMgVFNTIEVTTjo5OEZELUM2MUUtRTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgU2VydmljZaCCDx4wggT1MIID3aADAgECAhMzAAAAy194yyMOlJfD
# AAAAAADLMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwMB4XDTE4MDgyMzIwMjYyNFoXDTE5MTEyMzIwMjYyNFowgc4xCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo5
# OEZELUM2MUUtRTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
# dmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMV4yB3v8B1BcBxt
# NEo/VALKGnizA1WCEIU22DCpyy838O0VlW7D3KUomZPIU3nsx3MxaQXpai0OiVs+
# DPuHqdoKtsuYCaMxeDHhodCgPWdPT9NN0hngnC07R2nDB2NhvtRBpr4V36791Pqi
# 3CssKDdLjBrOQUhqEn8S0VP5xldDQPfMIpqRFQdP6Ut4dvaI/Mva5e86HbawJxdG
# KrTdHp7LOae3YHX25khbhuNatqp3dDu3Do6xDE1BIa2GuUGZa4oHVNwWIWk3SZ4x
# ZlarT3eAi712yWyeTrjGv56Ryje8yDiBtd+1UCn67t0TwQpTa+a2ZPP2v8HyQxQe
# gc+9ThUCAwEAAaOCARswggEXMB0GA1UdDgQWBBQo5PLm9snRTa5uyNsqlr8xw/vZ
# djAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEug
# SaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9N
# aWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsG
# AQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Rp
# bVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoG
# CCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQCL9GGFgwVibMsUlJfD6SUDbHKx
# L9pN6ZYMg+aOTE8AyCh9oD6HcuinUjkj6afQU63TvgVRWExYJLzrQBysAh2GgbGk
# KIPtdV6yQQMlJxclXpR48t1jS1VvBX0KksR5Bq/4/0e58+jXvUaU2JcUQVw3lHn9
# I/YtQJeuAvnNfLENxJKE3A7FOjOAw+fEH49OGK1IBR9yhXS+r6HslFuFLfjK7DU8
# 9+Cu1zAg9JTCCrqlWSydWApAYh/ACInONLHHp9OZdilC42zGjB8Ro/07YqMAjPhK
# 7Ze12lWThiZIFqc5fZTxCi3L2T8pQI91/Nxu4CnpIzLXUwSXUxkIpfSNsK7OMIIG
# cTCCBFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1
# WhcNMjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCC
# ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9p
# lGt0VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEw
# WbEwRA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeG
# MoQedGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJ
# UGKxXf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw
# 2k4GkbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0C
# AwEAAaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ
# 80N7fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8E
# BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2U
# kFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5j
# b20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmww
# WgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29m
# dC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYD
# VR0gAQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYI
# KwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0
# AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9
# naOhIW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtR
# gkQS+7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzy
# mXlKkVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCf
# Mkon/VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3D
# nKOiPPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs
# 9/S/fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110
# mCIIYdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL
# 2IK0cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffI
# rE7aKLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxE
# PJdQcdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc
# 1bN+NR4Iuto229Nfj950iEkSoYIDrDCCApQCAQEwgf6hgdSkgdEwgc4xCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29m
# dCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT
# Tjo5OEZELUM2MUUtRTY0MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# U2VydmljZaIlCgEBMAkGBSsOAwIaBQADFQC5o5PSQHbRtx8VowRRl644K9uaIaCB
# 3jCB26SB2DCB1TELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEp
# MCcGA1UECxMgTWljcm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJzAlBgNV
# BAsTHm5DaXBoZXIgTlRTIEVTTjo0REU5LTBDNUUtM0UwOTErMCkGA1UEAxMiTWlj
# cm9zb2Z0IFRpbWUgU291cmNlIE1hc3RlciBDbG9jazANBgkqhkiG9w0BAQUFAAIF
# AOAFkDowIhgPMjAxOTAyMDcwMDU2MjZaGA8yMDE5MDIwODAwNTYyNlowczA5Bgor
# BgEEAYRZCgQBMSswKTAKAgUA4AWQOgIBADAGAgEAAgF1MAcCAQACAhe8MAoCBQDg
# BuG6AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwGgCjAIAgEAAgMW
# 42ChCjAIAgEAAgMHoSAwDQYJKoZIhvcNAQEFBQADggEBAEMtYej5cHoMbdmxcK+z
# kcjDD2sOzH0c5o3KL5Wlo44HfxBByj8W6FJBTkJeJ9Ai6vNq36Xyc4NzaXlX0hFL
# YOKtfW666kcxgUnJnEBcqySsweTIh54RhGLb+ji4cd2ZKBrC6uplVeKccDtX8rF/
# Pt+mWYnvqJgW8gFzVui/kMZIhRimoPAtkV8/Xzl+uStyVF3dH1gmXKoc4fnssPSW
# mfzM4qm5mCo5Qg4/aQKE5W3O3Z78pz2XuM22alxcXrZEQvMDfggGLN915RgsRJ+6
# /+BIPWS7L/qGbfN4RrIED2bVATaCSHtH5vFwVNKV1d5kO8PT3W5fGigNqXFzL6kQ
# Q7cxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAIT
# MwAAAMtfeMsjDpSXwwAAAAAAyzANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcN
# AQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCA3rbpbw4SCzT0M8RMd
# rCw80ElPEN+2SvQnUrfmFxbWmzCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0E
# IDYnIaqpYKde63PQpL1LfC4X9p9L0y7uFEdeqmDdwR1kMIGYMIGApH4wfDELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z
# b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAADLX3jLIw6Ul8MAAAAAAMswIgQg
# 6ttG20L6nm38P1MhJNkcDI9lFb0iOFFQQtAR9EtuqyAwDQYJKoZIhvcNAQELBQAE
# ggEAATcarDFqJ25MYfgaS4RQW4hMmy8uTVsQ+hP+qNy1mTsaBuoFB3sM9/gqLfAA
# oXGxqbKcc52xuCjFH6VB7gmGBBbpw3pFhLw7XMMSNk7BMSnnAbJ0jsS6jYYUOzmD
# 2zPTkSgVBCpEPn8spNnFfcrWHcy+BwJZ9YOuGuDeoEmv65nEN4OTjD1r0i247SnS
# z0Q8vzGGam8GZGZH9/mbwsq2eGlopuZTaYzHbFhLmfPyrUsjgIyFdAkNhHvcu0zP
# vOe7WHzrna32JjZGDVl0AFot5ZfIYk9K96eprIqBiNQI3vDBdxW0yWcdH7MfWtqm
# bj33kWV0xH+HZIw0Xb+rCiFwtA==
# SIG # End signature block