Microsoft.FastTrack.psm1

Import-Module FastTrack-GDPR-RequestDsr -Scope:Local -WarningAction:SilentlyContinue
Import-Module FastTrack-TransactionQuery -Scope:Local -WarningAction:SilentlyContinue
Import-Module FastTrack-ConfigurationManagement -Scope:Local -WarningAction:SilentlyContinue
Import-Module FastTrack-ScheduleManagement -Scope:Local -WarningAction:SilentlyContinue
Import-Module FastTrack-KeyVaultRequests -Scope:Local -WarningAction:SilentlyContinue

[array] $importedModules = "FastTrack-GDPR-RequestDsr","FastTrack-TransactionQuery","FastTrack-ConfigurationManagement","FastTrack-ScheduleManagement","FastTrack-KeyVaultRequests"

$global:MsftApiKey = ""
$global:MsftAccessToken = ""
$global:MsoAdminProperties = @{}
$global:MsoSovereignCloud = "AzureCloud"
$global:MsoComOrGov = "Commercial"

Function SetAccessTokenHash
{
    param
    (
        [string] $ApiKey,
        [string] $TenantID
    )
    $StringBuilder = [System.Text.StringBuilder]::new()
    [System.Security.Cryptography.HashAlgorithm]::Create("SHA512").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($TenantId + $ApiKey)) | %{
        [Void] $StringBuilder.Append($_.ToString("x2"))
    }
    
    return $StringBuilder.ToString().ToUpper()
}

Function SetAzureEnvironmentProperties
{
    param
    (
        [string] $AzureEnvironment
    )

        switch ( $AzureEnvironment )
        {
            "AzureCloud" { $global:MsoSovereignCloud = 'AzureCloud' }
            "AzureChinaCloud" { $global:MsoSovereignCloud = 'AzureChinaCloud'    }
            "AzureGermanCloud" { $global:MsoSovereignCloud = 'AzureGermanyCloud'   }
            "AzureUSGovernmentCloud" { $global:MsoSovereignCloud = 'USGovernment' }
        }

        if($AzureEnvironment.Equals('AzureCloud', [System.StringComparison]::CurrentCultureIgnoreCase))
        {
            $global:MsoComOrGov = "Commercial"
        }
        else
        {
            $global:MsoComOrGov = "Government"
        }
}


Function Login-FastTrackAccount
{
<#
.SYNOPSIS
    Connect to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests.
.DESCRIPTION
    The Login-FasttrackAccount cmdlet connects to Azure with an authenticated account for use with FastTrack Customer Service cmdlet requests.
 
    In order to login, you must be a global admin on your organizations account.
 
    The API key is used to identify your organization as a FastTrack customer and can be obtained from you MVM.
     
    The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment.
.PARAMETER ApiKey
    Key to validate organization is a FastTrack customer.
.PARAMETER Environment
    Specifies the organizations Azure Cloud environment. "AzureCloud" is the default.
    Valid options: AzureCloud | AzureChinaCloud | AzureGermanCloud | AzureUSGovernmentCloud
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject.
.EXAMPLE
    Login-FastTrackAccount -ApiKey "APIKey"
.LINK
    Set-FastTrackEnvironment
#>

    param
    (
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [string] $ApiKey,   
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [string] $Environment = "AzureCloud"
    )

    [array]$environments = "AzureCloud","AzureChinaCloud","AzureGermanCloud","AzureUSGovernmentCloud"
    
    if($global:MsoAdminProperties.Count -gt 0)
    {
        Write-Warning "Unable to authenticate for Office 365 credentials!"
        Write-Warning "You must first remove the current PowerShell session before attempting another login..."
        return
    }

    if ($Environment -ne $null)
    {
        if ($environments.Contains($Environment))
        {
            SetAzureEnvironmentProperties -AzureEnvironment $Environment
        }
        else
        {
            Write-Warning "Invalid [Environment] provided."
            Write-Warning "Please use one of the following options [AzureCloud | AzureChinaCloud | AzureGermanCloud | AzureUSGovernmentCloud]"
            return
        }
    }

    InitiateMsoConnect

    if($global:MsoAdminProperties.Count -eq 0)
    {
        Write-Warning "Unable to retrieve Office 365 credentials!"
        Write-Warning "If you are attempting to login to an alternate Azure cloud environment, you must first call function [Set-FastTrackEnvironment]"
    }
    else
    {
        $global:MsftApiKey = $ApiKey
        $global:MsftAccessToken = (SetAccessTokenHash -ApiKey: $ApiKey -TenantID: $global:MsoAdminProperties["MSO-CompanyTenantInfo"])
        Write-Host -ForegroundColor:Green "You have successfully logged into Office 365 as Tenant: $($global:MsoAdminProperties["MSO-CompanyInfo"].DisplayName)"
        Write-Host -ForegroundColor:Green "Run the following command to see a list of available functions."
        Write-Host -ForegroundColor:Green " Get-Command *FastTrack*"
    }
}


Function Set-FastTrackEnvironment{
<#
.SYNOPSIS
    Set the Azure cloud corresponding to your subscription
.DESCRIPTION
    The Set-FastTrackEnvironment cmdlet sets the properties for the cloud environment in which to connect.
     
    The default environment is AzureCloud. If your organization is within another Azure environment, use the -Environment switch and select the appropriate environment.
.PARAMETER AzureEnvironment
    Specifies the organizations Azure Cloud environment. "AzureCloud" is the default.
    Valid options: AzureCloud | AzureChinaCloud | AzureGermanCloud | AzureUSGovernmentCloud
.INPUTS
    System.String
.OUTPUTS
    System.Management.Automation.PSObject
        This cmdlet generates a System.Management.Automation.PSObject object that represents the Transaction ID.
.EXAMPLE
    Set-FastTrackEnvironment
.LINK
    Login-FastTrackAccount
#>

    param(    
            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
            [ValidateSet("AzureCloud","AzureChinaCloud","AzureGermanCloud","AzureUSGovernmentCloud")]
            [string] $AzureEnvironment = "AzureCloud"
        )

    SetAzureEnvironmentProperties -AzureEnvironment $AzureEnvironment
}

function InitiateMsoConnect{
    param
    (
        [Parameter(Mandatory=$false,ValueFromPipeline=$true)]
        [pscredential] $Credential
    )

    $CatchError = ""
    Import-Module MSOnline
    try
    {
        Connect-MsolService -AzureEnvironment:$MsoSovereignCloud -ErrorAction:Stop -ErrorVariable:"CatchError"

        $tenantInfo = (Invoke-WebRequest "https://login.windows.net/$(((Get-MsolDomain)[0]).Name)/.well-known/openid-configuration"|ConvertFrom-Json).token_endpoint.Replace("https://","").Split('/')[1]
        $companyInfo = Get-MsolCompanyInformation
        $role = Get-MsolRole -RoleName "Company Administrator"
        $companyAdmins = Get-MsolRoleMember -RoleObjectId $role.ObjectId
        $adminUser = $companyAdmins | where {$_.EmailAddress -ne $null -and $_.EmailAddress.EndsWith((Get-MsolDomain).Name, [StringComparison]::CurrentCultureIgnoreCase)} | Select-Object -First:1

        $global:MsoAdminProperties.Add("MSO-CompanyInfo",$companyInfo)
        $global:MsoAdminProperties.Add("MSO-CompanyAdmins",$companyAdmins)
        $global:MsoAdminProperties.Add("MSO-CompanyTenantInfo",$tenantInfo.ToUpper())
        $global:MsoAdminProperties.Add("MSO-AdminUser",$adminUser)
    }
    catch
    {
        #Swallow exception - let parent method handle...
    }
}