Getting Intune Device Notes from Graph API

Profile picture for user PaulW
Posted by PaulW on Wed, 02/10/2021 - 10:43pm

Recently I have some clients requesting device datasets from Intune.  And the only real good way to get and modify device properties in mass is from the Graph API.  So, here we go.

There are a number of tutorials out there on using the Graph APi to get device details, so I'll skip right to the chase.  The Notes field quickly became our problem.Intune Device Properties Notes

Using the function Get-IntuneManagedDevice from the Microsoft.Graph.Intune module, you'll see that the "Notes" field doesn't even exist there.  As best I can tell, this is because this function uses the 1.0 API.  So, the function within the available module isn't our solution.

1.0 vs Beta

Graph has 2 APIs.  The version 1.0 API and the Beta API.  The Beta API exposes more of the properties of a device than does the 1.0 API.  Just taking a quick look at the documentation, and specifically the JSON representation, you'll see that the beta API is listing the Notes field where the 1.0 API is not.

1.0 API: https://docs.microsoft.com/en-us/graph/api/intune-devices-manageddevice-get?view=graph-rest-1.0#example

Beta API: https://docs.microsoft.com/en-us/graph/api/intune-devices-manageddevice-get?view=graph-rest-beta#example

You will notice that the 1.0 API example has no reference of the Notes field.  The Beta API does show the Notes field and will return the "Note Value".  Great, lets use the beta API!
Notes field example

Beta for the Win

Now that we know that the Beta API has the property, let's run a quick query:

$DeviceID = 'cdbdb5b1-43f8-4bdf-bce7-feef5cd1ab45'
$Resource = "deviceManagement/managedDevices('$DeviceID')"
$GraphApiVersion = "Beta"
$URI = "https://graph.microsoft.com/$graphApiVersion/$($resource)"
Invoke-MSGraphRequest -HttpMethod GET -Url $uri | Format-List deviceName,Notes

Which returns:

deviceName : BeesKnees
notes      :

Hmmmm....  Shouldn't that return "Important things about this computer stuffs." in the notes field like I have set for this computer above? (Yes it should)

What's going on?  Well a support call later, and some speculation on my part...  I guess Graph has the equivalent to lazy properties in Configuration Manager.  Or at least a single lazy property, Notes.

Ok. Now what?

Beta and Select for the Win Win

So not a PowerShell Select-Object, but a select parameter in the graph query.  Didn't figure this out on my own.  Had some help from support that provided a broken query that I had to tweak and fix the syntax.  Like I said, the trick is the select parameter.

A normal Graph device query uri will look something like this:

https://graph.microsoft.com/beta/deviceManagement/managedDevices('cdbdb5b1-43f8-4bdf-bce7-feef5cd1ab45')

With the select, it'll look like this:

https://graph.microsoft.com/beta/deviceManagement/managedDevices('cdbdb5b1-43f8-4bdf-bce7-feef5cd1ab45')?select=deviceName,notes

You can comma separate any number of properties you want to directly select and it returns only those properties specified. With this in mind, our new code block will look like this and I'm selecting the deviceName and Notes properties:

$DeviceID = 'cdbdb5b1-43f8-4bdf-bce7-feef5cd1ab45'
$Resource = "deviceManagement/managedDevices('$deviceId')"
$properties = 'deviceName,notes'
$uri = "https://graph.microsoft.com/beta/$($Resource)?select=$properties"
Invoke-MSGraphRequest -HttpMethod GET -Url $uri | Format-List

and this returns the following:

@odata.context : https://graph.microsoft.com/beta/$metadata#deviceManagement/managedDevices(deviceName,notes)/$entity
deviceName     : BeesKnees
notes          : Important things about this computer stuffs.

So, let's make a function to get the notes:

Function Get-IntuneDeviceNotes{
    <#
    .SYNOPSIS
    Gets the notes of a device in intune.
    
    .DESCRIPTION
    Gets the notes property on a device in intune using the beta Graph api
    
    .PARAMETER DeviceName
    The name of the device that you want to get the notes field from as it appears in intune.
    
    .EXAMPLE
    Get-IntuneDeviceNotes -DeviceName TestDevice01
    
    .NOTES
    Must connect to the graph api first with Connect-MSGraph.
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [String]
        $DeviceName
    )
    Try {
        $DeviceID = (Get-IntuneManagedDevice -filter "deviceName eq '$DeviceName'" -ErrorAction Stop).id
    }
    Catch {
        Write-Error $_.Exception.Message
        break
    }
    $deviceId = (Get-IntuneManagedDevice -Filter "deviceName eq 'BeesKnees'").id
    $Resource = "deviceManagement/managedDevices('$deviceId')"
    $properties = 'notes'
    $uri = "https://graph.microsoft.com/beta/$($Resource)?select=$properties"
    Try{
        (Invoke-MSGraphRequest -HttpMethod GET -Url $uri -ErrorAction Stop).notes
    }
    Catch{
        Write-Error $_.Exception.Message
        break
    }
}

 

Oh, and if you want a quick function to write to notes:

Function Set-IntuneDeviceNotes{
    <#
    .SYNOPSIS
    Sets the notes on a device in intune.
    
    .DESCRIPTION
    Sets the notes property on a device in intune using the beta Graph api
    
    .PARAMETER DeviceName
    The name of the device as it appears in intune.
    
    .PARAMETER Notes
    A string of the notes that you would like recorded in the notes field in intune.
    
    .EXAMPLE
    Set-IntuneDeviceNotes -DeviceName TestDevice01 -Notes "This is a note on the stuff and things for this device."
    
    .NOTES
    Must connect to the graph api first with Connect-MSGraph.
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [String]
        $DeviceName,
        [Parameter(Mandatory=$false)]
        [String]
        $Notes
    )
    Try {
        $DeviceID = (Get-IntuneManagedDevice -filter "deviceName eq '$DeviceName'" -ErrorAction Stop).id
    }
    Catch{
        Write-Error $_.Exception.Message
        break
    }
    If (![string]::IsNullOrEmpty($DeviceID)){
        $Resource = "deviceManagement/managedDevices('$DeviceID')"
        $GraphApiVersion = "Beta"
        $URI = "https://graph.microsoft.com/$graphApiVersion/$($resource)"
        $JSONPayload = @"
{
notes:"$Notes"
}
"@
        Try{
            Write-Verbose "$URI"
            Write-Verbose "$JSONPayload"
            Invoke-MSGraphRequest -HttpMethod PATCH -Url $uri -Content $JSONPayload -Verbose -ErrorAction Stop
        }
        Catch{
            Write-Error $_.Exception.Message
            break
        }
    }
}

Enjoy!

Additional Notes

With regards to select, I haven't found much of anything for the Intune Graph API in using the select parameter.  The only reference I found for select was in the general documentation for Graph here.

Related Technology

Comments

Thanks for this!

I am assuming the line:
$deviceId = (Get-IntuneManagedDevice -Filter "deviceName eq 'BeesKnees'").id
...is there to catch people out who don't look through the code before they run it!

:)

Hi.

Using this post with other references, I was able to create a Shell function using curl that reads and writes the "Notes" field of a Mac enrolled in Intune. It was a missing part in my LAPS project.

Many thanks !

Add new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
Verify you are a human.