1+ <#
2+
3+ .COPYRIGHT
4+ Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
5+ See LICENSE in the project root for license information.
6+
7+ #>
8+
9+ # ###################################################
10+
11+ function Get-AuthToken {
12+
13+ <#
14+ . SYNOPSIS
15+ This function is used to authenticate with the Graph API REST interface
16+ . DESCRIPTION
17+ The function authenticate with the Graph API Interface with the tenant name
18+ . EXAMPLE
19+ Get-AuthToken
20+ Authenticates you with the Graph API interface
21+ . NOTES
22+ NAME: Get-AuthToken
23+ #>
24+
25+ [cmdletbinding ()]
26+
27+ param
28+ (
29+ [Parameter (Mandatory = $true )]
30+ $User
31+ )
32+
33+ $userUpn = New-Object " System.Net.Mail.MailAddress" - ArgumentList $User
34+
35+ $tenant = $userUpn.Host
36+
37+ Write-Host " Checking for AzureAD module..."
38+
39+ $AadModule = Get-Module - Name " AzureAD" - ListAvailable
40+
41+ if ($AadModule -eq $null ) {
42+
43+ Write-Host " AzureAD PowerShell module not found, looking for AzureADPreview"
44+ $AadModule = Get-Module - Name " AzureADPreview" - ListAvailable
45+
46+ }
47+
48+ if ($AadModule -eq $null ) {
49+ write-host
50+ write-host " AzureAD Powershell module not installed..." -f Red
51+ write-host " Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow
52+ write-host " Script can't continue..." -f Red
53+ write-host
54+ exit
55+ }
56+
57+ # Getting path to ActiveDirectory Assemblies
58+ # If the module count is greater than 1 find the latest version
59+
60+ if ($AadModule.count -gt 1 ){
61+
62+ $Latest_Version = ($AadModule | select version | Sort-Object )[-1 ]
63+
64+ $aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version }
65+
66+ # Checking if there are multiple versions of the same module found
67+
68+ if ($AadModule.count -gt 1 ){
69+
70+ $aadModule = $AadModule | select - Unique
71+
72+ }
73+
74+ $adal = Join-Path $AadModule.ModuleBase " Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
75+ $adalforms = Join-Path $AadModule.ModuleBase " Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
76+
77+ }
78+
79+ else {
80+
81+ $adal = Join-Path $AadModule.ModuleBase " Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
82+ $adalforms = Join-Path $AadModule.ModuleBase " Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"
83+
84+ }
85+
86+ [System.Reflection.Assembly ]::LoadFrom($adal ) | Out-Null
87+
88+ [System.Reflection.Assembly ]::LoadFrom($adalforms ) | Out-Null
89+
90+ $clientId = " d1ddf0e4-d672-4dae-b554-9d5bdfd93547"
91+
92+ $redirectUri = " urn:ietf:wg:oauth:2.0:oob"
93+
94+ $resourceAppIdURI = " https://graph.microsoft.com"
95+
96+ $authority = " https://login.microsoftonline.com/$Tenant "
97+
98+ try {
99+
100+ $authContext = New-Object " Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" - ArgumentList $authority
101+
102+ # https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx
103+ # Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession
104+
105+ $platformParameters = New-Object " Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" - ArgumentList " Auto"
106+
107+ $userId = New-Object " Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" - ArgumentList ($User , " OptionalDisplayableId" )
108+
109+ $authResult = $authContext.AcquireTokenAsync ($resourceAppIdURI , $clientId , $redirectUri , $platformParameters , $userId ).Result
110+
111+ # If the accesstoken is valid then create the authentication header
112+
113+ if ($authResult.AccessToken ){
114+
115+ # Creating header for Authorization token
116+
117+ $authHeader = @ {
118+ ' Content-Type' = ' application/json'
119+ ' Authorization' = " Bearer " + $authResult.AccessToken
120+ ' ExpiresOn' = $authResult.ExpiresOn
121+ }
122+
123+ return $authHeader
124+
125+ }
126+
127+ else {
128+
129+ Write-Host
130+ Write-Host " Authorization Access Token is null, please re-run authentication..." - ForegroundColor Red
131+ Write-Host
132+ break
133+
134+ }
135+
136+ }
137+
138+ catch {
139+
140+ write-host $_.Exception.Message -f Red
141+ write-host $_.Exception.ItemName -f Red
142+ write-host
143+ break
144+
145+ }
146+
147+ }
148+
149+ # ###################################################
150+
151+ Function Export-iOSDevices (){
152+
153+ <#
154+ . SYNOPSIS
155+ This function is used to export iOS Devices from the Graph API REST interface
156+ . DESCRIPTION
157+ The function connects to the Graph API Interface and exports iOS devices
158+ . EXAMPLE
159+ Export-Devices
160+ Returns any iOS Device enrolled into Intune
161+ . NOTES
162+ NAME: Export-iOSDevices
163+ #>
164+
165+ [cmdletbinding ()]
166+
167+ param
168+ (
169+ $Name
170+ )
171+
172+ $graphApiVersion = " beta"
173+ $Resource = " deviceManagement/reports/exportJobs"
174+
175+ try {
176+
177+ $properties = @ {
178+
179+ reportName = ' Devices'
180+ select = @ (' DeviceId' , " DeviceName" , " OSVersion" , " HasUnlockToken" )
181+ filter = " ((DeviceType eq '14') or (DeviceType eq '9') or (DeviceType eq '8') or (DeviceType eq '10'))"
182+
183+ }
184+
185+ $psObj = New-Object - TypeName psobject - Property $properties
186+
187+ $Json = ConvertTo-Json - InputObject $psObj
188+
189+ if ($Name ){
190+
191+ $uri = " https://graph.microsoft.com/$graphApiVersion /$ ( $Resource ) "
192+ (Invoke-RestMethod - Uri $uri - Headers $authToken - Method Get).Value | Where-Object { ($_ .' displayName' ).contains(" $Name " ) }
193+
194+ }
195+
196+ else {
197+
198+ $uri = " https://graph.microsoft.com/$graphApiVersion /$ ( $Resource ) "
199+ $result = (Invoke-RestMethod - Uri $uri - Headers $authToken - Method Post - Body $JSON - ContentType " application/json" )
200+
201+ $id = $result.id
202+
203+ write-host " Export Job id is '$id '" - ForegroundColor Cyan
204+
205+ Write-Host
206+
207+ while ($true ){
208+
209+ $pollingUri = " $uri ('$id ')"
210+ write-host " Polling uri = " $pollingUri
211+
212+ $result = (Invoke-RestMethod - Uri $pollingUri - Headers $authToken - Method Get)
213+ $status = $result.status
214+
215+ if ($status -eq ' completed' ){
216+
217+ Write-Host " Export Job Complete..." - ForegroundColor Green
218+ Write-Host
219+
220+ $fileName = (Split-Path - Path $result.url - Leaf).split(' ?' )[0 ]
221+
222+ Invoke-WebRequest - Uri $result.url - OutFile $env: temp \$fileName
223+
224+ Write-host " Downloaded Export to local disk as '$env: temp \$fileName '..." - ForegroundColor Green
225+ Write-Host
226+ break ;
227+
228+ }
229+
230+ else {
231+
232+ Write-Host " In progress, waiting..." - ForegroundColor Yellow
233+ Start-Sleep - Seconds 5
234+ Write-Host
235+
236+ }
237+
238+ }
239+
240+ }
241+
242+ }
243+
244+ catch {
245+
246+ $ex = $_.Exception
247+ Write-Host " Request to $Uri failed with HTTP Status $ ( [int ]$ex.Response.StatusCode ) $ ( $ex.Response.StatusDescription ) " -f Red
248+ $errorResponse = $ex.Response.GetResponseStream ()
249+ $reader = New-Object System.IO.StreamReader($errorResponse )
250+ $reader.BaseStream.Position = 0
251+ $reader.DiscardBufferedData ()
252+ $responseBody = $reader.ReadToEnd ();
253+ Write-Host " Response content:`n $responseBody " -f Red
254+ Write-Error " Request to $Uri failed with HTTP Status $ ( $ex.Response.StatusCode ) $ ( $ex.Response.StatusDescription ) "
255+ write-host
256+ break
257+
258+ }
259+
260+ }
261+
262+ # ###################################################
263+
264+ # region Authentication
265+
266+ write-host
267+
268+ # Checking if authToken exists before running authentication
269+ if ($global :authToken ){
270+
271+ # Setting DateTime to Universal time to work in all timezones
272+ $DateTime = (Get-Date ).ToUniversalTime()
273+
274+ # If the authToken exists checking when it expires
275+ $TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime ).Minutes
276+
277+ if ($TokenExpires -le 0 ){
278+
279+ write-host " Authentication Token expired" $TokenExpires " minutes ago" - ForegroundColor Yellow
280+ write-host
281+
282+ # Defining User Principal Name if not present
283+
284+ if ($User -eq $null -or $User -eq " " ){
285+
286+ $User = Read-Host - Prompt " Please specify your user principal name for Azure Authentication"
287+ Write-Host
288+
289+ }
290+
291+ $global :authToken = Get-AuthToken - User $User
292+
293+ }
294+ }
295+
296+ # Authentication doesn't exist, calling Get-AuthToken function
297+
298+ else {
299+
300+ if ($User -eq $null -or $User -eq " " ){
301+
302+ $User = Read-Host - Prompt " Please specify your user principal name for Azure Authentication"
303+ Write-Host
304+
305+ }
306+
307+ # Getting the authorization token
308+ $global :authToken = Get-AuthToken - User $User
309+
310+ }
311+
312+ # endregion
313+
314+ # ###################################################
315+
316+ Export-iOSDevices
0 commit comments