【问题标题】:Replace AD attribute value with csv file header values将 AD 属性值替换为 csv 文件头值
【发布时间】:2022-01-19 09:16:03
【问题描述】:

我想根据 CSV 文件头值替换 AD 属性“userPrincipalName”值 这是 csv 文件(group.csv)包含的内容

sAMAccountName
--------------
test.user1    
test.user2    

在脚本下方

$data = Import-Csv -Path .\group.csv -Header 'sAMAccountName'
foreach($user in $data){
    Get-ADUser -Filter {sAMAccountName -eq "$($user.sAMAccountName)"} | Set-ADUser -Replace @{userPrincipalName="$($user.sAMAccountName)@RES.GROUP"}
}

这里我想用 csv 文件中的 sAMAccountName 的值替换 AD 属性“userPrincipalName”,例如 sAMAccountName@RES.GROUP

这个脚本不起作用,有人可以纠正它吗?

【问题讨论】:

  • 这个脚本不起作用.. 为什么不呢?错误信息?解释会发生什么。看起来您的 csv 已经有一个标题,那么为什么要使用参数 -Header 再次添加它呢? -Filter 应该是一个字符串,而不是一个脚本块,所以"SamAccountName -eq '$($user.sAMAccountName)'"
  • 它应该遍历csv文件中的每个“sAMAccountName”,在foreach中它应该通过过滤来获取用户,并将AD中的“userPrincipalName”属性值替换为sAMAccountName@RES.GROUP,这意味着userPrincipalName=sAMAccountName@RES.GROUP 例如它从循环中获取 test.user1 并将该用户的属性(userPrincipalName)值设置为 test.user1@RES.GROUP,这意味着 AD 中“userPrincipalName”属性的值将是“test.userPrincipalName”。用户“test.user1”的 user1@RES.GROUP”
  • 是的,您的问题很清楚您的目标是什么。我在问你你的代码是否产生错误,如果是,你需要显示它们。我还建议了两种可能的修复方法。你试过了吗?
  • 是的,先生,我尝试了您显示的那些修复程序,但没有任何反应,它没有显示错误,但同时它没有按预期工作,属性“userPrincipalName”不是替换
  • 如果我删除 -Header 'sAMAccountName' 并运行脚本,我收到此错误警告:未指定一个或多个标头。以“H”开头的默认名称已用于代替任何缺失的标题。 Get-ADUser : 无法识别搜索过滤器 At line:4 char:5 + Get-ADUser -Filter "sAMAccountName -eq '$($user.sAMAccountName)'" ... + ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Get-ADUser ], ADException + FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser

标签: powershell replace attributes get-aduser


【解决方案1】:

好的,由于您的评论显示 CSV 文件确实没有标题,我建议将代码更改为:

$data = Import-Csv -Path .\group.csv -Header 'sAMAccountName'
foreach($user in $data) {
    $adUser = Get-ADUser -Filter "SamAccountName -eq '$($user.sAMAccountName)'" -ErrorAction SilentlyContinue
    if ($adUser) {
        $newUPN = '{0}@res.group' -f $user.sAMAccountName
        $adUser | Set-ADUser -UserPrincipalName $newUPN
    }
    else {
        Write-Warning "No user with SamAccountName '$($user.sAMAccountName)' could be found.."
    }
}

这样,当找不到具有该 samaccountname 的用户时,文件中的任何错误都不会导致代码退出。相反,在这种情况下,您会看到一个警告,并且代码将继续处理其余数据。


值得一提的是,您可以在 Get-ADUserSet-ADUser cmdlet 上使用参数 -Server,以确保使用相同的域服务器 (DC) 来设置新的 UPN。否则,您可以在一个 DC 上设置它,但正在查看另一个不会立即显示更改的 DC,因为服务器需要时间来同步..



现在我们已经解决了有关 CSV 的问题并回答您的评论:

如果您想将此作为两个脚本的解决方案,请按以下方式进行

第 1 步:获取搜索 OU 中 UserPrincipalName 以“*@test.group”结尾的所有用户

$searchBase = "OU=Teams,OU=Prod,DC=RES,DC=TEST,DC=GROUP"
Get-ADUser -SearchBase $searchBase -Filter "UserPrincipalName -like '*@test.group'" | 
# select ony the SamAccountName and write to CSV with column header
Select-Object SamAccountName | Export-Csv -Path .\group.csv -NoTypeInformation

第 2 步:读取上面创建的 csv 并

$searchBase = "OU=Teams,OU=Prod,DC=RES,DC=TEST,DC=GROUP"
$data = Import-Csv -Path .\group.csv
$result = foreach($user in $data) {
    $adUser = Get-ADUser -SearchBase $searchBase -Filter "SamAccountName -eq '$($user.sAMAccountName)'" -ErrorAction SilentlyContinue
    # if we have a user object AND its UserPrincipalName is not as desired go ahead and change that
    if ($adUser) {
        if ($adUser.UserPrincipalName -notlike '*@res.test.group') {
            $newUPN = '{0}@res.test.group' -f $user.sAMAccountName
            $adUser | Set-ADUser -UserPrincipalName $newUPN
            # output this user object to be collected in variable $result
            $adUser
        }
        else {
            Write-Host "User $($user.sAMAccountName) already has UPN '$($adUser.UserPrincipalName)'"
        }
    }
    else {
        Write-Warning "User with SamAccountName '$($user.sAMAccountName)' not found.."
    }
}

# now that we have changed some users, create a second csv with all users that were actually changed
if (@($result).Count) {
    $result | Select-Object SamAccountName | Export-Csv -Path .\Updatedgroup.csv -NoTypeInformation
}
else {
    Write-Host 'No users needed updating'
}

仅将用户 SamAccountName 属性写入 csv 文件似乎是一种浪费。特别是因为默认情况下 Get-ADUser 已经返回以下属性:DistinguishedName、Enabled、GivenName、Name、ObjectClass、ObjectGUID、SamAccountName、SID、姓氏,用户主体名称

【讨论】:

  • 无需测试,未找到用户不会阻止其他处理。正如我已经评论过的,在Import-Csv 之后,只需使用这一行$data| ForEach {Set-ADUser -Identity $_.sAMAccountName -UserPrincipalName "$($_.sAMAccountName)@res.group"}。唯一的问题是您将遇到每个未找到用户的错误。如果您不关心错误,请添加 try catch 块:$data| ForEach {try{Set-ADUser -Identity $_.SamAccountName -UserPrincipalName "$($_.sAMAccountName)@res.group"}catch{}}
  • 感谢您的帮助兄弟,但它仍然无法正常工作我收到一个错误,找不到每个用户
  • @khamro 你最好开始检查你的 csv 文件然后..
  • 我检查了,csv文件没问题
  • @khamro 不,看到你在下面的帖子,你的 csv肯定不行。您保存的是Format-Table 的输出,仅用于显示目的。要创建正确的 csv,请直接在数据(objects)上使用Export-Csv,然后忘记FT | Out-File。所以,首先创建一个真正的 csv 并使用我的函数。
猜你喜欢
  • 2021-08-26
  • 2015-11-20
  • 1970-01-01
  • 2015-02-20
  • 2012-11-15
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
相关资源
最近更新 更多