检查并更新AD用户的多个属性



我正在尝试从CSV更新Active Directory。我想检查每个值,看看AD和CSV值是否匹配。如果AD值和CSV值不匹配,那么我想更新AD值。最后,我想创建一个更改值的日志,该日志最终将导出到CSV报告中。

现在我要检查大约30个值。我可以为每个值做一个if语句,但这似乎是很难做到的

我正在尝试使用一个函数,但似乎无法使它工作。我收到的错误如下:

set-ADUser : replace
At line:94 char:9
+         set-ADUser -identity $ADUser -replace @{$ADValue = $DIAccount ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (JDoe:ADUser) [Set-ADUser], ADInvalidOperationException
+ FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.SetADUser
set-ADUser : The specified directory service attribute or value does not exist
Parameter name: Surname
At line:94 char:9
+         set-ADUser -identity $ADUser -replace @{$ADValue = $DIAccount ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (JDoe:ADUser) [Set-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.SetADUser

欢迎提出任何建议我正在使用的代码:

Function AD-Check ($ADValue, $ADUser, $ADAccount, $UpdateAccount)
{
If ($ADAccount -ne $UpdateAccount)
{
set-ADUser -identity $ADUser -replace @{$ADValue = $UpdateAccount}
$Change = "Updated"
}
Else
{
$Change = "No Change"
}

Return $Change
}
$Import = get-content C:tempADUpdates.csv
Foreach ($user in $Import)
{
$Account = get-aduser $User.Samaccountname -Properties *
#First Name Check
$Test = AD-Check "GivenName" $Account.samaccountname $Account.givenname $user.givenname
$ChangeGivenName = $Test
#Initials Check
$Test = AD-Check "Initials" $Account.samaccountname $Account.Initials $user.Initials
$ChangeInitials = $Test
#Last Name Check
$Test = AD-Check "Surname" $Account.samaccountname $Account.SurnameSurname $user.Surname
$ChangeSurname = $Test
}

回复西奥,似乎无法添加任何其他方式。。。

谢谢西奥,这似乎很有道理,但却犯了一个错误。

Select-Object : Cannot convert System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection to one of the following types {System.String, 
System.Management.Automation.ScriptBlock}.

更改以下内容以获取所有属性进行测试,它就可以工作了。

$Account = Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue -Properties $propsToCheck

留下以下内容,它踢出错误

$oldProperties = $Account | Select-Object $propsToCheck

仅使用以下内容进行测试:

$propertiesMap = [ordered]@{
SamAccountName = 'sAMAccountName'
mail           = 'mail'
GivenName      = 'givenName'
Initials       = 'initials'
Surname        = 'sn'
Office         = 'physicalDeliveryOfficeName'
MobilePhone    = 'mobile'
DistinguishedName = 'DistinguishedName'
}

以警告开始:

替换用户属性是不可掉以轻心的需要首先检查在一组测试用户上执行此操作的任何代码
-WhatIf开关保留为Set-ADUser cmdlet,以便可以在不对AD造成任何问题的情况下首先运行此操作。
只有在您确信一切按计划进行后,才能移除-WhatIf开关。

请仔细阅读代码中的所有内联注释。

在您的代码中,您使用一个输入CSV文件,其中显然包含要检查/更新的属性和值,但您没有使用Import-Csv,而是对其执行Get-Content,因此您最终只得到几行文本,而不是一组解析的属性和数值。。

接下来,正如Mathias已经评论的那样,在使用Set-ADUser cmdlet的-Add-Remove-Replace-Clear参数时,需要使用LDAP属性名称。

要执行您打算执行的操作,我将首先创建一个哈希表,将PowerShell属性名称映射到它们的LDAP等效名称。要查看哪个属性名称映射到哪个LDAP名称,可以使用此处的表

# create a Hashtable to map the properties you want checked/updated
# the Keys are the PowerShell property names as they should appear in the CSV
# the Values are the LDAP AD attribute names in correct casing.
$propertiesMap = [ordered]@{
SamAccountName = 'sAMAccountName'
GivenName      = 'givenName'
Initials       = 'initials'
Surname        = 'sn'
Office         = 'physicalDeliveryOfficeName'
Organization   = 'o'
MobilePhone    = 'mobile'
# etcetera
}
# for convenience, store the properties in a string array
$propsToCheck = $propertiesMap.Keys | ForEach-Object { $_.ToString() }
# import your CSV file that has all the properties you need checked/updated
$Import = Import-Csv -Path 'C:tempADUpdates.csv'
# loop through all items in the CSV and collect the outputted old and new values in variable $result
$result = foreach ($user in $Import) {
$sam = $user.SamAccountName
# try and find the user by its SamAccountName and retrieve the properties you really want (not ALL)
$Account = Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue -Properties $propsToCheck
if (!$Account) {
Write-Warning "A user with SamAccountName '$sam' does not exist"
continue  # skip this one and proceed with the next user from the CSV
}
# keep an object with the current account properties for later logging
$oldProperties = $Account | Select-Object $propsToCheck
# test all the properties and create a Hashtable for the ones that need changing
$replaceHash = @{}
foreach ($prop in $propsToCheck) {
if ($Account.$prop -ne $user.$prop) {
$ldapAttribute = $propertiesMap[$prop]       # get the LDAP name from the $propertiesMap Hash
# If any of the properties have a null or empty value Set-ADUser will return an error.
if (![string]::IsNullOrWhiteSpace($($user.$prop))) {
$replaceHash[$ldapAttribute] = $user.$prop
}
else {
Write-Warning "Cannot use '-Replace' with empty value for property '$prop'"
}
}
}
if ($replaceHash.Count -eq 0) {
Write-Host "User '$sam' does not need updating"
continue  # skip this one and proceed with the next user from the CSV
}
# try and do the replacements
try {
##########################################################################################################
# for safety, I have added a `-WhatIf` switch, so this wll only show what would happen if the cmdlet runs. 
# No real action is performed when using '-WhatIf'
# Obviously, there won't be any difference between the 'OLD_' and 'NEW_' values then
##########################################################################################################
$Account | Set-ADUser -Replace $replaceHash -WhatIf
# refresh the account data
$Account = Get-ADUser -Identity $Account.DistinguishedName -Properties $propsToCheck
$newProperties = $Account | Select-Object $propsToCheck
# create a Hashtable with the old and new values for log output
$changes = [ordered]@{}
foreach ($prop in $propsToCheck) {
$changes["OLD_$property"] = $oldProperties.$prop
$changes["NEW_$property"] = $newProperties.$prop
}
# output this as object to be collected in variable $result
[PsCustomObject]$changes
}
catch {
Write-Warning "Error changing properties on user '$sam':`r`n$($_.Exception.Message)"
}
}
# save the result as CSV file so you can open with Excel
$result | Export-Csv -Path 'C:tempADUpdates_Result.csv' -UseCulture -NoTypeInformation

最新更新