Public/Connect-MsftIamApi.ps1

Function Connect-MsftIamApi {
    <#
        .SYNOPSIS
        Authenticates the end user to the Microsoft IAM Api.
 
        .DESCRIPTION
        Current version is focused on user authentication to the IAM Api.
        I have not yet successfully authenticated a service principal.
 
        .PARAMETER TenantId
        Takes in the tenant ID for the target azure tenant.
 
        .INPUTS
        None.
 
        .LINK
        https://github.com/nouselesstech/MsftIamApi
    #>


    param(
        [Parameter(Mandatory=$True)]
        [string]$TenantId
    )

    try {
        # Variables
        $ApplicationId  = '1950a258-227b-4e31-a9cf-717495945fc2'
        $Negs = @(
            'Go on. Do it. I dare you.',
            'You can do it!',
            'My grandma could have been done by now.',
            'What is the matter, Colonel Sanders? Chicken?',
            'Do it. Try it.',
            'Try it. You will like it.',
            'Try not. Do or do not. There is no try.'
        )

        ## Prepare the request information
        $Headers = @{}
        $Headers."Content-Type" = "application/x-www-form-urlencoded"

        $Body = "resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
        $Body += "&client_id=$ApplicationId"

        $Url = "https://login.microsoftonline.com/$TenantId/oauth2/devicecode"

        ## Complete the request
        $LoginRequest = Invoke-WebRequest `
            -Method Post `
            -Uri $Url `
            -Headers $Headers `
            -Body $Body
        $LoginBody = $LoginRequest | ConvertFrom-Json -Depth 100
        
        ## Prompt the user to login
        Write-Host $LoginBody.Message

        ## Wait for the authentication to complete
        $Body = ""
        $Body += "tenant=$TenantId"
        $Body += "&grant_type=urn:ietf:params:oauth:grant-type:device_code"
        $Body += "&client_id=$ApplicationId"
        $Body += "&device_code=$($LoginBody.device_code)"

        $Uri = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
        $TokenResponse = $Null
        While ($Null -eq $TokenResponse) { 
            $NagRequest = (Invoke-WebRequest `
                            -Uri $Uri `
                            -Body $Body `
                            -Headers $Headers `
                            -Method Post `
                            -SkipHttpErrorCheck ).Content | ConvertFrom-Json -Depth 100

            Switch($NagRequest.Error) {
                "authorization_pending"     {$Negs[(Get-Random -Minimum 0 -Maximum ($Negs.count-1))]}
                "authorization_declined"    {throw "You declined authorization. -_-"}
                "bad_verification_code"     {throw "Bad verification code"}
                "expired_token"             {throw "Device code token is expired. Try again."}
                default                     {$TokenResponse = $NagRequest}
            }

            Start-Sleep -Seconds 1
        }

        $Global:IamToken = $TokenResponse
        $Global:IamToken | Out-Null
        return $True
    } catch {
        Write-Error "Unable to connect to the IAM API. `r`n $_"
    }
}