为什么我不能将对象存储在并行 ForEach-Object 循环内的变量中?

问题描述 投票:0回答:1

我正在尝试从每个域控制器中为每个用户检索 AD 属性

LastLogon
。由于这需要大量时间,我正在尝试使用 PowerShell 7 中的
Parallel
功能

示例

$users = Get-ADUser -Filter "[filter]"
$DCs = Get-ADDomainController -Filter * | Where-Object { $_.Site -in $using:sites }

$users | ForEach-Object -ThrottleLimit 2  -Parallel {    
    $serv = $using:DCs

    foreach ($DC in $serv) {
        $lastLogonAD = Get-ADUser -Identity $_ -Properties LastLogon -Server $DC -ErrorAction Stop | Select-Object -ExpandProperty LastLogon

        $lastLogonConverted = [datetime]::FromFileTimeUTC($lastLogonAD)
    }
}

错误

Get-ADUser: 
Line |
   7 |  …        $lastLogonAD = Get-ADUser -Identity $_ -Properties LastLogon -Server  …
     |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The server has returned the following error: invalid enumeration context.

我发现,如果删除

-Server
参数,它就可以工作,或者如果我不将属性存储到变量中,它就可以工作。

删除服务器参数
    foreach ($DC in $DCs) {
        $lastLogonAD = Get-ADUser -Identity $_ -Properties LastLogon -ErrorAction Stop | Select-Object -ExpandProperty LastLogon

        $lastLogonConverted = [datetime]::FromFileTimeUTC($lastLogonAD)
    }

不存储变量

    foreach ($DC in $DCs) {
        Get-ADUser -Identity $_ -Properties LastLogon -Server $DC -ErrorAction Stop | Select-Object -ExpandProperty LastLogon

        $lastLogonConverted = [datetime]::FromFileTimeUTC($lastLogonAD)
    }
powershell active-directory powershell-7.0
1个回答
0
投票

错误“服务器返回以下错误:无效的枚举上下文。”主要是因为你的代码效率很低,这个错误发生在运行超过30分钟的查询上。请参阅 TechNet 文章 Active Directory 故障排除:服务器返回以下错误 - 枚举上下文无效

您的并行循环应该运行于每个域控制器而不是每个用户。并行调用应该处理每个运行空间的所有用户。

以下代码的作用:

  1. 获取将并行处理的
    DistinguishedName
    列表。
  2. 启动每个域控制器的并行调用,并将
    DistinguishedName
    列表传递给每个并行调用进行处理。
  3. 然后按
    DistinguishedName
    对所有结果进行分组,按
    LastLogon
    对每个组进行排序,并在每个组中选择具有最新
    LastLogon
    的用户。
  4. 最后,使用构造的“友好”属性来投影对象
    LastLogonDate
$sites = # needs to be defined here...

# only need the users `DistinguishedName` here
$users = (Get-ADUser -Filter '[filter]').DistinguishedName

# parallel loop per DC instead of per user
Get-ADDomainController -Filter * |
    Where-Object { $_.Site -in $sites } |
    ForEach-Object -Parallel {
        $using:users | Get-ADUser -Properties LastLogon -Server $_
    } |
    Group-Object DistinguishedName |
    ForEach-Object {
        $_.Group | Sort-Object LastLogon -Descending |
            Select-Object *, @{ N='LastLogonDate'; E={ [datetime]::FromFileTimeUtc($_.LastLogon) }} -First 1
    }
© www.soinside.com 2019 - 2024. All rights reserved.