1

I am trying to write a PowerShell script that allows me to update all the names of our devices in Intune [430ish devices] to reflect our asset tags. When they were imported into our tenant, they were given the serialNumber of the device as their deviceName. All permissions for the API have been applied:

API Permissions:
Device Read
Device Read all
DeviceManagementApps.ReadAll
DeviceManagementApps.ReadWriteAll
DeviceManagementConfiguration.ReadAll
DeviceManagementConfiguration.ReadWriteAll
DeviceManagementManagedDevices.PrivilegedOperations.All
DeviceManagementManagedDevices.ReadAll
DeviceManagementManagedDevices.ReadWriteAll
DeviceManagementRBAC.ReadAll
DeviceManagementRBAC.ReadWriteALL
DeviceManagementServiceConfig.ReadAll
DeviceManagementServiceConfig.ReadWriteAll
User Read

This is the code as far as I can get it, but I am still getting the following error [I apologise for ugly or poorly formatted code, I have had no formal training, all learnt using google-fu!]:

# Setting variables for connecting to the MS API 
$ApplicationID = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
$TenantDomainName = "contoso.com"
$AccessSecret = Read-Host "Enter Secret"

# Connect to MSGraph command to run
Connect-MSGraph

# Setting the body of the json
$Body = @{    
Grant_Type    = "client_credentials"
Scope         = "https://graph.microsoft.com/.default"
client_Id     = $ApplicationID
Client_Secret = $AccessSecret
} 

# Authenticating the connection to MSGraph
$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantDomainName/oauth2/v2.0/token" `
-Method POST -Body $Body

$token = $ConnectGraph.access_token

# Importing the CSV of device information
$csvfile = "C:\<Path to file>"
Import-Csv $csvfile | ForEach-Object {
    $serialNumber = $_.serialNumber;
    $tag = $_.tag;
    $deviceId = $serialNumber
    Write-Host "Renaming machine from: $deviceID to: $tag" -ForegroundColor Cyan

    # Getting the Device from the CSV and then putting it into MSGraph compatible Json
    $DeviceToRename = Get-IntuneManagedDevice -Filter ("serialNumber eq '$serialNumber'")
        Foreach ($Device in $DeviceToRename) {
                $Resource = "deviceManagement/managedDevices('$DeviceId')/setDeviceName"
                $graphApiVersion = "Beta"
                $uri = "https://graph.microsoft.com/beta/deviceManagement/managedDevices/executeAction"

#This JSON format doesnt work
#    $JSONPayload = @"
#    {  <NEW>
#        "body":  <NEW>
#        {
#            action: "setDeviceName",
#            actionName: "setDeviceName",
#            deviceName: "$tag",
#            realaction: "setDeviceName",
#            restartNow: false
#       }
#    }  <NEW>
#"@

  #Don't know if this works properly either?
    $JSONPayload = @"
        {
           "@odata.type": "#microsoft.graph.managedDevice",
           "actionName": "setDeviceName",
           "deviceName": "$tag"
        }
"@

# Writing out to check if this is working correctly
Write-Host $JSONPayload

# Converting $JSONPayload to an actual workable JSON
$convertedJSON = ConvertTo-Json $JSONPayload

try {
    Invoke-MSGraphRequest -Url $uri -HttpMethod PATCH -Body $JSONPayload -ContentType "application/Json"  -Verbose
} catch {
    # Dig into the exception to get the Response details.
    Write-Host "StatusCode:" "$_.Exception.Response.StatusCode.value__" 
    Write-Host "StatusDescription:" "$_.Exception.Response.StatusDescription"
    Write-Host "StatusCode2:" "$_.ErrorDetails.Message"
        }
     }
}

Error response:

StatusCode: A parameter cannot be found that matches parameter name 'Body'..Exception.Response.StatusCode.value__
StatusDescription: A parameter cannot be found that matches parameter name 'Body'..Exception.Response.StatusDescription
StatusCode2: A parameter cannot be found that matches parameter name 'Body'..ErrorDetails.Message

Thanks

Tom

Tom-D
  • 11
  • 2

2 Answers2

0

I had similar problems some months ago manipulating intune devices from an powershell runbook over graph. In my case the json body was the problem. I had to define the body first as hashtable and then convert it to json. Try something like this:

# JSONPayload as hashtable instead of string
$JSONPayload = @{
    "@odata.type" = "#microsoft.graph.managedDevice"
    "actionName" = "setDeviceName"
    "deviceName" = "$tag"
}

# Writing out to check if this is working correctly
$JSONPayload

# Converting $JSONPayload to an actual workable JSON
$convertedJSON = $JSONPayload | ConvertTo-Json

And then pass the $convertedJSON to your graph call as body:

Invoke-MSGraphRequest -Url $uri -HttpMethod POST -Content $convertedJSON -Verbose

EDIT: You are calling the endpoint /deviceManagement/managedDevices/executeAction with the http method PATCH. According to this ms docs article you have to call the endpoint with the http method POST.

fabrisodotps1
  • 117
  • 1
  • 10
  • Firstly, thank you very much for taking the time to respond! The current write-host $JSONPayload is ``` System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry ``` With the same issue about the -Body not being a parameter that can be used. I am wondering if I am using the correct Invoke? – Tom-D Apr 11 '22 at 14:24
  • `Write-Host` is to print out strings. As `$JSONPayload` is a hashtable I've removed the `Write-Host` part to write out the HT content. Further I checked the `Invoke-MSGraphRequest` cmdlet. `-ContentType` does not exist (removed). `-Body` does not exist (changed to `-Content`). And I found this article which covers exactly your case: https://msendpointmgr.com/2020/03/02/how-to-rename-windows-10-devices-in-intune-using-powershell/ (I hope this will help) – fabrisodotps1 Apr 12 '22 at 07:36
  • 1
    Thanks again for taking the time to respond! I had seen this script early on in my research for this, and couldn't work out how I could apply this to my already pre-defined assettags that we have already stuck on the laptops. However using `-Content` could be the resolution I need, thank you! – Tom-D Apr 13 '22 at 08:14
  • You're welcome @Tom-D , let me know if it works with `-Content` :) – fabrisodotps1 Apr 14 '22 at 07:22
  • Unfortunately not, I am pretty sure that I am doing something very wrong. I have managed to get the devices in AAD to be renamed, albeit one at a time, however trying to get this working for intune devices seems to be elusive! – Tom-D Apr 14 '22 at 09:29
0

I am currently testing this for a customer, will post back with my results.

This assumes you know how to create an azure app registration, if not see this article: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

I am using API to get a list of autoPilotdevices:

$autoPilotUri ="https://graph.microsoft.com/v1.0/deviceManagement/windowsAutopilotDeviceIdentities"

$AutoPilotInventory = ( Invoke-GraphRequest -Uri $autoPiloturi -Method Get -Headers $header -ContentType "application/json" -ErrorAction Stop )

Loop through inventory (you'll need to set the new name etc.):

foreach ($device in $AutoPilotInventory | where-object {$_.enrollmentState -eq "enrolled"}) { 

$mgdDevice = Get-MgDeviceManagementManagedDevice -managedDeviceId $device.managedDeviceId

$updatedName = $someNewNamingcovention

Set-MgDeviceManagementManagedDeviceName -managedDeviceId $device.managedDeviceId -DeviceName $updatedName  
}

Update: This worked. Renamed Intune, AutoPilot, AzureAD device name(s). it does require a reboot of the device, to show the updated name in the portal. The job will show completed, but name will not update until the device is restarted which makes sense.

SPGrinch
  • 1
  • 1