microsoftgraph / msgraph-sdk-powershell

Powershell SDK for Microsoft Graph
https://www.powershellgallery.com/packages/Microsoft.Graph
Other
711 stars 172 forks source link

Update-MgPlannerTaskDetail not attaching a file to the task #2322

Closed davetustin closed 1 year ago

davetustin commented 1 year ago

Describe the bug When using the Update-MgPlannerTaskDetail to update the task references with a file saved in SharePoint, the file is not attached to the task.

I am able to attach files to a task using the RestAPI. Nothing is returned after the Update-MgPlannerTaskDetail command has run.

The task is being created, the file is being downloaded and uploaded to SharePoint and I am fetching the etag from the planner task details object.

To Reproduce Steps to reproduce the behavior:

  1. Update-MgPlannerTaskDetail -PlannerTaskId $taskDetail.Id -BodyParameter $params -IfMatch $taskDetail.AdditionalProperties.'@odata.etag'

Expected behavior The file is attached to the task

Debug Output DEBUG: [CmdletBeginProcessing]: - Update-MgPlannerTaskDetail begin processing with parameterSet 'Update'. DEBUG: [Authentication]: - AuthType: 'AppOnly', TokenCredentialType: 'ClientCertificate', ContextScope: 'Process', AppName: 'Lender Updates Automation'. DEBUG: [Authentication]: - Scopes: [Mail.ReadWrite, Directory.ReadWrite.All, Sites.ReadWrite.All, Group.Create, Group.ReadWrite.All, Tasks.Read.All, Tasks.ReadWrite.All].

DEBUG: ============================ HTTP REQUEST ============================

HTTP Method: PATCH

Absolute Uri: https://graph.microsoft.com/v1.0/planner/tasks/AHySj4RgeUqXdROPWY1FzpgAHiH7/details

Headers: If-Match : W/"JzEtVGFza0RldGFpbHMgQEBAQABEQEBAQEBAQEBARCc=" FeatureFlag : 00000043 Cache-Control : no-store, no-cache User-Agent : Mozilla/5.0,(Windows NT 10.0; Microsoft Windows 10.0.22621; en-GB),PowerShell/2023.6.0 Accept-Encoding : gzip SdkVersion : graph-powershell/2.6.1 client-request-id : 9c895bc4-7a1b-4aff-9f5c-b583c1c987a7

Body: { "references": { "@https://4tlw7y.sharepoint.com/sites/casemanagers2/Shared%20Documents/T7uSocPUdLboAAACumcJAAA=.eml": { "previewPriority": " !", "@odata.type": "microsoft.graph.plannerExternalReference", "type": "Email", "alias": "Documentation" } } }

DEBUG: ============================ HTTP RESPONSE ============================

Status Code: NoContent

Headers: Cache-Control : no-cache Strict-Transport-Security : max-age=31536000 request-id : 18f19662-1dcd-461a-8500-f0c170d1446c client-request-id : 9c895bc4-7a1b-4aff-9f5c-b583c1c987a7 x-ms-ags-diagnostic : {"ServerInfo":{"DataCenter":"UK South","Slice":"E","Ring":"3","ScaleUnit":"000","RoleInstance":"LN2PEPF0000669F"}} X-ProxyCluster : neu-002.tasks.osi.office.net X-OfficeCluster : neu-002.tasks.osi.office.net X-Tasks-CorrelationId : 87076d66-e04b-4d60-8050-7a9731bf3b90 Date : Mon, 25 Sep 2023 10:49:09 GMT

Body:

DEBUG: [CmdletEndProcessing]: - Update-MgPlannerTaskDetail end processing.

Module Version Script 2.6.1 Microsoft.Graph.Authentication {Add-MgEnvironment, Connect-MgGraph, Disconnect-MgGraph, Get-MgContext…} Script 2.6.1 Microsoft.Graph.Files {Add-MgDriveListContentTypeCopy, Add-MgDriveListContentTypeCopyFromContentTypeHub, Add-MgShareListContentTypeCopy, Add-MgShareListContentTypeCopyFromConte… Script 2.6.1 Microsoft.Graph.Groups {Add-MgGroupDriveListContentTypeCopy, Add-MgGroupDriveListContentTypeCopyFromContentTypeHub, Add-MgGroupFavorite, Add-MgGroupSite…} Script 2.6.1 Microsoft.Graph.Mail {Get-MgUserInferenceClassification, Get-MgUserInferenceClassificationOverride, Get-MgUserInferenceClassificationOverrideCount, Get-MgUserMailFolder…}
Script 2.6.1 Microsoft.Graph.Planner {Get-MgGroupPlanner, Get-MgGroupPlannerPlan, Get-MgGroupPlannerPlanBucket, Get-MgGroupPlannerPlanCount…} Script 2.6.1 Microsoft.Graph.Sites {Add-MgSite, Add-MgSiteContentTypeCopy, Add-MgSiteContentTypeCopyFromContentTypeHub, Add-MgSiteListContentTypeCopy…} Script 2.6.1 Microsoft.Graph.Users {Get-MgUser, Get-MgUserCount, Get-MgUserCreatedObject, Get-MgUserCreatedObjectAsServicePrincipal…} Script 2.6.1 Microsoft.Graph.Users.Actions {Add-MgUserChatMember, Add-MgUserDriveListContentTypeCopy, Add-MgUserDriveListContentTypeCopyFromContentTypeHub, Clear-MgUserChatMessageReaction…}

Environment Data PSVersion 7.3.7 PSEdition Core GitCommitId 7.3.7 OS Microsoft Windows 10.0.22621 Platform Win32NT PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…} PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0

Additional context

$params = @{
    planId = $plan.Id
    bucketId = $bucket.Id
    title = "Update from $($lender.Name)"
    startDateTime = Get-Date -Format "o"
    details = @{
        previewType = "description"
        description = "Case Reference: $($matches[0])"
    }
    appliedCategories = @{
        category4 = $true
    }
    assignments = @{
        $userId = @{
            "@odata.type" = "#microsoft.graph.plannerAssignment"
            orderHint = " !"
        }
    }
}
$task = New-MgPlannerTask -BodyParameter $params
$taskDetail = Get-MgPlannerTaskDetail -PlannerTaskId $task.Id

$emailName = "$($email.Id.Substring($email.Id.Length - 24)).eml"
$emlFile = "$($workingDir)\$($emailName)"

# download email
Get-MgUserMessageContent -UserId $lender.Id -MessageId $email.Id -OutFile $emlFile

# upload email to sharepoint
$file = Set-MgDriveItemContent -DriveId $defaultDrive.Id -DriveItemId "root:/$($emailName):" -InFile $emlFile

# attach email to planner task.
$params = @{
    references = @{
        "@$($file.WebUrl)" = @{
            "@odata.type" = "microsoft.graph.plannerExternalReference"
            alias = "Documentation"
            previewPriority = " !"
            type = "Other"
        }
    }
}  
Update-MgPlannerTaskDetail -PlannerTaskId $taskDetail.Id -BodyParameter $params -IfMatch $taskDetail.AdditionalProperties.'@odata.etag' -Debug
SeniorConsulting commented 1 year ago

Hi DaveTustin,

Reading through the Graph documentation, it sounds like your URL will need to be encoded: https://learn.microsoft.com/en-us/graph/api/resources/plannerexternalreferences?view=graph-rest-1.0#properties

The thing I'm a little perplexed about is that apparently percentage (%) is not allowed within open types, yet it forms the basis of URL encoding - and is even included in the example. "https%3A//contoso%2Esharepoint%2Ecom/teams/agile/documents/AnnualReport%2Epptx"

I would recommend at least having a go at manually encoding the URL, and then seeing whether that works, then there are a few other articles in this project which talk about dynamically encoding URLs.

Looking at your debug output, it's likely to be the colon present at http:// and potentially full stop/period just before eml.

davetustin commented 1 year ago

Hi SeniorConsulting,

Thanks for reaching out, I really appreciate it. This issue is starting to drive me insane! Ha

Encoding the URL is a really good shout and something I haven't tried. Unfortunately I still get the same outcome when I encode it manually. The URL is below. I really hoped that was the answer.

https%3A//4tlw7y%2Esharepoint%2Ecom/sites/casemanagers2/Shared%20Documents/AAMkADBiN2E2MGRmLTJjMDYtNDEwZi04NmVkLTRlMjNjOGRjYTU2OABGAAAAAABsvRQhcTAZQ6UEXrjdYCVZBwABhM7NWjAVT7uSocPUdLboAAAAAAEMAAABhM7NWjAVT7uSocPUdLboAAACumcMAAA=/email%2Eeml

For reference, this is the code for doing it using the RestAPI directly. I was able to attach the file to the task using it.

$etag = $task.'@odata.etag' -replace "W/`"", "" -replace "`"", ""

$headers = @{
    "Authorization" = "Bearer $($authToken.AccessToken)"
    "Content-type"  = "application/json"
    "Prefer"        = "return=representation" 
    "If-Match"      = "W/`"$($etag)`""
}
$body = @{
    previewType = "noPreview"
    references = @{
        "@$($file.WebUrl)" = @{
            "@odata.type" = "microsoft.graph.plannerExternalReference"
            alias = "Presentation"
            previewPriority = " !"
            type = "PowerPoint"
        }
    }
} |  ConvertTo-Json

$apiUri = "https://graph.microsoft.com/v1.0/planner/tasks/$($task.Id)/details"

Invoke-RestMethod -Headers $headers -Uri $apiUri -Body $body -Method PATCH

The $etag code is probably not required but at the time I was having issues with it being invalid. I have kept it for transparency.

SeniorConsulting commented 1 year ago

Dang, I had hope that'd work too

I'll come back to this one when I get time. Out of curiosity, have you tried using the similar cmdlet (which manages headers and stuff for you): Invoke-MgGraphRequest (or its aliases Invoke-GraphRequest/Invoke-MgRestMethod)?

It might help you get a little closer to where you want to be. I intend to come back and look at this, should anyone else not have any answers for you.

davetustin commented 1 year ago

Sorry, I have been busy the last few days, so haven't been able to look into it.

I was able to attach the files to the task using Invoke-MgRestMethod and I nearly stopped there, but instead I gave Update-MgPlannerTaskDetail another shot and I was able to get it to work using the code below.

$taskDetail = Get-MgPlannerTaskDetail -PlannerTaskId $task.Id
$encodedURL = $file.WebUrl -replace "://", "%3A//" -replace "\.", "%2E"

$params = @{
    references = @{
        $encodedURL = @{
            "@odata.type" = "microsoft.graph.plannerExternalReference"
            alias = $file.Name
            type = "Other"
        }
    }
}
Update-MgPlannerTaskDetail -PlannerTaskId $taskDetail.Id -BodyParameter $params -IfMatch $taskDetail.AdditionalProperties.'@odata.etag'

I think it was unhappy with URL encoding, which I did with a replace, but because it wasn't throwing an exception it was difficult to troubleshoot.

Anyway, life can now go on! I really appreciate your help @SeniorConsulting and I hope these details help someone else in the future.