Skip to content

Instantly share code, notes, and snippets.

@tomasgreen
Last active November 22, 2018 18:10
Show Gist options
  • Save tomasgreen/80420eab4e41bb912b2ed15971eea0fd to your computer and use it in GitHub Desktop.
Save tomasgreen/80420eab4e41bb912b2ed15971eea0fd to your computer and use it in GitHub Desktop.
Update device ownership on Intune managed devices
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,
$Password
)
$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 = "YOUR CLIENT ID"
$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")
if($Password -eq $null){
$authResult = $authContext.AcquireTokenAsync($resourceAppIdURI,$clientId,$redirectUri,$platformParameters,$userId).Result
}
else {
if(test-path "$Password"){
$UserPassword = get-Content "$Password" | ConvertTo-SecureString
$userCredentials = new-object Microsoft.IdentityModel.Clients.ActiveDirectory.UserPasswordCredential -ArgumentList $userUPN,$UserPassword
$authResult = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions]::AcquireTokenAsync($authContext, $resourceAppIdURI, $clientid, $userCredentials).Result;
} else {
Write-Host "Path to Password file" $Password "doesn't exist, please specify a valid path..." -ForegroundColor Red
Write-Host "Script can't continue..." -ForegroundColor Red
Write-Host
break
}
}
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
}
}
#region Authentication
#update info with service account and credential.txt file location
$User = "YOUR SERVICE ACCOUNT OR GLOBAL ADMIN"
$Password = "PASSWORD"
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 Azure AD tenant name, this is the name of your Azure Active Directory (do not use the verified domain name)
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 -Password "$Password"
}
} else {
# Authentication doesn't exist, calling Get-AuthToken function
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 -Password "$Password"
}
#endregion
Function Get-ManagedDevices(){
<#
.SYNOPSIS
This function is used to get Intune Managed Devices from the Graph API REST interface
.DESCRIPTION
The function connects to the Graph API Interface and gets any Intune Managed Device
.EXAMPLE
Get-ManagedDevices
Returns all managed devices but excludes EAS devices registered within the Intune Service
.EXAMPLE
Get-ManagedDevices -IncludeEAS
Returns all managed devices including EAS devices registered within the Intune Service
.NOTES
NAME: Get-ManagedDevices
#>
[cmdletbinding()]
param
(
[switch]$IncludeEAS,
[switch]$ExcludeMDM
)
# Defining Variables
$graphApiVersion = "v1.0"
try {
$Count_Params = 0
if($IncludeEAS.IsPresent){ $Count_Params++ }
if($ExcludeMDM.IsPresent){ $Count_Params++ }
if($Count_Params -gt 1){
write-warning "Multiple parameters set, specify a single parameter -IncludeEAS, -ExcludeMDM or no parameter against the function"
Write-Host
break
} elseif($IncludeEAS) {
$uri = "https://graph.microsoft.com/$graphApiVersion/deviceManagement/managedDevices"
} elseif($ExcludeMDM) {
$uri = "https://graph.microsoft.com/$graphApiVersion/deviceManagement/managedDevices`?`$filter=managementAgent eq 'eas'"
} else {
$uri = "https://graph.microsoft.com/$graphApiVersion/deviceManagement/managedDevices`?`$filter=managementAgent eq 'mdm' and managementAgent eq 'easmdm'"
Write-Warning "EAS Devices are excluded by default, please use -IncludeEAS if you want to include those devices"
Write-Host
}
(Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value
} catch {
$ex = $_.Exception
$errorResponse = $ex.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($errorResponse)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
Write-Host "Response content:`n$responseBody" -f Red
Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
write-host
break
}
}
# This function is slightly changed from the original and I have removed the need to confirm each action (can't automate something that needs confirmation)
Function Set-ManagedDevice(){
<#
.SYNOPSIS
This function is used to set Managed Device property from the Graph API REST interface
.DESCRIPTION
The function connects to the Graph API Interface and sets a Managed Device property
.EXAMPLE
Set-ManagedDevice -id $id -ownerType company
Returns Managed Devices configured in Intune
.NOTES
NAME: Set-ManagedDevice
#>
[cmdletbinding()]
param
(
$id,
$ownertype
)
$graphApiVersion = "v1.0"
try {
if($id -eq "" -or $id -eq $null){
write-host "No Device id specified, please provide a device id..." -f Red
break
}
if($ownerType -eq "" -or $ownerType -eq $null){
write-host "No ownerType parameter specified, please provide an ownerType. Supported value personal or company..." -f Red
Write-Host
break
} elseif($ownerType -eq "company") {
$JSON = "{ ownerType:\`"company\`" }"
# Send Patch command to Graph to change the ownertype
$uri = "https://graph.microsoft.com/$graphApiVersion/deviceManagement/managedDevices('$ID')"
Invoke-RestMethod -Uri $uri -Headers $authToken -Method Patch -Body $Json -ContentType "application/json"
Write-Host -ForegroundColor Yellow "Ownertype changed to company for device:" $ID
} elseif($ownerType -eq "personal"){
$JSON = "{ ownerType:\`"personal\`" }"
# Send Patch command to Graph to change the ownertype
$uri = "https://graph.microsoft.com/$graphApiVersion/deviceManagement/managedDevices('$ID')"
Invoke-RestMethod -Uri $uri -Headers $authToken -Method Patch -Body $Json -ContentType "application/json"
Write-Host -ForegroundColor Yellow "Ownertype changed to personal for device:" $ID
}
} catch {
$ex = $_.Exception
$errorResponse = $ex.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($errorResponse)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
Write-Host "Response content:`n$responseBody" -f Red
Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
write-host
break
}
}
# Getting all personal owned devices
$PersonalDevices = Get-ManagedDevices | Where-Object {$_.OwnerType -eq "personal"} | Select-Object id,devicename,ownertype
# If any personal devices found
if ($PersonalDevices -ne $null) {
# Personal devices found - looping through each
ForEach ($PersonalDevice in $PersonalDevices) {
# Setting ownertype on devices
Set-ManagedDevice -id $PersonalDevice.id -ownertype Company
}
} else {
# No devices found - write to host
Write-Host -ForegroundColor Yellow "No personal devices found"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment