Azure Device Authentication with PowerShell Universal

Someone asked for an example like this so I wanted to share with the community.

This technique uses device authentication. The concept is that we have a PowerShell script that connects to azure with Connect-AzAccount and -DeviceAuth parameter. It then returns the device connect URL and code. The script will then wait until the user authenticates.

On the dashboard (UI) side, the user will be presented with the URL and code. Once the user authenticates, the script can advance the script will continue under the context of that user and tenant. Since each script in PSU runs under it’s own process, you can use the Process scope with Connect-AzAccount.

The PSU script is just:

Connect-AzAccount -Scope Process -DeviceAuth
# do azure stuff here

The dashboard I created uses a stepper and presents the user with the device auth information.

New-UDDashboard -Title "Hello, World!" -Content {
    New-UDStepper -Steps {
        New-UDStep -OnLoad {
            New-UDElement -tag 'div' -Content { 
                "Click next to login to Azure. You can put some more information here." 
            }
        } -Label "Welcome"
        New-UDStep -OnLoad {
            do {
                $Output = Get-UAJobOutput -JobId $Session:JobId -ComputerName "http://localhost:5000" -AppToken $AppToken
                $DeviceLogin = $output | where { $_.Data -ne $null -and $_.Data.Contains("devicelogin") }
            } while($DeviceLogin -eq $null)

            New-UDElement -tag 'div' -Content { $DeviceLogin.Data }
        } -Label "Log In"
    } -OnFinish {
        New-UDDynamic -Id 'progress' -Content {
            $Job = get-uajob -id $Session:JobId -ComputerName "http://localhost:5000" -AppToken $AppToken
            if ($Job.Status -ne "Completed")
            {
                New-UDProgress -Circular 
            }
        }
        New-UDDynamic -Id 'jobstatus' -Content {
            do {
                $Job = get-uajob -id $Session:JobId -ComputerName "http://localhost:5000" -AppToken $AppToken
            } while ($Job.Status -ne 'Completed')
            Sync-UDElement -Id 'progress'
            New-UDElement -tag 'div' -Content { "Complete!" }
        }
    } -OnValidateStep {
        $Context = $EventData
        if ($Context.CurrentStep -eq 0)
        {
            $Session:JobId = (Invoke-UAScript "Az.ps1" -ComputerName "http://localhost:5000" -AppToken $AppToken).Id 
        }
        New-UDValidationResult -Valid -DisablePrevious
    }
}

It requires an AppToken variable defined either in the script or within the variables.

Here’s an example of what the flow looks like for the user.

az

2 Likes

@adam i like the MTG website interception in this demo :smile:

It’s my random MTG card extension lol Magic: The Gathering Tab - Chrome Web Store

1 Like

@adam Do you know if it works with the newest version of PowerShell Universal? I tried to edit the old get-uajoboutput commands etc. to the newer commands. It starts the job, but the Device Login Output will not be shown. Its just keeps loading in the dashboard after pressing the next button.