msgraph-sdk-powershell icon indicating copy to clipboard operation
msgraph-sdk-powershell copied to clipboard

URLencode seems to cause issues with filters

Open michevnew opened this issue 3 years ago • 4 comments

Here's a filter that works perfectly fine with Graph explorer:

GET https://graph.microsoft.com/beta/users?$filter=assignedPlans/any(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)&$count=true (advanced query, so needs the ConsistencyLevel header)

image

Same request works fine with direct Graph query as well:

$uri = "https://graph.microsoft.com/beta/users?`$filter=assignedPlans/any(c:ServicePlanId eq 57ff2da0-773e-42df-b2af-ffb7a2317929)&`$count=true"
Invoke-WebRequest -Headers $AuthHeader1 -Uri $uri -Verbose -Debug

Trying to run the same in the SDK results in "Get-MgUser_List: Invalid filter clause" error.

Get-MgUser -Filter 'assignedPlans/any(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)' -ConsistencyLevel Eventual -CountVariable count -Verbose -Debug
DEBUG: [CmdletBeginProcessing]: - Get-MgUser begin processing with parameterSet 'List'.
DEBUG: [Authentication]: - AuthType: 'Delegated', AuthProviderType: 'InteractiveAuthenticationProvider', ContextScope: 'CurrentUser', AppName: 'Microsoft Graph PowerShell'.
DEBUG: [Authentication]: - Scopes: [AuditLog.Read.All, DeviceManagementServiceConfig.Read.All, Directory.AccessAsUser.All, Directory.Read.All, email, Group.Read.All, Mail.Read, Mail.ReadWrite, OnlineMeetingArtifact.Read.All, OnlineMeetings.Read, openid, profile, Sites.Read.All, User.Read, User.Read.All, User.ReadWrite.All].
DEBUG: ============================ HTTP REQUEST ============================

HTTP Method:
GET

Absolute Uri:
https://graph.microsoft.com/beta/users?$filter=assignedPlans%2Fany%28c%3AServicePlanId%2Beq%2B57ff2da0-773e-42df-b2af-ffb7a2317929%29&$count=true

Headers:
ConsistencyLevel              : Eventual

Looking at the above, the URLencode seems to be causing the issue. Specifically, replacing the space (or "+") sign within the lambda operator statement. So, while this does NOT work:

https://graph.microsoft.com/beta/users?$filter=assignedPlans%2Fany%28c%3AServicePlanId%2Beq%2B57ff2da0-773e-42df-b2af-ffb7a2317929%29&$count=true

this will:

https://graph.microsoft.com/beta/users?$filter=assignedPlans%2Fany(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)&$count=true

So the potential solution is to avoid encoding the plus sign (or spaces) within the lambda payload.

Tested on latest module version, 1.9.6

michevnew avatar Jun 22 '22 15:06 michevnew

@michevnew, -Filter expects you to pass a filter expression that is unencoded. In the example above, the filter expression being passed to -Filter is already encoded with + for space thus the error. This can be reproduced using:

➜ [System.Web.HttpUtility]::UrlEncode("assignedPlans/any(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)")
# Outputs -> assignedPlans%2fany(c%3aServicePlanId%2beq%2b57ff2da0-773e-42df-b2af-ffb7a2317929)
➜ [System.Web.HttpUtility]::UrlDecode("assignedPlans/any(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)")
# Outputs -> assignedPlans/any(c:ServicePlanId eq 57ff2da0-773e-42df-b2af-ffb7a2317929)

Please pass a decoded -Filter expression as the command already handles query parameter encoding for you:

Get-MgUser -Filter 'assignedPlans/any(c:ServicePlanId eq 57ff2da0-773e-42df-b2af-ffb7a2317929)' -ConsistencyLevel Eventual -CountVariable count -Debug

This is the same filter clause you used with Invoke-MgGraphRequest in:

$uri = "https://graph.microsoft.com/beta/users?`$filter=assignedPlans/any(c:ServicePlanId eq 57ff2da0-773e-42df-b2af-ffb7a2317929)&`$count=true"
Invoke-WebRequest -Headers $AuthHeader1 -Uri $uri -Verbose -Debug

peombwa avatar Jun 24 '22 19:06 peombwa

We will use this issue as a feature request to track support for both encoded and decoded query parameters.

peombwa avatar Jun 24 '22 19:06 peombwa

Thanks for the explanation Peter. I suppose my complaint here is that the PowerShell SDK does not provide the same experience as either the Graph explorer or direct calls via Invoke-WebRequest/Invoke-RestMethod, all of which seem to decode the input and thus handle various permutations. If we are to use a simpler query as an example, all of the variations below work with other tools:

id eq 'fca15ab9-c964-49e5-9531-904bbd5f9160'
id+eq+'fca15ab9-c964-49e5-9531-904bbd5f9160'
id+eq+%27fca15ab9-c964-49e5-9531-904bbd5f9160%27
id eq+%27fca15ab9-c964-49e5-9531-904bbd5f9160'
id+eq 'fca15ab9-c964-49e5-9531-904bbd5f9160%27

(and similar permutations)

I realize those are different products, but it would be nice if you can improve the experience on that front. URL decoding the -Filter input should address this, I believe? Get-MgUser -Filter $([System.Web.HttpUtility]::UrlDecode("assignedPlans/any(c:ServicePlanId+eq+57ff2da0-773e-42df-b2af-ffb7a2317929)")) -ConsistencyLevel Eventual -CountVariable count -Debug

P.S. As the issue is not only with advanced queries, I've adjusted the title.

michevnew avatar Jun 24 '22 19:06 michevnew

I agree with you! The experience can be improved to match existing tools. We will work with the team that owns the code generator to resolve this.

That's right, decoding the -Filter input can be used as a work around/fix. However, the challenge with this approach is HttpUtility class is not available in PowerShell 5.1, which we support. If you are using the command in PowerShell 7+, you should be fine with using [System.Web.HttpUtility]::UrlDecode to decode the filter input.

peombwa avatar Jun 24 '22 20:06 peombwa

Closing as fixed by https://github.com/microsoftgraph/msgraph-sdk-powershell/releases/tag/2.0.0-preview6

peombwa avatar Mar 15 '23 21:03 peombwa

Hi,

What's the correct way to do it if you want to filter something that actually has a "+" sign?

I wan't to get a user by his ImmutableID. And this often has "+" signs. But this gets translated to " ":

Get-MgUser -filter "onPremisesImmutableId eq 'jcsXNJHNAUyn+8bAc+2XVg=='"

Absolute Uri:
https://graph.microsoft.com/v1.0/users?$filter=onPremisesImmutableId eq %27jcsXNJHNAUyn 8bAc 2XVg%3D%3D%27

thanordic avatar Mar 08 '24 13:03 thanordic