修复try / catch并输出

时间:2019-10-14 15:00:21

标签: powershell active-directory

我要将一个用户单位OU添加到组中,并希望捕获:

  1. 已添加用户
  2. 已经在列表中的用户
  3. 将以上内容输出到文件

下面的当前代码可以工作并输出:

UserName              GroupName                          TimeStamp
--------              ---------                          ---------
%Username%            %groupname%                        14/10/2019 15:50:49

但是,catch不会捕获该组中已经存在的用户并在控制台上报告输出。导出到CSV文件仅包含OU中的所有用户,并显示其添加时间。

我希望catch输出在屏幕上触发,并在导出的CSV文件中有某种方式来显示是否已添加用户或在此运行中添加了用户。

我正在使用的代码:

$groupName = 'SOMEGROUP'
$ou = 'OU=Users,DC=DC,DC=LOCAL'
$cred = Get-Credential -Credential bsg\myusername$

$results = Get-ADUser -Filter * -SearchBase $ou -Credential $cred | ForEach-Object {
    #Add the user to the group here
    $userName = $_.Name
    try {
        Add-ADGroupMember -Identity $groupName -Members $_.DistinguishedName -Credential $cred -ErrorAction Stop
    } catch {
        Write-Warning "User $userName is already a member of group $groupName"
    }

    # output a PsCustomObject that gets collected in the $results variable
    [PsCustomObject]@{
        'UserName'  = $userName
        'GroupName' = $groupName
        'TimeStamp' = Get-Date
    }
}

# output on console
$results | Format-Table -AutoSize

# Export to CSV file
$results | Export-Csv C:\PS\AddADGroupToUsers.csv -NoTypeInformation

Read-Host -Prompt "Press Enter to exit"

我不确定Add-ADGroupMember。那里的DistingushedName而不是$userName无关紧要吗?

我希望输出显示无法正常工作的catch

我在两个语句上都使用了-Credential $cred,是否有一种更简单的方法来使所有内容以-Credential作为会话运行,而不是为了整洁而使用命令?


回复阅读并理解。 我运行了脚本。用户已经在组中,因此我希望他们全部回来,因为“用户已经是组…的成员。”但是相反,这似乎是错误的。

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

Add-ADGroupMember : Cannot validate argument on parameter 'Members'. The argument is null, empty, or an element of the
argument collection contains a null value. Supply a collection that does not contain any null values and then try the
command again.
At C:\PS\add to usersNEW2.ps1:28 char:57
+ ... oupMember -Identity $groupName -Members $_.DistinghuishedName -ErrorA ...
+                                             ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Add-ADGroupMember], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.AddADGrou
   pMember

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

UserName    GroupName   TimeStamp           Status
TheUser     GROUPSActual    16/10/2019 15:23    User added successfully

因此,远离Theo的代码,我尝试了Ivan的建议,但这花了很长时间:

# 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

2 个答案:

答案 0 :(得分:3)

仅在将catch设置为ErrorAction时发生错误时,才执行Stop块。当用户已经是组的成员时,Add-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块来处理可能发生的任何错误。

答案 1 :(得分:0)

尽管我之前从未见过Add-ADGroupMember 抛出异常Add-AdGroupMember : The specified account name is already a member of the group,但Ivan MIrchev报告说,在他的环境中,尝试添加时没有任何异常已经是该组成员的用户。

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

# 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