当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

作者:精品下载站 日期:2024-12-14 06:49:43 浏览:16 分类:玩电脑

如何通过 Microsoft Graph PowerShell 使用 -Filter


Microsoft Graph 中使用的 -Filter 参数使你能够从 PowerShell 客户端执行服务器端结果选择。这意味着通过在命令中使用 -Filter,您可以获得在控制台中返回给您的非常具体的结果。然后可以根据您的需求报告、分析、导出或操作这些结果。

使用过滤器方法选择数据是实现所需结果的有效且高效的方法。通过仅返回您想要的结果,您可以最大限度地减少带宽使用,减少客户端资源使用,并且可以说提高了安全性。

在本教程中,我将向您展示如何在 Microsoft Graph PowerShell 中使用筛选器参数,并提供您可以自己使用的实际示例。

-过滤器与Where-Object

在我的开场白中,我提到使用 -Filter 是实现所需结果的有效方法,这是与您可能熟悉的其他排序方法(例如Where 或Where-Object)相比。

使用 -Filter 参数通常比Where 或Where-Object 命令更有效。这是因为虽然它们都可以产生相同的结果,但Where命令将首先检索完整的结果列表并在客户端过滤它们,而-Filter参数将过滤请求发送到服务器,然后查询处理后,它只会将过滤后的结果返回给客户端(您)。

这意味着,如果您的目录中有很多对象,那么在使用Where命令时,它们都将通过互联网下载到您的本地设备,然后对它们进行处理,这需要时间和资源。但是 -Filter 命令只会将过滤后的结果下载到本地设备,这使其更快、更高效。

虽然相比之下很小,但您可以在下面看到使用Where命令和-Filter参数完成相同命令所需的时间截然不同:

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

何时使用 ConsistencyLevel 和 CountVariable 参数

-一致性级别

Azure Active Directory 管理着全球呈指数级增长的大量数据。当然,这些数据存储在许多服务器上的多个服务中。更新此数据时,更新的数据必须在所有必要的系统和服务器之间复制,如果没有发生这种情况,或者如果您尝试在此复制完成之前查找数据,则结果可能不一致。为了确保使用具有高级功能的搜索功能时的一致性,需要使用 -ConsistencyLevel 参数手动定义最终一致性级别。

-计数变量

在命令中定义最终一致性时,通常需要 count 变量。然而,它的位置和要求并不那么明确……虽然检索结果计数有时很有帮助,但使用最终一致性运行命令而不使用 -CountVariable 参数将导致命令因不支持的过滤器而失败运算符或查询错误。因此,即使您不需要计数信息,您也需要在命令中定义计数变量。

ConsistencyLevel 和 CountVariable 参数说明

执行所谓的“高级查询”时,这两个参数都是必需的。高级查询的示例包括在查询中使用 not (not)、ne (not equals) 和 EndsWith (ends with) 运算符。

不幸的是,并非所有目录对象都支持使用 Microsoft Graph 的高级查询。因此,处理这些高级查询的方式是,当发出请求时,Microsoft Graph 内部的内部规则将确定它是否是高级查询。如果确定查询是高级查询,则请求将发送到称为“高级查询服务”的单独服务,然后该服务从独立的“索引存储”中检索数据,其中仅保存支持的数据。这与简单查询从中检索数据的目录存储不同。同样,对于受支持的对象,您可以使用 ConsistencyLevel 和 CountVariable 参数运行简单查询,并让高级查询服务处理该请求。

由于索引存储独立于目录存储,因此执行单向同步,仅将受支持的属性从目录存储同步到索引存储,这解释了为什么需要最终一致性级别。由于索引存储与目录存储并不真正同步,因此最终一致性可确保所做的任何新目录写入也可供高级查询服务的读取作业使用。

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

我们来看看这个动作的变化。下面我将更新用户“[email ”的 DisplayName 属性。

对于此测试,我们将专门将基本查询(未由 Microsoft Graph 中的高级规则定义的查询)定向到高级查询服务。我们通过在简单请求上指定 ConsistencyLevel 和 CountVariable 参数来实现此目的。

Update-MgUser -userid [email  -DisplayName "DisplayName Changed"

然后我将使用 Get-MgUser 命令查看是否已更新。一个查询将是基本查询并发送到休息目录服务,另一个查询将发送到高级查询服务。

#Sent to Rest Directory Service
Get-MgUser -userid [email 

#Sent to Advanced Queries Service
Get-MgUser -Filter "UserPrincipalName eq '[email '" -CountVariable CountVar -ConsistencyLevel Eventual

从下面的输出中,您可以看到我们立即从 Rest Directory Service 返回了准确的信息,但高级查询服务仍然显示 DisplayName 的旧值。

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

如果我们稍等一下并再次针对高级查询服务运行命令,您可以看到我们现在返回了准确的结果。

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

不幸的是,此测试还表明在使用高级查询服务进行 GET 请求时缺乏验证。因此,当有疑问时,您可以通过简单的查询(可能会返回更多数据)或门户网站来检查您的结果。

使用单个运算符的示例

我经常将每个过滤器查询视为一条规则,并且属性值必须与您的规则匹配才能作为屏幕上的输出返回。例如,以最简单的形式,可以使用单个运算符在过滤器查询中定义规则;该属性等于该属性,或者该属性大于该属性。让我们看一下可在查询中使用的所有可能的单个运算符。

eq(等于)

等于运算符用于查询与特定属性完全匹配的对象。例如,以下命令将查询显示名称与我定义的名称完全相同的任何用户,这当然只会返回一个结果。

Get-MgUser -Filter "UserPrincipalName eq '[email '"

ne(不等于)

不等于运算符用于查询与已定义的特定属性不完全匹配的对象。例如,以下命令将查询与我定义的内容不匹配的任何用户,这将返回许多结果。

Get-MgUser -Filter "UserPrincipalName ne '[email '" -CountVariable CountVar -ConsistencyLevel eventual 

not 和 eq(不与等于)

不和等于运算符通过仅查询特定属性与已定义内容不匹配的对象来实现与不等于相同的结果。例如,以下命令将查询与已定义的用户名不匹配的任何用户。

Get-MgUser -Filter "NOT(UserPrincipalName eq '[email ')" -CountVariable CountVar -ConsistencyLevel eventual 

in(等于集合中的值)

in 运算符将搜索属性值与集合中已定义的任何值相匹配的对象。例如,以下查询将搜索部门属性与“R&D”或“IT”匹配的任何对象。

Get-MgUser -Filter "Department in ('R&D', 'IT')"

not and in(不等于集合中的值)

not and in 运算符执行与 in 运算符相反的查询。它将查询属性与集合中定义的属性不匹配的任何对象。例如,以下查询将过滤部门属性与“R&D”或“IT”不匹配的对象。

Get-MgUser -Filter "NOT(Department in ('R&D', 'IT'))" -CountVariable CountVar -ConsistencyLevel eventual 

le(小于或等于)

小于或等于运算符将过滤属性值小于或等于查询中指定值的任何对象。例如,以下查询将筛选上次登录日期小于或等于 23-01/01 12:00:00 的所有用户。此运算符的另一个变体包括 lt(小于),它将过滤小于定义值的对象。

Get-MgUser -Filter "SigninActivity/LastSignInDateTime le 2023-01-01T12:00:00Z"

ge(大于或等于)

大于或等于运算符将过滤属性值大于或等于查询中指定值的任何对象。例如,以下查询将筛选上次登录日期大于或等于 23-01/01 12:00:00 的所有用户。 此运算符的另一个变体是 gt(大于) 它将过滤大于定义值的对象。

Get-MgUser -Filter "SigninActivity/LastSignInDateTime ge 2023-01-01T12:00:00Z"

开始于(值开始于)

startsWith 运算符将过滤属性值以特定字符串值开头的任何对象。例如,以下查询将返回 Mail 属性以单词“Dan”开头的所有对象。

Get-MgUser -Filter "startsWith(Mail, 'D')"

not 和startsWith(值不以以下方式开头)

not 和 startsWith 运算符将过滤属性值不以特定字符串值开头的任何对象。例如,以下查询将返回 Mail 属性不以单词“Dan”开头的所有对象。

Get-MgUser -Filter "not(startsWith(Mail, 'D'))" -ConsistencyLevel eventual -CountVariable CountVar -All

结束于(值结束于)

endsWith 运算符将过滤属性值以特定字符串值结尾的任何对象。例如,以下查询将返回“用户主体名称”属性以值“onmicrosoft.com”结尾的所有对象。

Get-MgUser -Filter "endsWith(UserPrincipalName, 'onmicrosoft.com')" -ConsistencyLevel eventual -CountVariable CountVar -All

not 和结束(值不以以下结尾)

not 和 endsWith 运算符将过滤属性值不以特定字符串值结尾的任何对象。例如,以下查询将返回“用户主体名称”属性不以值“onmicrosoft.com”结尾的任何对象。

Get-MgUser -Filter "not(endsWith(UserPrincipalName, 'onmicrosoft.com'))" -ConsistencyLevel eventual -CountVariable CountVar -All

包含(值包含)

contains 运算符将过滤属性值中包含特定字符串值的任何对象,无论该字符串位于属性值的开头、结尾还是中间。例如,下面的过滤器将返回其中设备名称作为工作主页的任何对象。

Get-MgDeviceManagementManagedDevice -Filter "contains(deviceName, 'Home')" 

有(财产具有价值)

has 运算符将返回在特定属性集合的值集合中具有特定值的任何对象。例如,以下过滤器将返回场景属性集合中具有字符串“ZeroTrust”的任何条件访问策略模板对象。

Get-MgIdentityConditionalAccessTemplate -Filter "scenarios has 'ZeroTrust'"

如何在单个查询中使用多个运算符

当您确实想从目录中深入挖掘和资助非常具体的信息时,在单个查询中使用多个运算符非常有用,而且也很容易做到。

例如,下面我过滤了邮件地址以“it-career.online”或“ourcloudnetwork.com”结尾的用户,此查询使用 OR 运算符。

下面我还使用了(反勾号)来包装我的代码,以便您更容易阅读。仍然可以按原样复制和粘贴。

Get-MgUser -Filter `
"endsWith(mail,'it-career.online') OR endsWith(mail,'ourcloudnetwork.com')" `
-CountVariable CountVar -ConsistencyLevel eventual

AND 运算符还可用于在单个查询中连接规则。例如,我可以使用 AND 运算符来过滤邮件地址中包含后备域以及职位为“总监”的用户。

Get-MgUser -Filter `
"endsWith(mail,'microsoft.com') AND jobtitle eq 'Director'" `
-CountVariable CountVar -ConsistencyLevel eventual

过滤原始类型的集合(Lambda 运算符)

Lambda 运算符或 Lambda 表达式用于将 Lambda 参数列表与其主体分开。基本上,运算符(任意/全部)的左侧是属性,右侧是语句。

让我们看看 Lambda 运算符查询是什么样子的:

(以下查询将筛选分配有许可证 SKU“184efa21-98c3-4e5d-95ab-d07053a96e67”的任何用户)

分配的许可证/任何( x:x/skuId eq 184efa21-98c3-4e5d-95ab-d07053a96e67)”

  • 分配的许可证= 这个是初始目标属性,该属性将包含对象或值的集合。
  • 任意 = 这个是 Lambda 运算符。任何将任何值与定义的值相匹配的方法都将返回 true。
  • x:x =这用作范围变量,它将在迭代过程中保存当前项目,同时过滤器通过循环机制进行处理。这是因为 Lambda 运算符旨在搜索属性(可以说是数组)内的项目集合。该字符使用冒号两侧的“:”不相关,您可以使用任何内容,例如 p:p、sku:sku 或 L:L。
  • skuId = 这个是初始属性数组中的一项的属性。您可以想象,由于 Microsoft 365 中使用的大多数产品可能分配了多个产品许可证,因此signedLicenses 属性自然会是一个项目数组。
  • eq = 这是匹配查询的逻辑运算符。这表明过滤器将查找属性中的任何项目,其中该项目的 SkuId 属性等于定义的值。
  • 184efa21-98c3-4e5d-95ab-d07053a96e67 = 这是 SkuId 的定义值。这是将根据过滤器属性的值进行分析的值,在本例中为 SkuId。
Get-MgUser -Filter "assignedLicenses/any(s:s/skuId eq 184efa21-98c3-4e5d-95ab-d07053a96e67)"

让我们看另一个示例,在这里我想筛选分配有 Azure Active Directory Premium Service (AADPremiumService) 计划的任何用户:

我首先要找到我想要定位的相关属性,在本例中,我将查看特定用户的AssignedPlans 属性,并展开该属性以在控制台中查看。

Get-MgUser -userid [email  -Property * | `
Select AssignedPlans -ExpandProperty AssignedPlans

这是输出:

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

您可以在上图中看到,AssignedPlans 属性包含与分配给该用户的每个服务计划相关的项目集合。并且AssignedPlans属性中的每一项都包含4个自己的属性;分配日期时间、兼容性状态、服务和服务计划 ID。我在上面强调了我们需要的信息位于“服务”列中,因此我们将使用它来创建过滤器查询。

以下是过滤器查询,它将按上面突出显示的信息进行过滤:

Get-MgUser -Filter "AssignedPlans/any(x:x/Service eq 'exchange')" `
-CountVariable CountVar -ConsistencyLevel eventual

使用 Invoke-MgGraphRequest 过滤结果

并非所有信息都可以通过其特定的 PowerShell cmdlet 找到。这是因为并非每个 API 路径都开发了用于利用 API 功能的 cmdlet。对我们来说幸运的是,身份验证模块包含非常强大的 Invoke-MgGraphRequest 命令,从根本上讲,许多 cmdlet 都是在幕后使用的。如果您想了解有关此 cmdlet 的更多信息,请查看我的教程:如何通过 PowerShell 使用 Invoke-MgGraphRequest。

由于此命令的性质,我在本教程中使用的任何运算符和过滤器查询也可以与 Invoke-MgGraphRequest cmdlet 一起使用。它的工作原理是在 URI 路径末尾定义筛选器查询,在 Microsoft Graph 剩余目录或高级查询服务中找到项目。这些查询与我上面定义的相同,并在 URI 末尾定义,并以 $filter 开头。

例如,此过滤器将查找 allowedCombinations 属性集合包含字符串“SMS”的任何项目。

$filter=allowedCombinations/any(t:t+has+'SMS')"

由于此属性与身份验证强度策略相关,因此我将将此过滤器附加到索引身份验证强度策略的 URI 路径的末尾:

$uri = "https://graph.microsoft.com/beta/identity/conditionalAccess/authenticationStrength/policies?$filter=allowedCombinations/any(t:t+has+'SMS')"

$result = Invoke-MgGraphRequest -uri $uri -Method GET -OutputType PSObject

$result.value

您可以在下面看到上述命令的预期输出:

[玩转系统] 如何通过 Microsoft Graph PowerShell 使用 -Filter

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯