我要将一个用户单位OU添加到组中,并希望捕获:
下面的当前代码可以工作并输出:
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
答案 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