Functions/Connect-PartnerCenterAdminAccount.ps1

<#
.SYNOPSIS
    This function connects to Partner Center using credentials or a MSPComplete Endpoint.
.DESCRIPTION
    This function connects to Partner Center using credentials or a MSPComplete Endpoint.
    It returns whether the connection and logon was successful.
    It currently supports either app + user authentication, or app-only authentication.
    App + user authentication will be disabled by Microsoft as of 4 February 2019.
    After that, only app-only authentication will be allowed.
    TODO: RUN-1225 - KB for step-by-step to retrieve web app application ID, application secret, and tenant ID
#>

function Connect-PartnerCenterAdminAccount {
    [CmdletBinding(PositionalBinding=$false)]
    [OutputType([Bool])]
    param (
        # The username of the Partner Center admin account.
        [Parameter(Mandatory=$true, ParameterSetName="credential")]
        [ValidateNotNullOrEmpty()]
        [String]$username,

        # The password of the Partner Center admin account.
        [Parameter(Mandatory=$true, ParameterSetName="credential")]
        [ValidateNotNull()]
        [SecureString]$password,

        # The Partner Center Native App application Id, or the Web App application Id.
        # The Native App application Id is used when connecting using user credentials,
        # and the Web App application Id is used when connecting using an application secret.
        [Parameter(Mandatory=$true, ParameterSetName="credential")]
        [Parameter(Mandatory=$true, ParameterSetName="servicePrincipal")]
        [ValidateNotNull()]
        [GUID]$applicationId,

        # The Partner Center Web App application secret
        [Parameter(Mandatory=$true, ParameterSetName="servicePrincipal")]
        [ValidateNotNull()]
        [SecureString]$applicationSecret,

        # The Office 365 tenant Id
        [Parameter(Mandatory=$true, ParameterSetName="servicePrincipal")]
        [ValidateNotNull()]
        [GUID]$tenantId,

        # The MSPComplete Endpoint for the Partner Center admin credentials.
        [Parameter(Mandatory=$true, ParameterSetName="endpoint", ValueFromPipeline=$true)]
        [ValidateNotNull()]
        $endpoint,

        # Select the stream where the failure messages will be directed.
        [Parameter(Mandatory=$false)]
        [ValidateSet("Information", "Warning", "Error")]
        [String]$outputStream = "Error"
    )

    # Track the authentication method used
    $authentication = ""

    # Extract the values from the endpoint
    if ($PSCmdlet.ParameterSetName -eq "endpoint") {
        $credential = $endpoint.Credential
        $username = $credential.Username
        $password = $credential.Password

        # Using app + user authentication
        if (Test-EmailAddressValidity -EmailAddress $username) {
            $authentication = "appUser"

            # Retrieve the application ID from the endpoint's extended properties
            if ([String]::IsNullOrWhiteSpace($endpoint.ExtendedProperties.ApplicationId)) {
                Write-OutputMessage "The endpoint provided does not have an 'ApplicationId' extended property." `
                    -OutputStream $outputStream | Out-Null
                return $false
            }
            $applicationId = $endpoint.ExtendedProperties.ApplicationId
        }

        # Using app-only authentication
        else {
            $authentication = "appOnly"
            $applicationId = $username
            $applicationSecret = $password
            $credential = [PSCredential]::new($applicationId, $applicationSecret)

            # Retrieve the tenant ID from the endpoint's extended properties
            if ([String]::IsNullOrWhiteSpace($endpoint.ExtendedProperties.TenantId)) {
                Write-OutputMessage "The endpoint provided does not have an 'TenantId' extended property." `
                    -OutputStream $outputStream | Out-Null
                return $false
            }
            $tenantId = $endpoint.ExtendedProperties.TenantId
        }
    }

    # Retrieve the authentication method to use based on the parameter set name
    elseif ($PSCmdlet.ParameterSetName -eq "credential") {
        $authentication = "appUser"
        $credential = [PSCredential]::new($username, $password)
    }
    else {
        $authentication = "appOnly"
        $credential = [PSCredential]::new($applicationId, $applicationSecret)
    }

    # Connect to Partner Center
    # Connect using app + user authentication
    if ($authentication -eq "appUser") {
        try {
            Write-Warning ("Using app + user authentication to connect to Partner Center." + $CRLF `
                + "This authentication method will no longer be supported by Microsoft as of 4 February 2019." + $CRLF `
                + "Switch to app-only authentication to continue to connect to Partner Center.")
            Write-Information "Connecting to Partner Center with username '$($username)' and application ID '$($applicationId)'."
            Connect-PartnerCenter -ApplicationId $applicationId -Credential $credential -ErrorAction Stop
        }
        catch {
            Write-OutputMessage "Exception occurred while connecting to Partner Center.`r`n$($_.Exception.Message)" `
                -OutputStream $outputStream | Out-Null
            return $false
        }
    }

    # Connect using app-only authentication
    else {
        try {
            Write-Information "Connecting to Partner Center with application Id $($applicationId)."
            Connect-PartnerCenter -Credential $credential -ServicePrincipal -TenantId $tenantId
        }
        catch {
            Write-OutputMessage "Exception occurred while connecting to Partner Center.`r`n$($_.Exception.Message)" `
                -OutputStream $outputStream | Out-Null
            return $false
        }
    }

    # Successfully connected
    return $true
}