PowerShell函数Set-DRAUserProperty仅单次输出$Properties问题求助
问题根因
你遇到的问题由两个错误共同导致:
- 哈希表初始化位置错误
你把$Properties = @{}写在了Begin块中,整个函数运行周期内只会初始化一次。第一次处理用户Abe时已经往哈希表里添加了Company键,第二次循环处理第二个Abe时,你的逻辑会判断键已存在就直接跳过添加操作,最终两次循环操作的都是同一个哈希表对象。 - PowerShell输出默认合并表头
就算你两次输出同一个哈希表的枚举值,PowerShell默认对连续输出的同类型对象只会显示一次表头,视觉上会误以为只输出了一次,实际后台返回了两组结果,只是被合并显示了。
解决方法
- 把
$Properties的初始化逻辑移到foreach循环内部,每次处理用户都重新构建独立的哈希表,避免不同用户的属性互相干扰 - 如果需要调试时每次都显示表头,输出时直接输出完整哈希表即可,不需要调用
GetEnumerator();如果是用于后续splat传参,只要保证每次生成的哈希表独立就可以正常使用。
修正后的完整代码
Function Set-DRAUserProperty { Param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [string[]]$UserName, $Company, $Department, $Name, $O, $PhysicalDeliveryOfficeName, $TelephoneNumber, $Title ) DynamicParam { # 额外提示:此处原Split逻辑存在隐患,DynamicParam运行时参数未完全绑定,管道传参时$UserName为空 if ($UserName.Count -le 1) { $displayNameAttribute = New-Object System.Management.Automation.ParameterAttribute $displayNameAttribute.Mandatory = $false $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection.Add($displayNameAttribute) $displayNameParam = New-Object System.Management.Automation.RuntimeDefinedParameter('DisplayName', [string], $attributeCollection) $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('DisplayName', $displayNameParam) $paramDictionary } } Begin { $OrgBoxOu = "*OU=xxxxxxxxx" $Parameters = $PSBoundParameters } Process { foreach ($User in $UserName) { # 每次处理用户都初始化新的哈希表 $Properties = @{} try { $SelectedUser = Get-ADUser -Identity $User -Properties DisplayName if ($SelectedUser) { $Parameters.GetEnumerator() | Where-Object -FilterScript {$_.Key -ne 'UserName'} | ForEach-Object -Process ` { if ($_.Key -eq 'DisplayName' -and $SelectedUser.DistinguishedName -like $OrgBoxOu) { if ('FirstNamePreferred' -in $Properties.Keys) { Continue } else { $Properties.Add($_.Key, $_.Value) $Properties.Add('FirstNamePreferred', $_.Value) } } else { if ($_.Key -in $Properties.Keys) { Continue } else { $Properties.Add($_.Key, $_.Value) } } } # 直接输出哈希表,调试要强制显示表头可加 | Format-Table -Force $Properties #Set-DRAUser -Identifier $SelectedUser.DistinguishedName -Properties $Properties @DRA_Server_Splat -ErrorAction Stop } else { Write-Host -Object "No valid member selected!" } } catch { Write-Host -Object "ERROR: $($_.Exception.Message)" -ForegroundColor Red -BackgroundColor Black continue } } } End { } }
额外优化建议
你原DynamicParam块中的$UserName.Split(',').Count逻辑存在隐患:DynamicParam阶段是参数绑定前运行的,如果用户通过管道传入UserName参数,此时$UserName还未被赋值,判断逻辑会失效,建议把UserName按数组处理,直接用$UserName.Count判断即可,不需要调用Split方法。
内容的提问来源于stack exchange,提问作者Abraham Zinala
相关产品推荐
相关产品推荐

