-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDevice Code Flow.ps1
More file actions
105 lines (89 loc) · 3.5 KB
/
Device Code Flow.ps1
File metadata and controls
105 lines (89 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
$ErrorActionPreference = 'stop'
<#
.SYNOPSIS
Obtaining an Access Token for Microsoft Graph using the Device Code grant and
PowerShell with the Invoke-RestMethod cmdlet.
.DESCRIPTION
.NOTES
AUTHOR: https://github.com/dwarfered/msgraph-sdk-powershell-examples
UPDATED: 12-10-2023
#>
#region Supporting Functions
function Get-TokenUsingDeviceFlow {
[CmdletBinding()]
param
(
[Parameter(
Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[string] $TenantId,
[Parameter(
Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[string] $ClientId,
[Parameter(
Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 1)]
[string] $Scope
)
process {
$scope = $Scope
$uri = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/devicecode"
$headers = @{}
$headers.Add("Content-Type", "application/x-www-form-urlencoded")
$body = @{
scope = $Scope
client_id = $ClientId
}
$deviceCodeRequest = Invoke-RestMethod -Uri $uri -Method POST -Headers $headers -Body $body
$expires = (Get-Date).AddSeconds($deviceCodeRequest.expires_in)
$deviceCodeRequest | Add-Member -NotePropertyName expires -NotePropertyValue $expires
Write-Host $deviceCodeRequest.message
# Request Token
$uri = " https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
$body = @{
tenant = $tenantId
grant_type = 'urn:ietf:params:oauth:grant-type:device_code'
client_id = $clientId
device_code = $deviceCodeRequest.device_code
}
$bearerAccessToken = $null
if ($deviceCodeRequest.interval) {
do {
Start-Sleep -Seconds $deviceCodeRequest.interval
$errMsg = $null
try {
$bearerAccessToken = Invoke-RestMethod -Uri $uri -Method POST -Headers $headers -Body $body
$expires = (Get-Date).AddSeconds($bearerAccessToken.expires_in)
$bearerAccessToken | Add-Member -NotePropertyName expires -NotePropertyValue $expires
}
catch {
if ($_.Exception -is [System.Net.Http.HttpRequestException]) {
$errMsg = $_.ErrorDetails
$errMsg = (ConvertFrom-Json $errMsg).error
Write-Host $errMsg
if ($errMsg -eq 'invalid_client') {
Write-Host -ForegroundColor Yellow "Does $clientId allow public client flows?"
throw $_
}
}
else {
throw $_
}
}
} while ($errMsg -eq 'authorization_pending')
}
$bearerAccessToken
}
}
#endRegion
$tenantId = 'common'
# Client that allows public flows i.e. Azure AD PowerShell
$clientId = '1b730954-1685-4b74-9bfd-dac224a7b894'
$msGraphScope = 'https://graph.microsoft.com/.default'
$aadGraphScope = 'https://graph.windows.net/.default'
$msGraphToken = Get-TokenUsingDeviceFlow -TenantId $tenantId -ClientId $clientId -Scope $msGraphScope
$aadToken = Get-TokenUsingDeviceFlow -TenantId $tenantId -ClientId $clientId -Scope $aadGraphScope