How do I update a Planner task description in HTML format using PowerShell?

Users with permissions can create Planner tasks with PowerShell and Microsoft Graph. In the past, users could update a Planner task description in text format (string). Since 2022, the Planner API plannerTaskDetails contains a Notes property for an HTML description.

  • Property Description > only supports plain text.
  • Property Notes > supports HTML format.

As Microsoft describes in the documentation, these two properties are linked and should not be updated together.

notes
Rich text description of the task. To be used by HTML-aware clients. For backwards compatibility, a plain-text version of the HTML description will be synced to the “description” field. If this field hasn’t previously been set but “description” has been, the existing description is synchronized to “notes” with minimal whitespace-preserving HTML markup. Setting both “description” and “notes” is an error and will result in an exception.

Two steps are required to update the description field of a Planner task with PowerShell.

  1. Creating a Planner task
  2. Updating the description of the task

 

New Planner task with description in plain text

In the first example, I create the task with the Description property. The description of that task is in plain text.

PowerShell
Import-Module Microsoft.Graph.Authentication
Connect-MgGraph -Scopes Tasks.ReadWrite

# Prepare the body to create a new task
$Body = @"
{
    "planId": "xWXTRNFiDEuKXzpfad8EV5gAEFfk",
    "bucketId": "DvPqFQBk0E-xeopNovLVGpgAEiJv",
    "title": "Task with plain description"
}
"@

# Create a new task
$Url = "https://graph.microsoft.com/v1.0/planner/tasks"
$NewPlannerTask = Invoke-MgGraphRequest -Method  POST -Uri $Url -Body $Body -ContentType "application/json"
$NewPlannerTaskID = $NewPlannerTask.id

# Get the task details to get the latest etag value (required to update a Planner task)
$Url = "https://graph.microsoft.com/v1.0/planner/tasks/$NewPlannerTaskID/details"
$PlannerTaskDetails = Invoke-MgGraphRequest -Method GET -Uri $Url -ContentType "application/json"

# Prepare the body to update the task with a description
$MessageBody = @"
<p>This is a <strong>sample description</strong> with <em>HTML</em> content.</p>
<ul>
    <li>First item</li>
    <li>Second item</li>
    <li>Third item</li>
</ul>
<p>For more information, visit <a href='https://blog-en.topedia.com/' Target='_blank'>Topedia Blog</a>.</p>
"@

# Update the task body with the description
$Body = @{
    'previewType' = 'noPreview'
    'description' = $MessageBody
}

# Update the task with the description (in plain text)
$Url = "https://graph.microsoft.com/v1.0/planner/tasks/$NewPlannerTaskID/details"
$Header = @{ "If-Match" = $PlannerTaskDetails.'@odata.etag'  }
Invoke-MgGraphRequest -Method PATCH -Uri $Url -Body ($Body | ConvertTo-Json) -Headers $Header -ContentType "application/json"


The new task has been created. The description is an unformatted HTML format in plain text.

Planner Task mit Beschreibung in Plaintext
Planner task with description in plain text

 

New Planner task with description in HTML format

The same process for creating a task with a description in HTML format.
Important: Use the beta endpoint for the Notes property; otherwise, it will continue to create the description in plain text. The v1 endpoint does not yet support a Notes property.

PowerShell
# Prepare the body to create a new task
$Body = @"
{
    "planId": "xWXTRNFiDEuKXzpfad8EV5gAEFfk",
    "bucketId": "DvPqFQBk0E-xeopNovLVGpgAEiJv",
    "title": "Task with HTML description"
}
"@

# Create a new task
$Url = "https://graph.microsoft.com/beta/planner/tasks"
$NewPlannerTask = Invoke-MgGraphRequest -Method  POST -Uri $Url -Body $Body -ContentType "application/json"
$NewPlannerTaskID = $NewPlannerTask.id

# Get the task details to get the latest etag value (required to update a Planner task)
$Url = "https://graph.microsoft.com/beta/planner/tasks/$NewPlannerTaskID/details"
$PlannerTaskDetails = Invoke-MgGraphRequest -Method GET -Uri $Url -ContentType "application/json"

# Prepare the body to update the task with a description
$MessageBody = @"
<p>This is a <strong>sample description</strong> with <em>HTML</em> content.</p>
<ul>
    <li>First item</li>
    <li>Second item</li>
    <li>Third item</li>
</ul>
<p>For more information, visit <a href='https://blog-en.topedia.com/'>Topedia Blog</a>.</p>
"@

# Update the task body with the HTML description
$Body = @{
    'previewType' = 'noPreview'
    'notes' = @{            
        'contentType' = 'html'
        'content' = $MessageBody 
    }
}

# Update the task with the description (in HTML format)
$Url = "https://graph.microsoft.com/beta/planner/tasks/$NewPlannerTaskID/details"
$Header = @{ "If-Match" = $PlannerTaskDetails.'@odata.etag'  }
Invoke-MgGraphRequest -Method PATCH -Uri $Url -Body ($Body | ConvertTo-Json) -Headers $Header -ContentType "application/json"

Disconnect-MgGraph


The second task has been created. The description is a formatted HTML format.

Planner task with description in HTML format

 

Bonus: New Planner task from Microsoft 365 Message in HTML format

The Microsoft 365 Message Center messages include an HTML format in the body. The entire body (incl. screenshots) can be added to the Planner task.

Note that the Notes property does not support some HTML attributes. For Microsoft 365 Messages, for example, one of the attributes is the attribute target=”_blank”. The API will return an error in such cases.

The request contains invalid HTML for the Notes field. [Invalid or disallowed HTML attribute or attribute value [NotAllowedAttribute]]

In my example for MC949004, I remove the attribute (if present).

PowerShell
Connect-MgGraph -Scopes Tasks.ReadWrite, ServiceMessage.Read.All

# Get the service announcement message for MC949004
$Url = "https://graph.microsoft.com/beta/admin/serviceAnnouncement/messages/MC949004"
$MCResult = Invoke-MgGraphRequest -Method Get -Uri $Url

# Prepare the body to create a new task
$TaskTitle = $MCResult.title + " - " + $MCResult.id
$Body = @"
{
    "planId": "xWXTRNFiDEuKXzpfad8EV5gAEFfk",
    "bucketId": "DvPqFQBk0E-xeopNovLVGpgAEiJv",
    "title": "$TaskTitle"
}
"@

# Create a new task
$Url = "https://graph.microsoft.com/beta/planner/tasks"
$NewPlannerTask = Invoke-MgGraphRequest -Method  POST -Uri $Url -Body $Body -ContentType "application/json"
$NewPlannerTaskID = $NewPlannerTask.id

# Get the task details to get the latest etag value (required to update a Planner task)
$Url = "https://graph.microsoft.com/beta/planner/tasks/$NewPlannerTaskID/details"
$PlannerTaskDetails = Invoke-MgGraphRequest -Method GET -Uri $Url -ContentType "application/json"

# Remove an unsupported HTML attribute from the message body
$MessageBody = $MCResult.body.content 
$MessageBody = $MessageBody -replace 'target="_blank"', ""

# Prepare the body to update the task with a description
$Body = @{
    'previewType' = 'noPreview'
    'notes' = @{            
        'contentType' = 'html'
        'content' = $MessageBody
    }
}

# Update the task with the description (in HTML format)
$Url = "https://graph.microsoft.com/beta/planner/tasks/$NewPlannerTaskID/details"
$Header = @{ "If-Match" = $PlannerTaskDetails.'@odata.etag'  }
Invoke-MgGraphRequest -Method PATCH -Uri $Url -Body ($Body | ConvertTo-Json) -Headers $Header -ContentType "application/json"

Disconnect-MgGraph


The third task was created, and the description is in HTML format.

Microsoft Message im HTML-Format
Microsoft Message in HTML format
Share
Avatar photo

Tobias Asböck

Tobias is a Senior System Engineer with around ten years of professional experience with Microsoft 365 products such as SharePoint Online, OneDrive for Business, Teams Collaboration, Entra ID, Information Protection, Universal Print, and Microsoft 365 Licensing. He also has 15+ years of experience planning, administering, and operating SharePoint Server environments. Tobias is a PowerShell Scripter with certifications for Microsoft 365 products. In his spare time, Tobias is busy with updates in the Microsoft 365 world or on the road with his road bike and other sports activities. If you have additional questions, please contact me via LinkedIn or [email protected].

Leave a Reply

Your email address will not be published. Required fields are marked *