An API that connects multiple Microsoft services, enabling data access and automation across platforms
After additional debugging and troubleshooting, I figured this out. Due to data security, I had to strip out part of the filter that was being used because I'm lazy and didn't want to manually sanitize it. Below is a sanitized version of the actual filter that was being passed to the endpoint:
$filter = "status/errorCode eq 0 and signInEventTypes/any(t:t eq 'interactiveUser' or t eq 'nonInteractiveUser') and contains(UserDisplayName, 'Bob Smith') or contains(UserDisplayName, 'John Smith') or contains(UserDisplayName, 'Jack Smith') or contains(UserDisplayName, 'Jill Smith') and createdDateTime ge $utcStart and createdDateTime le $utcEnd"
The crux of the issue has to do with logical grouping and operator precedence. Basically, UserDisplayName queries needed to be encapsulated:
$filter = "status/errorCode eq 0 and signInEventTypes/any(t:t eq 'interactiveUser' or t eq 'nonInteractiveUser') and (contains(UserDisplayName, 'Bob Smith') or contains(UserDisplayName, 'John Smith') or contains(UserDisplayName, 'Jack Smith') or contains(UserDisplayName, 'Jill Smith')) and createdDateTime ge $utcStart and createdDateTime le $utcEnd"
This is visually intuitive with the following formatting:
status/errorCode eq 0
and signInEventTypes/any(t:t eq 'interactiveUser' or t eq 'nonInteractiveUser')
and (
contains(UserDisplayName, 'Bob Smith')
or contains(UserDisplayName, 'John Smith')
or contains(UserDisplayName, 'Jack Smith')
or contains(UserDisplayName, 'Jill Smith')
)
and createdDateTime ge $utcStart
and createdDateTime le $utcEnd