Search code examples
azurepowershellmicrosoft-graph-apiintune

Error 404 Not Found when trying to add an Intune device to a security group through a PS script using Graph API


I keep struggling with this PS script which based on app detection through reg key, adds an Intune device to an Entra Id security group. Most of the script seems to run fine but I keep getting errors at the point where it tries to actually the device to the group. Detection works, it gives the desired output, it also finds and identifies the device with the object id, then tries to add it to the group but fails

I will post the whole script here and highlight where it fails

# Define variables
$TenantID = "*my tenant id*"
$ClientID = "*registered app client id*"
$ClientSecret = "*app secret*"
$SecurityGroupID = "*security group ID I want to add the device to*"
$RegistryPath = "*HKLM:\SOFTWARE\...*"
$RegistryValue = "*Random value to test detection*"



# Function to get an access token from Microsoft Graph
function Get-GraphToken {
    $body = @{
        grant_type    = "client_credentials"
        client_id     = $ClientID
        client_secret = $ClientSecret
        scope         = "https://graph.microsoft.com/.default"
    }
    $response = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$TenantID/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $body
    return $response.access_token
}

# Function to get Intune device ID
function Get-IntuneDeviceID {
    param (
        [string]$DeviceName
    )
    $token = Get-GraphToken
    $headers = @{ Authorization = "Bearer $token" }

    $url = "https://graph.microsoft.com/v1.0/devicemanagement/managedDevices?`$filter=deviceName eq '$DeviceName'"
    $response = Invoke-RestMethod -Method Get -Uri $url -Headers $headers -ContentType "application/json"

    if ($response.value.Count -gt 0) {
        return $response.value[0].id
    } else {
        Write-Host "Device not found in Intune." -ForegroundColor Red
        return $null
    }
}

**# Function to add device to security group
function Add-DeviceToGroup {
    param (
        [string]$DeviceID
    )
    $token = Get-GraphToken
    $headers = @{ Authorization = "Bearer $token" ; "Content-Type" = "application/json" }
    
    $body = @{
        "@odata.id" = "https://graph.microsoft.com/v1.0/devices/$DeviceID"
    } | ConvertTo-Json -Depth 2

    $url = "https://graph.microsoft.com/v1.0/groups/$SecurityGroupID/members/`$ref"
    $response = Invoke-RestMethod -Method Post -Uri $url -Headers $headers -Body $body

    Write-Host "Device successfully added to security group." -ForegroundColor Green
}**

# Check for registry key presence
if (Test-Path $RegistryPath) {
    $regValue = Get-ItemProperty -Path $RegistryPath -Name $RegistryValue -ErrorAction SilentlyContinue
    if ($regValue -ne $null) {
        Write-Host "Registry key found. Proceeding with Intune operation." -ForegroundColor Yellow
        $DeviceName = $env:COMPUTERNAME
        $DeviceID = Get-IntuneDeviceID -DeviceName $DeviceName

        if ($DeviceID) {
            Add-DeviceToGroup -DeviceID $DeviceID
        }
    } else {
        Write-Host "Registry key exists, but value not found." -ForegroundColor Red
    }
} else {
    Write-Host "Registry key not found. No action taken." -ForegroundColor Red
}

When I run the script, it gives me the output "Registry key found. Proceeding with Intune Operation." and then throws the error 404 not found When inspecting the request in Fiddler this is shown :

{"error":{"code":"Request_ResourceNotFound","message":"Resource 'my device id' does not exist or one of its queried reference-property objects are not present.

When I look for the device id in Intune, I can find it no problem so it must be something else?

I have posted before regarding my issues with this script, so apologies if this is again duplicate, I have followed all the recommendations and advice but not getting further again now...

Really grateful for any assistance.


Solution

  • There is no correlation between the id properties from managedDevices and devices endpoints, the correlated property between these 2 APIs is azureADDeviceId (on managedDevices) and deviceId (on devices), so what you should do in your Get-IntuneDeviceID is:

    if ($response.value.Count -gt 0) {
        # return `azureADDeviceId` instead of `id`
        return $response.value[0].azureADDeviceId
    }
    else {
        Write-Host 'Device not found in Intune.' -ForegroundColor Red
        return $null
    }
    

    Then, to find that device in devices API you can use:

    https://graph.microsoft.com/v1.0/devices(deviceId='$DeviceID')
    

    So, when calling Add members you can use that URI as your @odata.id:

    $deviceId = Get-IntuneDeviceID -DeviceName $DeviceName
    $url = "https://graph.microsoft.com/v1.0/groups/$SecurityGroupID/members/`$ref"
    Invoke-RestMethod -Method Post -Uri $url -Headers $headers -Body @{
        '@odata.id' = "https://graph.microsoft.com/v1.0/devices(deviceId='$deviceId')"
    }