Powershell 修复try/catch和输出

Powershell 修复try/catch和输出,powershell,active-directory,Powershell,Active Directory,我正在向组中添加用户OU,并希望捕获: 用户添加 已在列表中的用户 将上述内容输出到一个文件 以下当前代码工作并输出: UserName GroupName TimeStamp -------- --------- --------- %Username% %groupname%

我正在向组中添加用户OU,并希望捕获:

  • 用户添加
  • 已在列表中的用户
  • 将上述内容输出到一个文件
  • 以下当前代码工作并输出:

    UserName GroupName TimeStamp -------- --------- --------- %Username% %groupname% 14/10/2019 15:50:49 我对添加ADGroupMember的
    不太清楚。区分用户名而不是
    $userName
    有关系吗

    我希望输出显示不起作用的
    捕获

    我在这两个语句中都使用了
    -Credential$cred
    ,有没有更简单的方法让一切都以
    -Credential
    作为会话而不是整洁的命令运行


    阅读并理解回复。 我运行脚本。用户已经在组中了,所以我希望他们都会以“用户已经是组的成员…”的形式返回,但这似乎是错误的

    最新更新后的错误消息(该组中已有许多成员):

    输出CSV不正确,因为没有添加用户,他们已经在其中。所以结果是错误的:

    UserName    GroupName   TimeStamp           Status
    TheUser     GROUPSActual    16/10/2019 15:23    User added successfully
    
    因此,从西奥的准则出发,我尝试了伊万的建议,但这需要很长时间:

    # I'll use the DistinghuishedName because this is always unique in the forest
    $currentMembers = Get-ADGroupMember -Identity $groupName | Select-Object -ExpandProperty DistinghuishedName
    
    $results = Get-ADUser -Filter * -SearchBase $ou -credential $cred | ForEach-Object {
    
        # test if the user is already a member by checking the array
    
    If ((Get-ADGroupMember -Identity $groupname).distinguishedName -contains $_.distinguishedName) {
        Write-Warning "User $userName is already a member of group $groupName"
    }
    else { 
        Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
    }
            # output a PsCustomObject that gets collected in the $results variable
            [PsCustomObject]@{
                'UserName'  = $_.Name
                'GroupName' = $groupName
                'TimeStamp' = Get-Date
                'Status'    = $status
        }
    }
    
    我认为这是可行的,但需要几分钟才能得到7个结果中的3个,而原始代码只需几秒钟。 编辑:代码已完成,并已写入宿主警告。我知道我可以调整状态部分,将错误添加到状态。不应该花这么长时间

    时间戳相隔几秒,但现在:

    TimeStamp
    16/10/2019 16:12
    16/10/2019 16:14
    16/10/2019 16:15
    16/10/2019 16:16
    16/10/2019 16:17
    16/10/2019 16:18
    16/10/2019 16:19
    

    只有当
    ErrorAction
    设置为
    Stop
    时发生错误时,才会执行
    catch
    块<当用户已经是组成员时,代码>添加ADGroupMember
    不会返回错误

    我建议在try块中的脚本中使用某种逻辑。比如:

    If ((Get-ADGroupMember -Identity $groupname).distinguishedName -contains $_.distinguishedName) {
        Write-Warning "User $userName is already a member of group $groupName"
    }
    else { 
        Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
    }
    

    仍然可以使用
    catch
    块来处理可能发生的任何错误

    只有当
    ErrorAction
    设置为
    Stop
    时发生错误,才会执行
    catch
    块<当用户已经是组成员时,代码>添加ADGroupMember不会返回错误

    我建议在try块中的脚本中使用某种逻辑。比如:

    If ((Get-ADGroupMember -Identity $groupname).distinguishedName -contains $_.distinguishedName) {
        Write-Warning "User $userName is already a member of group $groupName"
    }
    else { 
        Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
    }
    

    仍然可以使用
    catch
    块来处理可能发生的任何错误

    虽然我从未见过
    Add ADGroupMember
    NOT引发异常
    Add ADGroupMember:指定的帐户名以前已经是组的成员,但报告说,在他的环境中,当尝试添加已经是组成员的用户时,没有任何异常

    如果在某些环境中确实如此,那么信任该异常不再是一个好主意,我们需要采取额外的步骤,首先获取组中所有当前成员的列表。
    这一额外步骤当然会导致更长的处理时间

    # Get all user objects s that are currently member of the group and capture only 
    # the usable property like SamAccountName or DistinghuishedName to use for the -Members 
    # parameter of Add-ADGroupMember.
    # the -Members parameter takes either:
    #   the DistinghuishedName
    #   the ObjectGUID
    #   the SID
    #   the SamAccountName
    
    # Use a Hasttable object for fast lookup
    $currentMembers = @{}
    Get-ADGroupMember -Identity $groupName | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object {
        # you could also use the SamAccountName, but they are only unique within the same domain.
        # I'll use the DistinghuishedName because this is always unique in the forest
        # the Value of the entry is not important, we'll only use the Key.
        $currentMembers[$_.DistinghuishedName] = $true
    }
    
    $results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
        # test if the user is already a member by checking if the lookup Hashtable has that Key
        $userName = $_.Name
        if ($currentMembers.ContainsKey($_.DistinghuishedName)) {
            Write-Host "User $userName is already a member of group $groupName"
            $status = "User $userName is already a member"
        }
        else {
            try {
                # the user is not already a member, so add him/her to the group
                Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
                $status = "User $userName added successfully"
            }
            catch {
                # something went wrong..
                $status = "User $userName could not be added to group $groupName. Error: $($_.Exception.Message)"
            }
        }
    
        # output a PsCustomObject that gets collected in the $results variable
        [PsCustomObject]@{
            'UserName'  = $userName
            'GroupName' = $groupName
            'TimeStamp' = Get-Date
            'Status'    = $status
        }
    }
    # output on console
    $results | Format-Table -AutoSize
    
    # Export to CSV file
    $results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
    

    虽然我以前从未见过
    Add ADGroupMember
    未引发异常
    Add ADGroupMember:指定的帐户名已经是组的成员
    ,但报告说,在他的环境中,当尝试添加已经是组成员的用户时,没有任何异常

    如果在某些环境中确实如此,那么信任该异常不再是一个好主意,我们需要采取额外的步骤,首先获取组中所有当前成员的列表。
    这一额外步骤当然会导致更长的处理时间

    # Get all user objects s that are currently member of the group and capture only 
    # the usable property like SamAccountName or DistinghuishedName to use for the -Members 
    # parameter of Add-ADGroupMember.
    # the -Members parameter takes either:
    #   the DistinghuishedName
    #   the ObjectGUID
    #   the SID
    #   the SamAccountName
    
    # Use a Hasttable object for fast lookup
    $currentMembers = @{}
    Get-ADGroupMember -Identity $groupName | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object {
        # you could also use the SamAccountName, but they are only unique within the same domain.
        # I'll use the DistinghuishedName because this is always unique in the forest
        # the Value of the entry is not important, we'll only use the Key.
        $currentMembers[$_.DistinghuishedName] = $true
    }
    
    $results = Get-ADUser -Filter * -SearchBase $ou | ForEach-Object {
        # test if the user is already a member by checking if the lookup Hashtable has that Key
        $userName = $_.Name
        if ($currentMembers.ContainsKey($_.DistinghuishedName)) {
            Write-Host "User $userName is already a member of group $groupName"
            $status = "User $userName is already a member"
        }
        else {
            try {
                # the user is not already a member, so add him/her to the group
                Add-ADGroupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorAction Stop
                $status = "User $userName added successfully"
            }
            catch {
                # something went wrong..
                $status = "User $userName could not be added to group $groupName. Error: $($_.Exception.Message)"
            }
        }
    
        # output a PsCustomObject that gets collected in the $results variable
        [PsCustomObject]@{
            'UserName'  = $userName
            'GroupName' = $groupName
            'TimeStamp' = Get-Date
            'Status'    = $status
        }
    }
    # output on console
    $results | Format-Table -AutoSize
    
    # Export to CSV file
    $results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation
    

    您可能希望强制将
    if
    条件作为数组计算:
    @(
    以处理组中只有一个成员的情况。您应该收到
    Add-ADGroupMember:指定的帐户名已经是组的成员
    异常。您使用的是什么操作系统?@Theo在我的实验室环境中,我无法复制任何异常消息,但我可以多次运行该命令
    Add ADGroupMember-Identity group01-Members test01
    ,并且在
    $error
    变量中未显示或存储任何错误。正确,如果我多次运行代码,我不会在我的环境中收到异常消息。我尝试使用上述代码,以及原始命令
    $currentMembers=get ADGroupMember-Identity$groupName | Select Object-ExpandProperty DistinghuishedName
    。但是脚本需要花费很长时间,您的代码是否再次运行get-adgroupmember命令?原始代码(虽然它不会报告已添加成员的失败)花费了几秒钟。现在代码需要几分钟。它似乎正在工作,但在7个用户中,它只花了10分钟,并且只成功捕获了2个已成为成员但仍在运行的用户。如果将
    条件作为数组进行计算,则可能需要强制执行
    @((Get-ADGroupMember-Identity$groupname).DifferentiedName)
    处理组中只有一个成员的情况。您应该收到
    Add AdGroupMember:指定的帐户名已经是组的成员
    异常。您使用的是什么操作系统?@Theo在我的实验室环境中,我无法复制任何异常消息,但我可以多次运行该命令
    Add ADGroupMember-Identity group01-Members test01
    ,并且在
    $error
    变量中未显示或存储任何错误。正确,如果我多次运行代码,我不会在我的环境中收到异常消息。我尝试使用上述代码,以及原始命令
    $currentMembers=get ADGroupMember-Identity$groupName | Select Object-ExpandProperty DistinghuishedName
    。但是脚本需要花费很长时间,您的代码是否再次运行get-adgroupmember命令?原始代码(虽然它不会报告已添加成员的失败)花费了几秒钟。现在代码需要几分钟。它是