Powershell 修复try/catch和输出
我正在向组中添加用户OU,并希望捕获:Powershell 修复try/catch和输出,powershell,active-directory,Powershell,Active Directory,我正在向组中添加用户OU,并希望捕获: 用户添加 已在列表中的用户 将上述内容输出到一个文件 以下当前代码工作并输出: UserName GroupName TimeStamp -------- --------- --------- %Username% %groupname%
不太清楚。区分用户名而不是$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命令?原始代码(虽然它不会报告已添加成员的失败)花费了几秒钟。现在代码需要几分钟。它是