#Get All Windows 10 Intune Managed Devices for the Tenant
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-Win10IntuneManagedDevice {

    <#
    .SYNOPSIS
    This gets information on Intune managed device
    .DESCRIPTION
    This gets information on Intune managed device
    .EXAMPLE
    Get-Win10IntuneManagedDevice
    .NOTES
    NAME: Get-Win10IntuneManagedDevice
    #>
    
    [cmdletbinding()]
    
    param
    (
    [parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [string]$deviceName
    )
        
        $graphApiVersion = "beta"
    
        try {
    
            if($deviceName){
    
                $Resource = "deviceManagement/managedDevices?`$filter=deviceName eq '$deviceName'"
                $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" 
    
                (Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).value
    
            }
    
            else {
    
                $Resource = "deviceManagement/managedDevices?`$filter=(((deviceType%20eq%20%27desktop%27)%20or%20(deviceType%20eq%20%27windowsRT%27)%20or%20(deviceType%20eq%20%27winEmbedded%27)%20or%20(deviceType%20eq%20%27surfaceHub%27)))"
                $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)"
            
                (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)"
            throw "Get-IntuneManagedDevices error"
        }
    
    }
    
function Get-IntuneDevicePrimaryUser {

    <#
    .SYNOPSIS
    This lists the Intune device primary user
    .DESCRIPTION
    This lists the Intune device primary user
    .EXAMPLE
    Get-IntuneDevicePrimaryUser
    .NOTES
    NAME: Get-IntuneDevicePrimaryUser
    #>
    
    [cmdletbinding()]
    
    param
    (
        [Parameter(Mandatory=$true)]
        [string] $deviceId
    )
        
        $graphApiVersion = "beta"
        $Resource = "deviceManagement/managedDevices"
        $uri = "https://graph.microsoft.com/$graphApiVersion/$($Resource)" + "/" + $deviceId + "/users"
    
        try {
            
            $primaryUser = Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get
    
            return $primaryUser.value."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)"
            throw "Get-IntuneDevicePrimaryUser error"
        }
    }

#$authtoken = Get-AuthToken -User andrew.amason@carecentrix.com

$Devices = Get-Win10IntuneManagedDevice | where usersLoggedOn -ne $Null

Foreach ($Device in $Devices) {

    Write-Host "Device name:" $device."deviceName" -ForegroundColor Cyan
    $IntuneDevicePrimaryUser = Get-IntuneDevicePrimaryUser -deviceId $Device.id

    #Check if there is a Primary user set on the device already
    if ($IntuneDevicePrimaryUser -eq $null) {

        Write-Host "No Intune Primary User Id set for Intune Managed Device" $Device."deviceName" -f Red

    }

    else {
        $PrimaryAADUser = Get-AzureADUser -ObjectId $IntuneDevicePrimaryUser
        Write-Host "Intune Device Primary User:" $PrimaryAADUser.displayName

    }

    #Get the objectID of the last logged in user for the device, which is the last object in the list of usersLoggedOn
    $LastLoggedInUser = ($Device.usersLoggedOn[-1]).userId

    #Using the objectID, get the user from the Microsoft Graph for logging purposes
    $User = Get-AzureADUser -ObjectId $LastLoggedInUser

    #Check if the current primary user of the device is the same as the last logged in user
    if ($IntuneDevicePrimaryUser -notmatch $User.ObjectId) {

        #If the user does not match, then set the last logged in user as the new Primary User
        $SetIntuneDevicePrimaryUser = Set-IntuneDevicePrimaryUser -IntuneDeviceId $Device.id -userId $User.id

        if ($SetIntuneDevicePrimaryUser -eq "") {

            Write-Host "User"$User.displayName"set as Primary User for device '$($Device.deviceName)'..." -ForegroundColor Green

        }

    }

    else {
        #If the user is the same, then write to host that the primary user is already correct.
        Write-Host "The user '$($User.displayName)' is already the Primary User on the device..." -ForegroundColor Yellow
 
    }

    Write-Host

}
