-
Notifications
You must be signed in to change notification settings - Fork 654
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
edc639f
commit 157e868
Showing
2 changed files
with
548 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
|
||
<# | ||
.COPYRIGHT | ||
Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. | ||
See LICENSE in the project root for license information. | ||
#> | ||
|
||
param( | ||
|
||
[Parameter(Mandatory = $true, HelpMessage = "File path and name for output of expiring devices")] | ||
$OutputFile | ||
|
||
) | ||
|
||
#################################################### | ||
|
||
function Get-AuthToken { | ||
|
||
<# | ||
.SYNOPSIS | ||
This function is used to authenticate with the Graph API REST interface | ||
.DESCRIPTION | ||
The function authenticate with the Graph API Interface with the tenant name | ||
.EXAMPLE | ||
Get-AuthToken | ||
Authenticates you with the Graph API interface | ||
.NOTES | ||
NAME: Get-AuthToken | ||
#> | ||
|
||
[cmdletbinding()] | ||
|
||
param | ||
( | ||
[Parameter(Mandatory=$true)] | ||
$User | ||
) | ||
|
||
$userUpn = New-Object "System.Net.Mail.MailAddress" -ArgumentList $User | ||
|
||
$tenant = $userUpn.Host | ||
|
||
Write-Host "Checking for AzureAD module..." | ||
|
||
$AadModule = Get-Module -Name "AzureAD" -ListAvailable | ||
|
||
if ($AadModule -eq $null) { | ||
|
||
Write-Host "AzureAD PowerShell module not found, looking for AzureADPreview" | ||
$AadModule = Get-Module -Name "AzureADPreview" -ListAvailable | ||
|
||
} | ||
|
||
if ($AadModule -eq $null) { | ||
write-host | ||
write-host "AzureAD Powershell module not installed..." -f Red | ||
write-host "Install by running 'Install-Module AzureAD' or 'Install-Module AzureADPreview' from an elevated PowerShell prompt" -f Yellow | ||
write-host "Script can't continue..." -f Red | ||
write-host | ||
exit | ||
} | ||
|
||
# Getting path to ActiveDirectory Assemblies | ||
# If the module count is greater than 1 find the latest version | ||
|
||
if($AadModule.count -gt 1){ | ||
|
||
$Latest_Version = ($AadModule | select version | Sort-Object)[-1] | ||
|
||
$aadModule = $AadModule | ? { $_.version -eq $Latest_Version.version } | ||
|
||
# Checking if there are multiple versions of the same module found | ||
|
||
if($AadModule.count -gt 1){ | ||
|
||
$aadModule = $AadModule | select -Unique | ||
|
||
} | ||
|
||
$adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" | ||
$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" | ||
|
||
} | ||
|
||
else { | ||
|
||
$adal = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll" | ||
$adalforms = Join-Path $AadModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" | ||
|
||
} | ||
|
||
[System.Reflection.Assembly]::LoadFrom($adal) | Out-Null | ||
|
||
[System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null | ||
|
||
$clientId = "d1ddf0e4-d672-4dae-b554-9d5bdfd93547" | ||
|
||
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" | ||
|
||
$resourceAppIdURI = "https://graph.microsoft.com" | ||
|
||
$authority = "https://login.microsoftonline.com/$Tenant" | ||
|
||
try { | ||
|
||
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority | ||
|
||
# https://msdn.microsoft.com/en-us/library/azure/microsoft.identitymodel.clients.activedirectory.promptbehavior.aspx | ||
# Change the prompt behaviour to force credentials each time: Auto, Always, Never, RefreshSession | ||
|
||
$platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" | ||
|
||
$userId = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.UserIdentifier" -ArgumentList ($User, "OptionalDisplayableId") | ||
|
||
$authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result | ||
|
||
# If the accesstoken is valid then create the authentication header | ||
|
||
if($authResult.AccessToken){ | ||
|
||
# Creating header for Authorization token | ||
|
||
$authHeader = @{ | ||
'Content-Type'='application/json' | ||
'Authorization'="Bearer " + $authResult.AccessToken | ||
'ExpiresOn'=$authResult.ExpiresOn | ||
} | ||
|
||
return $authHeader | ||
|
||
} | ||
|
||
else { | ||
|
||
Write-Host | ||
Write-Host "Authorization Access Token is null, please re-run authentication..." -ForegroundColor Red | ||
Write-Host | ||
break | ||
|
||
} | ||
|
||
} | ||
|
||
catch { | ||
|
||
write-host $_.Exception.Message -f Red | ||
write-host $_.Exception.ItemName -f Red | ||
write-host | ||
break | ||
|
||
} | ||
|
||
} | ||
|
||
#################################################### | ||
|
||
function Get-MsGraphCollection { | ||
|
||
param | ||
( | ||
[Parameter(Mandatory = $true)] | ||
$Uri, | ||
|
||
[Parameter(Mandatory = $true)] | ||
$AuthHeader | ||
) | ||
|
||
$Collection = @() | ||
$NextLink = $Uri | ||
$CertExpiration = [datetime]'2020-07-12 12:00:00' #(Get-Date -Year 2019 -Month 4 -Day 21 -Hour 14 -Minute 48) | ||
|
||
do { | ||
|
||
try { | ||
|
||
Write-Host "GET $NextLink" | ||
$Result = Invoke-RestMethod -Method Get -Uri $NextLink -Headers $AuthHeader | ||
|
||
foreach ($d in $Result.value) | ||
{ | ||
if ([datetime]($d.managementCertificateExpirationDate) -le $CertExpiration) | ||
{ | ||
$Collection += $d | ||
} | ||
} | ||
$NextLink = $Result.'@odata.nextLink' | ||
} | ||
|
||
catch { | ||
|
||
$ResponseStream = $_.Exception.Response.GetResponseStream() | ||
$ResponseReader = New-Object System.IO.StreamReader $ResponseStream | ||
$ResponseContent = $ResponseReader.ReadToEnd() | ||
Write-Host "Request Failed: $($_.Exception.Message)`n$($_.ErrorDetails)" | ||
Write-Host "Request URL: $NextLink" | ||
Write-Host "Response Content:`n$ResponseContent" | ||
break | ||
|
||
} | ||
|
||
} while ($NextLink -ne $null) | ||
|
||
return $Collection | ||
} | ||
|
||
#################################################### | ||
|
||
#region Authentication | ||
|
||
write-host | ||
|
||
# Checking if authToken exists before running authentication | ||
if($global:authToken){ | ||
|
||
# Setting DateTime to Universal time to work in all timezones | ||
$DateTime = (Get-Date).ToUniversalTime() | ||
|
||
# If the authToken exists checking when it expires | ||
$TokenExpires = ($authToken.ExpiresOn.datetime - $DateTime).Minutes | ||
|
||
if($TokenExpires -le 0){ | ||
|
||
write-host "Authentication Token expired" $TokenExpires "minutes ago" -ForegroundColor Yellow | ||
write-host | ||
|
||
# Defining User Principal Name if not present | ||
|
||
if($User -eq $null -or $User -eq ""){ | ||
|
||
$User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" | ||
Write-Host | ||
|
||
} | ||
|
||
$global:authToken = Get-AuthToken -User $User | ||
|
||
} | ||
} | ||
|
||
# Authentication doesn't exist, calling Get-AuthToken function | ||
|
||
else { | ||
|
||
if($User -eq $null -or $User -eq ""){ | ||
|
||
$User = Read-Host -Prompt "Please specify your user principal name for Azure Authentication" | ||
Write-Host | ||
|
||
} | ||
|
||
# Getting the authorization token | ||
$global:authToken = Get-AuthToken -User $User | ||
|
||
} | ||
|
||
#endregion | ||
|
||
#################################################### | ||
|
||
$uri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices?`$filter=((managementAgent%20eq%20%27mdm%27%20or%20managementAgent%20eq%20%27easmdm%27%20or%20managementAgent%20eq%20%27configurationmanagerclientmdm%27%20or%20managementAgent%20eq%20%27configurationmanagerclientmdmeas%27)%20and%20managementState%20eq%20%27managed%27)" | ||
|
||
$devices = Get-MsGraphCollection -Uri $uri -AuthHeader $authToken | ||
|
||
Write-Host | ||
Write-Host "Found" $devices.Count "devices:" | ||
Write-Host "Writing results to" $OutputFile -ForegroundColor Cyan | ||
|
||
($devices | Select-Object Id, DeviceName, DeviceType, IMEI, UserPrincipalName, SerialNumber, LastSyncDateTime, ManagementCertificateExpirationDate) | Export-Csv -Path $OutputFile -NoTypeInformation | ||
|
||
$devices | Select-Object Id, DeviceName, DeviceType, IMEI, UserPrincipalName, SerialNumber, LastSyncDateTime, ManagementCertificateExpirationDate | ||
|
||
Write-Host "Results written to" $OutputFile -ForegroundColor Yellow |
Oops, something went wrong.