powershellcharacter-encodingmicrosoft-graph-apiinvoke-restmethod

Encoding problem when generating user in Microsoft Graph


What character encoding should a POST body to /v1.0/users have?

I have problems with generating users with accented characters in the name with Microsoft Graph.

I use the following body:

{
    "accountEnabled":false,
    "displayName":"ADM Joost Müller",
    "userprincipalname":"admjmuller@mytenant.onmicrosoft.com",
    "mailNickname":"admjmuller",
    "passwordProfile":{      
        "forceChangePasswordNextSignIn":true,
        "forceChangePasswordNextSignInWithMfa":true,
        "password":"Randompasswordgenerated"
    }
}

When calling POST to /v1.0/users with the above JSON in the body I get the following object back:

@odata.context    : https://graph.microsoft.com/v1.0/$metadata#users/$entity
id                : xxxxxxxx-xxxx-xxxx-xxxx-a72a188e6d9a
businessPhones    : {}
displayName       : ADM Joost M�ller
givenName         : 
jobTitle          : 
mail              : 
mobilePhone       : 
officeLocation    : 
preferredLanguage : 
surname           : 
userPrincipalName : admjmuller@mytenant.onmicrosoft.com

Note the '�' in the displayname. This is NOT a display problem in Powershell, the Entra ID blade in the Azure portal also shows this character. I've already tried to forcibly convert the JSON to UTF-8:

$enc = [System.Text.Encoding]::UTF8
$jsonutf8 = $enc.getstring($enc.getbytes($json))

but that didn't solve the problem.

I've tried various search terms but can't find anything that points to a solution. It's probably something trivial but if it is, I'm using the wrong search terms...

The actual code:

function Encode {
  Param(
    [string]$text
  )
  $enc = [System.Text.Encoding]::Utf8
  return $enc.getstring($enc.getbytes($text))
}

function Invoke-GraphPost {
  [cmdletbinding()]
  Param(
    [parameter(Mandatory = $true)][string]$API,
    [parameter(Mandatory = $true)][string]$AccessToken,
    [parameter(Mandatory = $true)]$body,
    [parameter(Mandatory = $false)][string]$Apiversion = "v1.0"
  )
  $header = @{
    Authorization  = ("Bearer {0}" -f $AccessToken)
    'Content-Type' = 'application/json; charset=utf-8'
  }
  $bodyjson = Encode(ConvertTo-Json -InputObject $body -Compress)
  $URI = Encode(("https://graph.microsoft.com/{0}/{1}" -f $Apiversion, $API))
  try {
    $result = Invoke-RestMethod -Uri $URI -Method Post -Body $bodyjson -Headers $header
  }
  catch {
    $FailMessage = ("Unable to create graph POST request {0} with body {1}" -f $URI, $bodyjson)
    $module.failjson($FailMessage)
  }
  return $result
}

      $password = [System.Web.Security.Membership]::GeneratePassword(12, 4)
      $upnbase = New-EntraUserName -NameFormat "$adminprefix$format" -Voornaam $User.Roepnaam -Infix $User.Voorv_gebnaam -Achternaam $User.Geboortenaam -Domainname $admindomain
      $body = @{
        accountEnabled    = $false
        displayName       = ("ADM {0} {1}" -f $User.Roepnaam.Trim(), $User.Volledige_achternaam.Trim())
        mailNickname      = $upnbase
        userprincipalname = ("{0}@{1}" -f $upnbase, $admindomain)
        passwordProfile   = @{
          forceChangePasswordNextSignIn        = $true
          forceChangePasswordNextSignInWithMfa = $true
          password                             = $password
        }
      }
$newuser = Invoke-GraphPost -API users -AccessToken $token.access_token -body $body

where New-EntraUserName generates a unique username based on givenname, infix and surname (that exact code is irrelevant for the problem, for Joost Müller, the generated username is admjmuller, so without accent).

Joost


Solution

  • Your request body is not being submitted with the expected UTF-8 character encoding, for the following reasons:


    Solutions: