FastTrack-ScheduleManagement.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 SetIdentityRecipientValues {

    [string] $TenantID =  $global:MsoAdminProperties['MSO-CompanyTenantInfo'] 
    [string] $CompanyName = $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName 
    [string] $LogonUserEmail = $global:MsoAdminProperties["MSO-LoggedOnUser"].Account

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

    return $Identity
}

Function SetCreateRequestValues{
    param
    (
        [string] $TenantID,
        [string] $CompanyName,
        [string] $LogonUserEmail,
        [string] $MigrationType,
        [string] $Source,
        [string] $Target,
        [string] $MigrationDate,
        [string] $MigrationWindow,
        [string] $MigrationGroup,
        [string] $Size,
        [string] $PropertyBag,
        [string] $IsCutover,
        [string] $Region

    )

        $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 Customer $CustomerIdentity |
        Add-Member -PassThru NoteProperty MigrationType $MigrationType |
        Add-Member -PassThru NoteProperty Source $Source |
        Add-Member -PassThru NoteProperty Target $Target |
        Add-Member -PassThru NoteProperty MigrationDate $MigrationDate |
        Add-Member -PassThru NoteProperty MigrationWindow $MigrationWindow |
        Add-Member -PassThru NoteProperty MigrationGroup $MigrationGroup |
        Add-Member -PassThru NoteProperty Size $Size |
        Add-Member -PassThru NoteProperty IsCutover $IsCutover |
        Add-Member -PassThru NoteProperty Region $Region |
        Add-Member -PassThru NoteProperty PropertyBag $PropertyBag |
        Add-Member -PassThru NoteProperty TransactionId "00000000-0000-0000-0000-000000000000" |
        Add-Member -PassThru NoteProperty ScheduleIdentifier "00000000-0000-0000-0000-000000000000") 

        return $CustomerObject
}

Function SetUpdateRequestValues{
    param
    (
        [string] $TenantID,
        [string] $CompanyName,
        [string] $LogonUserEmail,
        [string] $MigrationType,
        [string] $Source,
        [string] $Target,
        [string] $MigrationDate,
        [string] $MigrationWindow,
        [string] $MigrationGroup,
        [string] $Size,
        [string] $PropertyBag,
        [string] $IsCutover,
        [string] $Region
    )

        $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 Customer $CustomerIdentity |
        Add-Member -PassThru NoteProperty TransactionId "00000000-0000-0000-0000-000000000000" |
        Add-Member -PassThru NoteProperty MigrationType $MigrationType |
        Add-Member -PassThru NoteProperty Source $Source |
        Add-Member -PassThru NoteProperty Target $Target |
        Add-Member -PassThru NoteProperty MigrationDate $MigrationDate |
        Add-Member -PassThru NoteProperty MigrationWindow $MigrationWindow |
        Add-Member -PassThru NoteProperty MigrationGroup $MigrationGroup |
        Add-Member -PassThru NoteProperty Size $Size |
        Add-Member -PassThru NoteProperty IsCutover $IsCutover |
        Add-Member -PassThru NoteProperty Region $Region |
        Add-Member -PassThru NoteProperty PropertyBag $PropertyBag)

        return $CustomerObject
}

Function Get-CsvAsJson {
    param
    ( 
        [string] $FilePath
    )
    [string] $targetBaseUrl = ""

    $readData = Get-Content $FilePath | ForEach-Object {
        #csv is FileShareManager
        [string] $line = $_.ToString().ToLower()
        $lineNumber++
        if($targetBaseUrl -eq "")
        {                    
            [int] $index = $line.IndexOf("https://")
            if($index -gt 0) 
            {
                $indexOfComma = $line.IndexOf(',', $index)
                if($indexOfComma -le 0){
                    $indexOfComma = line.Length;
                }
                $targetBaseUrl = $line.Substring($index, $indexOfComma - $index).TrimEnd('/');
                $targetBaseUrl += "/";        
            }
        }
        else
        {
            if($line -match '^([,"]+|[\s]*$)')        
            {
                if(!$endLine)
                {
                    $endLine = $lineNumber
                }
            }
        }
    }

    if($targetBaseUrl -ne "") #If csv is FileShareManager
    {
        $FileContent =  Get-Content $FilePath | select -Skip 1 -First ($endLine-2) | Out-String | ConvertFrom-Csv
        foreach ($obj in $FileContent)
        {
            $obj."Target SharePoint Site" = $targetBaseUrl + $obj."Target SharePoint Site"
        }
    }
    else
    {
        $FileContent = Get-Content $FilePath | Out-String | ConvertFrom-Csv
    }

    if($FileContent -isnot [Array])    {
        #csv contails single row
        $FileContentStr = $FileContent | ConvertTo-Json -Compress: $true 
        $FileContentStr = "[" + $FileContentStr + "]"
    }
    else {
        $FileContentStr = $FileContent | ConvertTo-Json -Compress: $true
    }

    return $FileContentStr
}

Function Get-FastTrackSchedule {
<#
.SYNOPSIS
    Get FastTrack schedule list.
.DESCRIPTION
    This cmdlet is intended for customers who are Global Administrators to get FastTrack schedule list.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
 
.PARAMETER ScheduleId
    Unique Guid for FastTrack schedule.
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    Get-FastTrackSchedule -ScheduleId "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the list of FastTrack schedule details.
.LINK
    New-FastTrackSchedule
    Set-FastTrackSchedule
    Remove-FastTrackSchedule
    New-FastTrackScheduleFromCsv
    Get-FastTrackDeleteTypes
#>

    param
    (
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $ScheduleId,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [ValidateSet("dev","uat","prod")]
        [string] $EnvironmentMode = "prod"
    )
    try
    {
        if($global:MsoAdminProperties.Count -eq 0)
        {
            Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
            return
        }            
    
        if($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
        {            
            [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]

            $header = @{}
            $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
            $header.Add("TENANT_ID",$TenantId)
            Write-Host "Sending Schedule Get Request..."
            [string] $requestUri

            if($EnvironmentMode -eq "uat")
            {
                $requestUri = "https://msft-csi-{0}.azurewebsites.net/api/{1}"                
            }
            else
            {
                $requestUri = "https://msft-cssp-{0}.azurewebsites.net/api/{1}"
            }

            if ($ScheduleId -eq $null)
            {
                $requestUri = [System.String]::Format($requestUri + "/Schedule", $EnvironmentMode, $TenantId) 
            }
            else
            {
                $requestUri = [System.String]::Format($requestUri + "/Schedule/{2}", $EnvironmentMode, $TenantId, $ScheduleId)
            }

            $JsonResult = Invoke-GetRequest -Uri ([System.String]::Format($requestUri, $EnvironmentMode, $TenantId, $ScheduleId)) -Headers $header

            if($JsonResult.StatusCode -ne $null)
            {
                # Error?
                Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
            }
            else
            {
                Write-Host "Get request completed"
            }
    
            return $JsonResult
        }        
        else 
        {
            Write-Warning "SORRY! - The Logon User is not marked as a Global Administrator... We cannot continue!"
        }
    }
    catch
    {
        
        Write-Warning -Message:"An error occurred attempting to authenticate with this module"
        Write-Warning -Message: $_.Exception.Message
        Write-Host "Press the [enter] key to close this process"
        Read-Host
    }
}
Function New-FastTrackSchedule {
<#
.SYNOPSIS
    Creates a new FastTrack schedule.
.DESCRIPTION
    This cmdlet is intended for customers who are Global Administrators to create a new FastTrack schedule.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
.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-DominoBAM
        Notes user documents into BAM (Binary Tree Application Manager) migration
    Mig-DominoODME
        Notes user documents into ODME migration
    MIG-SPOnPrem
        Sharepoint Migration
.PARAMETER Source
    Source for different migration types.
.PARAMETER Target
    Target for different migration types.
.PARAMETER MigrationDate
    Date of migration.
.PARAMETER MigrationWindow
    Migration event window.
.PARAMETER MigrationGroup
    Migration group.
.PARAMETER Size
    Size of source storage.
.PARAMETER IsCutover
    Is cutover true | false | null.
.PARAMETER Region
    Name of region.
.PARAMETER PropertyBag
    Properties for different migration types.
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    New-FastTrackSchedule -MigrationType "Mig-Box" -Source "joe@contoso.com" -Target "Jane@contoso.net" -MigrationDate "YYYY-DD-MMTHH:MIN:SS" -MigrationWindow "Window1" -MigrationGroup "Group1" -Size 2 -PropertyBag "FilesOwned"
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID .
.LINK
    Get-FastTrackSchedule
    Remove-FastTrackSchedule
    Set-FastTrackSchedule
    New-FastTrackScheduleFromCsv
    Get-FastTrackDeleteTypes
#>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationType,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Source,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Target,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationDate,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationWindow,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationGroup,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Size,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("false","true","null")]
            [string] $IsCutover = "null",
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $PropertyBag,
            [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
        }

        if($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
        {            
            [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]
            
            if($IsCutover -eq "null")
            {
                $IsCutoverOb = $null
            }
            elseif($IsCutover -eq "true")
            {
                $IsCutoverOb = "true"
            }
            elseif($IsCutover -eq "false")
            {
                $IsCutoverOb = "false"
            }

            $jsonObj = SetCreateRequestValues -TenantID: $TenantId `
                                              -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                              -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account `
                                              -MigrationType: $MigrationType `
                                              -Source: $Source `
                                              -Target: $Target `
                                              -MigrationDate: $MigrationDate `
                                              -MigrationWindow: $MigrationWindow `
                                              -MigrationGroup: $MigrationGroup `
                                              -Size: $Size `
                                              -IsCutover $IsCutoverOb `
                                              -Region $Region `
                                              -PropertyBag: $PropertyBag 

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

            $header = @{}
            $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
            $header.Add("TENANT_ID",$TenantId)
            Write-Host "Sending Schedule Create Request..."

            #$JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/Create",$EnvironmentMode)) -Headers $header -Body $serializedJson
    
            if($EnvironmentMode -eq "uat")
            {
                $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/Schedule/Create",$EnvironmentMode)) -Headers $header -Body $serializedJson
            }
            else
            {
                $JsonResult = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/Create",$EnvironmentMode)) -Headers $header -Body $serializedJson
            }

            Write-Host $JsonResult

            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
        }
        catch
        {
            Write-Warning "SORRY! - The Logon User is not marked as a Global Administrator... We cannot continue!"
        }

}
Function Set-FastTrackSchedule {
<#
.SYNOPSIS
    Updates an existing FastTrack schedule.
.DESCRIPTION
    This cmdlet is intended for customers who are Global Administrators to update an existing FastTrack schedule.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
.PARAMETER ScheduleId
    Unique GUID For FastTrack Schedule.
.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-DominoBAM
        Notes user documents into BAM (Binary Tree Application Manager) migration
    Mig-DominoODME
        Notes user documents into ODME migration
    MIG-SPOnPrem
        Sharepoint Migration
.PARAMETER Source
    Source for different migration types.
.PARAMETER Target
    Target for different migration types.
.PARAMETER MigrationDate
    Date of migration.
.PARAMETER MigrationWindow
    Migration event window.
.PARAMETER MigrationGroup
    Migration group.
.PARAMETER Size
    Size of source storage
.PARAMETER IsCutover
    Is cutover true | false | null.
.PARAMETER Region
    Name of region.
.PARAMETER PropertyBag
    Properties for different migration types.
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    New-FastTrackSchedule -ScheduleId "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -MigrationType "Mig-Box" -Source "joe@contoso.com" -Target "Jane@contoso.net" -MigrationDate "YYYY-DD-MMTHH:MIN:SS" -MigrationWindow "Window1" -MigrationGroup "Group1" -Size 2 -PropertyBag "FilesOwned"
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID .
.LINK
    Get-FastTrackSchedule
    Remove-FastTrackSchedule
    New-FastTrackSchedule
    New-FastTrackScheduleFromCsv
    Get-FastTrackDeleteTypes
#>

    param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $ScheduleId,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationType,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Source,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Target,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationDate,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationWindow,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $MigrationGroup,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Size,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("false","true","null")]
            [string] $IsCutover = "null",
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $Region,
            [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
            [string] $PropertyBag,
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("dev","uat","prod")]
            [string] $EnvironmentMode = "prod"
        )
    try
    {
        if($global:MsoAdminProperties.Count -eq 0)
        {
            Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
            return
        }

        [string]$tenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]

        if($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
        {            
            [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]

            if($IsCutover -eq "null")
            {
                $IsCutoverOb = $null
            }
            elseif($IsCutover -eq "true")
            {
                $IsCutoverOb = "true"
            }
            elseif($IsCutover -eq "false")
            {
                $IsCutoverOb = "false"
            }

            $jsonObj = SetUpdateRequestValues -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"] `
                                    -CompanyName: $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName `
                                    -LogonUserEmail: $global:MsoAdminProperties["MSO-LoggedOnUser"].Account `
                                    -MigrationType: $MigrationType `
                                    -Source: $Source `
                                    -Target: $Target `
                                    -MigrationDate: $MigrationDate `
                                    -MigrationWindow: $MigrationWindow `
                                    -MigrationGroup: $MigrationGroup `
                                    -Size: $Size `
                                    -IsCutover $IsCutoverOb `
                                    -Region $Region `
                                    -PropertyBag: $PropertyBag 

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

            $header = @{}
            $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
            $header.Add("TENANT_ID",$TenantId)
            Write-Host "Sending Schedule Update Request..."

            #$JsonResult = Invoke-PutRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode,$ScheduleId)) -Headers $header -Body $serializedJson
            if($EnvironmentMode -eq "uat")
            {
                $JsonResult = Invoke-PutRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode, $ScheduleId)) -Headers $header -Body $serializedJson
            }
            else
            {
                $JsonResult = Invoke-PutRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode, $ScheduleId)) -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
        }
        else
        {
            
            Write-Warning "SORRY! - The Logon User is not marked as a Global Administrator... We cannot continue!"
        }
    }
    catch
    {        
        Write-Warning -Message:"An error occurred attempting to authenticate with this module"
        Write-Warning -Message: $_.Exception.Message
        Write-Host "Press the [enter] key to close this process"
        Read-Host
    }
}
Function Remove-FastTrackSchedule {
<#
.SYNOPSIS
    Remove an existing FastTrack schedule.
.DESCRIPTION
    This cmdlet is used to remove an existing FastTrack schedule.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
.PARAMETER ScheduleId
    Unique Guid for FastTrack schedule.
.PARAMETER DeleteType
    Delete type to remove specified FastTrack schedule. This can be either ForceDelete or VerifyDelete.
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    Remove-FastTrackSchedule -ScheduleId "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -DeleteType: "ForceDelete"
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID .
.LINK
    Get-FastTrackSchedule
    Set-FastTrackSchedule
    New-FastTrackSchedule
    New-FastTrackScheduleFromCsv
    Get-FastTrackDeleteTypes
#>

    param(
                     [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
                     [string] $ScheduleId,
                     [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
                     [string] $DeleteType,
                     [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
                     [ValidateSet("dev","uat","prod")]
                     [string] $EnvironmentMode = "prod"
              )      
    try
    {
        if($global:MsoAdminProperties.Count -eq 0)
        {
            Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
            return
        }
    
        if ($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
        {
            
            [string] $ApiKey = $global:MsftApiKey

            [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]

            $Identity = SetIdentityRecipientValues

            $CustomerObject = (New-Object PSObject |
                                Add-Member -PassThru NoteProperty Customer $Identity |
                                Add-Member -PassThru NoteProperty DeleteType $DeleteType)
       
            $serializedJson = $CustomerObject | ConvertTo-Json -Compress: $true
            write-host $serializedJson

            $header = @{}
            $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
            $header.Add("TENANT_ID",$TenantId)
            Write-Host "Sending Schedule Delete Request..."

            #$JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode, $ScheduleId)) -Headers $header
            if($EnvironmentMode -eq "uat")
            {
                $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode, $ScheduleId)) -Headers $header -Body $serializedJson
            }
            else
            {
                $JsonResult = Invoke-DeleteRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/{1}",$EnvironmentMode, $ScheduleId)) -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  
        }
        else
        {
            Write-Warning "SORRY! - The Logon User is not marked as a Global Administrator... We cannot continue!"
        }
    }
    catch
    {
        Write-Warning -Message:"An error occurred attempting to authenticate with this module"
        Write-Warning -Message: $_.Exception.Message
        Write-Host "Press the [enter] key to close this process"
        Read-Host
    }
}
Function New-FastTrackScheduleFromCsv {
<#
.SYNOPSIS
    Creates a new FastTrack schedule from CSV
.DESCRIPTION
    This cmdlet is used to Create a new FastTrack schedule from the input CSV.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
.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-DominoBAM
        Notes user documents into BAM (Binary Tree Application Manager) migration
    Mig-DominoODME
        Notes user documents into ODME migration
    MIG-SPOnPrem
        Sharepoint Migration
.PARAMETER IsCutover
    Is cutover true | false | null.
.PARAMETER Region
    Name of region.
.PARAMETER FilePath
    Specifies the path to the Schedule CSV file .
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    New-FastTrackScheduleFromCsv -ScheduleType "Mig-Box" -FilePath "C:\filename.csv"
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID .
.LINK
    New-FastTrackSchedule
    Get-FastTrackSchedule
    Set-FastTrackSchedule
    Remove-FastTrackSchedule
    Get-FastTrackDeleteTypes
#>

    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $ScheduleType,
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $Region,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [ValidateSet("true","false","null")]
        [string] $IsCutover = "null",
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $FilePath,
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [ValidateSet("dev","uat","prod")]
        [string] $EnvironmentMode = "prod"
        )
    try
    {
        if($global:MsoAdminProperties.Count -eq 0)
        {
            Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
            return
        }

        if($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
        {
            [string] $extention = [IO.Path]::GetExtension($FilePath)
            if($extention.ToUpper() -ne ".CSV")
            {
                Write-Error "Please select CSV file."
                return
            }

            if($IsCutover -eq "null")
            {
                $IsCutoverOb = $null
            }
            elseif($IsCutover -eq "true")
            {
                $IsCutoverOb = "true"
            }
            elseif($IsCutover -eq "false")
            {
                $IsCutoverOb = "false"
            }

            $FileContentStr = Get-CsvAsJson -FilePath $FilePath

            if($FileContentStr -ne "[]")
            {
                [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]
                [string] $CompanyName = $global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName
                [string] $global:MsoAdminProperties["MSO-LoggedOnUser"].Account
                [string] $ApiKey = $global:MsftApiKey

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

                $FormattedJson = New-Object psobject |
                    Add-Member -PassThru NoteProperty Customer $CustomerIdentity |
                    Add-Member -PassThru NoteProperty ScheduleType $ScheduleType |
                    Add-Member -PassThru NoteProperty Schedules $FileContentStr |
                    Add-Member -PassThru NoteProperty Region $Region |
                    Add-Member -PassThru NoteProperty IsCutover $IsCutoverOb

                $Output = $FormattedJson | ConvertTo-Json -Compress: $true
                Write-Host $Output

                $header = @{}
                $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
                $header.Add("TENANT_ID", $TenantId)
                Write-Host "Sending New Schedule From CSV Request..."

                if($EnvironmentMode -eq "uat")
                {
                    $result = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-csi-{0}.azurewebsites.net/api/Schedule/Create/Batch", $EnvironmentMode)) -Headers $header -Body $Output
                }
                else
                {
                    $result = Invoke-PostRequest -Uri ([System.String]::Format("https://msft-cssp-{0}.azurewebsites.net/api/Schedule/Create/Batch", $EnvironmentMode)) -Headers $header -Body $Output
                }

                Write-Host $result

                return $result 
            }
        }
        else
        {
            Write-Warning "SORRY! - The Logon User is not marked as a Global Administrator... We cannot continue!"
        }
    }
    catch
    {
        Write-Warning -Message:"An error occurred attempting to authenticate with this module"
        Write-Warning -Message: $_.Exception.Message
        Write-Host "Press the [enter] key to close this process"
        Read-Host
    }
}
Function Get-FastTrackDeleteTypes {
<#
.SYNOPSIS
    Get FastTrack delete types.
.DESCRIPTION
    This cmdlet is used to get all the delete types to delete FastTrack schedules.
 
    In order to use this cmdlet, you must first login using the Login-FastTrackAcount cmdlet.
.PARAMETER EnvironmentMode
    DO NOT USE. INTERNAL USE ONLY
.EXAMPLE
    Get-FastTrackDeleteTypes
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the list of possible delete types for FastTrack schedule delete.
.LINK
    New-FastTrackSchedule
    Set-FastTrackSchedule
    Remove-FastTrackSchedule
    New-FastTrackScheduleFromCsv
    Get-FastTrackSchedule
#>

    param
    (
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [ValidateSet("dev","uat","prod")]
        [string] $EnvironmentMode = "prod"
    )
        try
        {
            if($global:MsoAdminProperties.Count -eq 0)
            {
                Write-Warning "Unable to retrieve Office 365 credentials! :: Please call [Login-FastTrackAccount] function."
                return
            }            
    
            if($global:MsoAdminProperties["MSO-AdminUser"] -ne $null)
            {            
                [string] $ApiKey = $global:MsftApiKey
                [string] $TenantId = $global:MsoAdminProperties["MSO-CompanyTenantInfo"]

                $header = @{}
                $header.Add("ACCESS_TOKEN",$global:MsftAccessToken)
                $header.Add("TENANT_ID",$TenantId)
                Write-Host "Sending Schedule Get Request..."

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

                if($JsonResult.StatusCode -ne $null)
                {
                    Write-Warning "Request failed! : $($JsonResult.StatusCode) - Error Message: $($JsonResult)"
                }
                else
                {
                    Write-Host "Get request completed"
                }
    
                return $JsonResult
            }
        }
        catch
        {
            Write-Warning -Message:"An error occurred attempting to authenticate with this module"
            Write-Warning -Message: $_.Exception.Message
            Write-Host "Press the [enter] key to close this process"
            Read-Host
        }
}