FastTrack-KeyVaultRequests.psm1

Add-Type -AssemblyName System.Web -ErrorAction SilentlyContinue
Function Get-ResponseError {
    param([System.Net.HttpWebResponse]$Response)
    $streamReader = New-Object System.IO.StreamReader($Response.GetResponseStream())
    $streamReader.BaseStream.Position = 0
    $streamReader.DiscardBufferedData()
    $body = ConvertFrom-Json($streamReader.ReadToEnd())
    Add-Member -InputObject $body -MemberType NoteProperty -Name "StatusCode" -Value $_.Exception.Response.StatusCode
    $body
}
Function Invoke-GetRequest {
    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 {
    param([String]$Uri, [hashtable]$Headers, [String]$Body)
    $response = try {
    Invoke-RestMethod -Method POST -Uri $Uri -ContentType 'application/json' -Headers $Headers -Body $Body
    } catch {
    Get-ResponseError $_.Exception.Response
    }

    return $response
}
Function Invoke-PutRequest {
    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 {
    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 SetBaseRequestValues{
    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{
    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:MsoSovereignCloud |
                Add-Member -PassThru NoteProperty MigrationType $MigrationType)
}

function New-KeyVaultSecret {
    <#
    .SYNOPSIS
        Create a new KeyVault secret
    .DESCRIPTION
        This cmdlet is used for customers who are Global Administrators to create new KeyVault secret.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
    .PARAMETER KeyVaultSecretName
        Unique name for new KeyVault.
    .PARAMETER KeyVaultSecretValue
        Value for new KeyVault.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .PARAMETER EnvironmentMode
        DO NOT USE. INTERNAL USE ONLY
    .EXAMPLE
        New-KeyVaultSecret -KeyVaultSecretName:"NewKeyVaultSecret" -KeyVaultSecretValue:"NewKeyVaultSecretValue" -Region:"Region" -MigrationType:"Mig-ExHybrid"
        This will create a new KeyVaultSecret named as NewKeyVaultSecret and value as NewKeyVaultSecretValue.
    .INPUTS
        System.String
    .OUTPUTS
        System.Management.Automation.PSObject
            This cmdlet generates System.Management.Automation.PSObject object that represents transaction ID.
    .LINK
        Set-KeyVaultSecret
        Remove-KeyVaultSecret
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $KeyVaultSecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $KeyVaultSecretValue,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("dev","uat","prod")]
            [string] $EnvironmentMode = "prod"
        )

    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-AdminUser"].EmailAddress

    $updateJsonObj = SetKvRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$KeyVaultSecretName `
                                        -KeyVaultSecretValue:$KeyVaultSecretValue `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType `

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

    $header = @{}
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending KeyVault Create Request..."

    if($EnvironmentMode.Equals("UAT", [System.StringComparison]::CurrentCultureIgnoreCase))
    {
        $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/KeyVault/Set",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }
    else
    {
        $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/KeyVault/Set",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }

    if($JsonResult.StatusCode -ne $null)
    {
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Write-Host "Request Generated Transaction ID $($JsonResult.TransactionId)"
    }
    
    return $JsonResult

}
function Set-KeyVaultSecret {
    <#
    .SYNOPSIS
        Update an existing KeyVault secret
    .DESCRIPTION
        This cmdlet is used for customers who are Global Administrators to update already existing KeyVault secret.
         
        In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
    .PARAMETER KeyVaultSecretName
        Unique name for already existing KeyVault secret.
    .PARAMETER KeyVaultSecretValue
        New value for specified KeyVault secret.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .PARAMETER EnvironmentMode
        DO NOT USE. INTERNAL USE ONLY
    .EXAMPLE
        Set-KeyVaultSecret -KeyVaultSecretName:"SecretValueName" -KeyVaultSecretValue:"ChangedSecretValue" -Region:"Region" -MigrationType:"Mig-ExHybrid"
        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-KeyVaultSecret
        Remove-KeyVaultSecret
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $KeyVaultSecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $KeyVaultSecretValue,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("dev","uat","prod")]
            [string] $EnvironmentMode = "prod"
        )

    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-AdminUser"].EmailAddress

    $updateJsonObj = SetKvRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$KeyVaultSecretName `
                                        -KeyVaultSecretValue:$KeyVaultSecretValue `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType

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

    $header = @{}
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending KeyVault Update Request..."
    if($EnvironmentMode.Equals("UAT", [System.StringComparison]::CurrentCultureIgnoreCase))
    {
        $JsonResult = Invoke-PutRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/KeyVault",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }
    else
    {
        $JsonResult = Invoke-PutRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/KeyVault",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }
            
    if($JsonResult.StatusCode -ne $null)
    {
        # Error?
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Write-Host "Request Generated Transaction ID $($JsonResult.TransactionId)"
    }
    
    return $JsonResult
}
function Remove-KeyVaultSecret {
    <#
    .SYNOPSIS
        Remove an existing KeyVault secret
    .DESCRIPTION
        This cmdlet is used for customers who are Global Administrators to remove already existing KeyVault secret.
 
        In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
    .PARAMETER KeyVaultSecretName
        Unique name for already existing KeyVault secret.
    .PARAMETER Region
        Region of migration.
    .PARAMETER MigrationType
        The type of migration.
    .PARAMETER EnvironmentMode
        DO NOT USE. INTERNAL USE ONLY
    .EXAMPLE
        Remove-KeyVaultSecret -KeyVaultSecretName:"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-KeyVaultSecret
        Set-KeyVaultSecret
    #>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $KeyVaultSecretName,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationType,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("dev","uat","prod")]
            [string] $EnvironmentMode = "prod"
        )

    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-AdminUser"].EmailAddress

    $deleteJson = SetKvRequestValues -RequestObject:$jsonObj `
                                        -KeyVaultSecretName:$KeyVaultSecretName `
                                        -Region:$Region `
                                        -MigrationType:$MigrationType
                            
    $serializedJson = $deleteJson | ConvertTo-Json -Compress: $true
    write-host $serializedJson

    $header = @{}
    $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
    $header.Add("TENANT_ID",$global:MsoAdminProperties["MSO-CompanyTenantInfo"])
    Write-Host "Sending KeyVault Delete Request..."
    if($EnvironmentMode.Equals("UAT", [System.StringComparison]::CurrentCultureIgnoreCase))
    {
        $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/KeyVault",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }
    else
    {
        $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/KeyVault",$EnvironmentMode)) -Headers $header -Body $serializedJson
    }
            
    if($JsonResult.StatusCode -ne $null)
    {
        # Error?
        Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
    }
    else
    {
        Write-Host "Request Generated Transaction ID $($JsonResult.TransactionId)"
    }
    
    return $JsonResult
}