I imported a CSV into a variable containing several columns, including an ownerId column with valid Microsoft Entra ID user GUIDs. I want to loop through the rows and look up each user with Microsoft Graph PowerShell, but both of these approaches produce errors such as "Id cannot be a string" or an invalid filter clause:
foreach ($row in $wbs) {
Get-MgUser -UserId $row.ownerId
}
Get-MgUser -Filter "id eq '$wbs.ownerId'"
The filter attempt sometimes reports that a value looks like a DateTimeOffset. Can Get-MgUser accept a variable or a property from an imported CSV, and what is the correct syntax for the loop and filter?
2 Answers
Get-MgUser can accept a variable as long as it contains one user ID string. Since the CSV variable is a collection of row objects, loop through the rows and access the property on each row:
foreach ($row in $wbs) {
$ownerId = [string]$row.ownerId
Write-Output "Looking up: [$ownerId]"
Get-MgUser -UserId $ownerId
}
Alternatively, loop directly over the property values:
foreach ($ownerId in $wbs.ownerId) {
Get-MgUser -UserId ([string]$ownerId)
}
The important distinction is that `$wbs` is the collection, while `$row.ownerId` or `$wbs.ownerId` is the actual value to send to Graph.
For a filter, PowerShell does not expand an object property inside a double-quoted string unless you wrap the expression in `$()`. Also, `$wbs.ownerId` may contain multiple values, so it is not appropriate as one filter value:
foreach ($row in $wbs) {
$id = [string]$row.ownerId
Get-MgUser -Filter "id eq '$id'"
}
or:
foreach ($row in $wbs) {
Get-MgUser -Filter "id eq '$($row.ownerId)'"
}
Using `-UserId` is simpler when you already have the GUID. The DateTimeOffset error usually means the expression is resolving to the wrong CSV field or to an entire row/object instead of the intended ownerId value. Print the value and its type before calling Graph to verify it.
A quick diagnostic is `Write-Host "[$($row.ownerId)] - $($row.ownerId.GetType().FullName)"`. That makes it obvious if the column name is wrong, the value is empty, or the loop is passing the whole imported row.

The data is loaded with Import-Csv, so each item in the collection is a row containing several columns. I was looping over the entire row object rather than selecting the ownerId property.