这与使用 powershell 检索 AD 中每个用户的管理员名称
有类似的前提问题:在为自定义属性定义表达式值时,我们是否可以包含 try/catch 或 if 条件来处理错误和/或捕获错误详细信息以用于记录目的,而不弄乱表达式值本身?
详细信息:在下面的代码中,我们将管理器属性传递回
Get-ADUser
以检索管理器的sAMAccountName:
Start-Transcript -Path 'c:\temp\log.txt' -Force
## List of AD user objects
$OU = "OU=Users,DC=company,DC=com"
$Users = Get-ADUser -LDAPFilter '(&(objectCategory=Person)(sAMAccountName=*))' -SearchBase $OU -Properties *
## this array will make sense later...
$missingMgrs = [System.Collections.ArrayList]@()
## Defined properties through splatting:
$ChosenProperties = @{
"Property" = @(
# built-in attributes:
'Name', 'sAMAccountName', 'EmailAddress'
# custom attributes below:
@{
Label = "ManagerSAmAccountName"
Expression = {
Get-ADUser $_.Manager -Properties DisplayName |Select -Expand sAMAccountName
}
}
)
}
$Users | Select-Object @ChosenProperties
Stop-Transcript
文字摘录可能如下所示:
Name sAMAccountName EmailAddress ManagerSAmAccountName
---- -------------- ------------ ---------------------
Person One pone [email protected] managera
Person Two ptwo [email protected] managerb
>> TerminatingError(Get-ADUser): "Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again."
Person Three pthree [email protected]
>> TerminatingError(Get-ADUser): "Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again."
Person Four pfour [email protected]
Person Five pfive [email protected] managera
由于人员 3 和人员 4 没有经理,因此自定义表达式针对空经理值调用
Get-ADUser
。
我想我可以用 if 语句替换表达式,以便仅在经理存在时调用
Get-ADUser
,并进行增值,以记录哪个用户遇到此问题:
Expression = {
if ($($_.Manager.Length) -gt 0) {
Get-ADUser $_.Manager -Properties DisplayName |Select -Expand sAMAccountName
} else {
$missingMgrs.Add("$($_.Name) is missing a manager.")
}
}
最后,就在停止转录之前:
Write-Output $missingMgrs
但是,这会产生如下结果:
Name sAMAccountName EmailAddress ManagerSAmAccountName
---- -------------- ------------ ---------------------
Person One pone [email protected] managera
Person Two ptwo [email protected] managerb
>> TerminatingError(Get-ADUser): "Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again."
Person Three pthree [email protected] 0
>> TerminatingError(Get-ADUser): "Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again."
Person Four pfour [email protected] 1
Person Five pfive [email protected] managera
[...]
Person Three is missing a manager.
Person Four is missing a manager.
尽管 if/else 确实成功记录了无管理员用户,但它并没有阻止
Get-ADUser
行在这些条目上运行。此外,ManagerSAmAccountName
的表达式现在计算为递增整数,而不是 $null。
回到最初的问题:有没有办法使用 if/else 编写自定义属性,以便仅在满足 if 条件时才计算表达式的值?
谢谢!
关于:
此外,
的表达式现在计算为递增整数,而不是ManagerSAmAccountName
。$null
.Add(..)
中的 ArrayList
输出一个整数,表示添加项目的索引。要解决此问题,请将其更改为 List<T>
(请参阅代码)。
回到主要问题,我没有解释为什么您在成绩单中看到异常,特别是因为在表达式块的上下文中完全忽略终止错误:
'' | Select-Object @{ N = 'Test'; E = { throw 'hi' } }
# Test
# ----
#
我能为你提供的是不会抛出任何错误的代码,我还添加了缓存机制,这样你就不会查询已经查询过的管理器,主要是为了提高效率。
Start-Transcript -Path 'c:\temp\log.txt' -Force
$getADUserSplat = @{
LDAPFilter = '(sAMAccountName=*)'
SearchBase = 'OU=Users,DC=company,DC=com'
Properties = 'EmailAddress', 'Manager'
}
## this array will make sense later...
$missingMgrs = [System.Collections.Generic.List[string]]::new()
$managerCache = @{}
Get-ADUser @getADUserSplat | ForEach-Object {
# if `.Manager` is populated and has not yet been added to the cache
if ($_.Manager -and -not $managerCache.ContainsKey($_.Manager)) {
$managerCache[$_.Manager] = try {
($_.Manager | Get-ADUser).SamAccountName
}
catch {
# `catch` block is left empty here in case the manager's distinguishedName
# points to a deleted object.
# can also include here adding to `$missingMgrs` if needed, see below:
# $missingMgrs.Add("$($_.Exception.Message): $($_.TargetObject)")
}
}
else {
$missingMgrs.Add("$($_.Name) is missing a manager.")
}
[pscustomobject]@{
Name = $_.Name
sAMAccountName = $_.sAMAccountName
EmailAddress = $_.EmailAddress
# the `[string]` cast here avoids getting an exception if `.Manager` was null
ManagerSAmAccountName = $managerCache[[string] $_.Manager]
}
}
Stop-Transcript