简体   繁体   中英

Updating user ProxyAddresses

I try to update AD user account ProxyAddresses property. I've read many topics about this and applied one of the suggested approach ( this one ) but it doesn't work for me. Why? I use a following bit of code (it's a part of script updating more users data):

$ADUser = SearchADUser -Kogo "sAMAccountName -eq '$($WzorUser.sAMAccountName)'"
...
1.$ProxyOK = $false
2.$Proxies = $ADUser.ProxyAddresses
3.$Proxies | ForEach-Object {
4.  $_ = $_ -replace 'SMTP', 'smtp'
5.  if ($_ -match $NoweMail) {
6.      $_ = $_ -replace 'smtp', 'SMTP'
7.      $ProxyOK = $true
8.  }
9.}
10.if (!($ProxyOK)) { $Proxies += ("SMTP:$($NoweMail)") }
...
if (!([string]::IsNullOrEmpty($Proxies))) {
    $AttrToReplace.Add("ProxyAddresses", $Proxies)
Set-ADUser -Identity $ADUser.sAMAccountName -Server $ADDC @Attr #-PassThru -WhatIf

When looping on Proxies, its elements are properly processed: letters are lowercased for all and uppercased if the new mail was already present. But Proxies is not changed. Do each element needs to be saved in some way or replaced in the object?

Update 2020-04-02

Because supporter effort (@Theo once again thanks for Your assist) focus on replacing method I try to more detailed explain my problem.

Target user proxyAddresses values (it's a rare case when women come back to her maiden name alredy recorded in AD):
SMTP :anna.nowak22@lp.pl
smtp :ab@moc.com

Initial values (line 2):

[DBG]: PS X:\>> $Proxies
smtp:anna.nowak22@lp.pl
SMTP:a.b@moc.com

While looping on every proxy element (line 9):

[DBG]: PS X:\>> $_
SMTP:anna.nowak22@lp.pl
[DBG]: PS X:\>> $Proxies
smtp:anna.nowak22@lp.pl
SMTP:a.b@moc.com

[DBG]: PS X:\>> $_
smtp:a.b@moc.com
[DBG]: PS X:\>> $Proxies
smtp:anna.nowak22@lp.pl
SMTP:a.b@moc.com

As can be seen $Proxies doesn't reflect changes.

If there was only one ProxyAddresses value not equal with new mail, new mail was added as SMTP to the existed one which is leaved also as SMTP (two primary ProxyAddresses).

I tried to create a new variable and assign to it each value respectively but I don't know how to handle it.

$newProxies = $null
$Proxies | ForEach-Object {
    $_ = $_ -creplace 'SMTP', 'smtp'
    if ($_ -match $NoweMail) {
        $_ = $_ -creplace 'smtp', 'SMTP'
        $ProxyOK = $true
    }
      $newProxies.add($_)
}

Above generates an error

You cannot call a method on a null-valued expression

$newProxies += $_ creates one string SMTP:anna.nowak22@lp.pl smtp:ab@moc.com which is added as single ProxyAddress.

As I noted $Proxies is a special AD object and I don't know how to create an object of such type and how to add new elements to it.

As commented, here more readable as answer.

In your code, you add the modified $Proxies array to a hashtable (i think) called $AttrToReplace . However, in the final Set-ADUser command, you are not using this, but instead splat using a variable @Attr .

To update the multivalued attribute ProxyAddresses, change the code after the three dots in your question from:

if (!([string]::IsNullOrEmpty($Proxies))) {
    $AttrToReplace.Add("ProxyAddresses", $Proxies)
Set-ADUser -Identity $ADUser.sAMAccountName -Server $ADDC @Attr #-PassThru -WhatIf

into:

# no need to test if $Proxies is an empty array, because 
# it will at the very least have "SMTP:$($NoweMail)"
Set-ADUser -Identity $ADUser.SamAccountName -Clear ProxyAddresses
Set-ADUser -Identity $ADUser.SamAccountName -Add @{proxyAddresses = $Proxies | ForEach-Object { "$_" }}

# or do this on one line:
# Set-ADUser -Identity $ADUser.SamAccountName -Replace @{proxyAddresses = $Proxies | ForEach-Object { "$_" }}


Update

From your comments, your code does leave room for duplicate proxy addresses.

You can get this list, replace all existing SMTP: by smtp: and add the new primary email address to it like this:

 # get the current ProxyAddress values for this user, change all values # that begin with uppercase 'SMTP:' to lowercase 'smtp:'. # skip any proxy that is equal to "smtp:$NoweMail", add the $NoweMail # preceeded by 'SMTP:' to the list and sort or select unique $Proxies = @($ADUser.ProxyAddresses -replace '^SMTP:', 'smtp:' | Where-Object { $_ -ne "smtp:$NoweMail" }) + "SMTP:$NoweMail" | Sort-Object -Unique # set the new proxy addresses in the user attribute # no need to test if $Proxies is an empty array, because # it will at the very least have "SMTP:$($NoweMail)" Set-ADUser -Identity $ADUser.SamAccountName -Clear ProxyAddresses Set-ADUser -Identity $ADUser.SamAccountName -Add @{proxyAddresses = [string[]]$Proxies} # or do this on one line: # Set-ADUser -Identity $ADUser.SamAccountName -Replace @{proxyAddresses = [string[]]$Proxies}

Note that inside the hash to Add or Replace, the LDAP name is used, so proxyAddresses with a lowercase p

@Theo. You solution works fine. Thank You for help. I remained my approach (it suits me and works) and modified code a bit.

$ProxyOK = $false
$Proxies = $null
$Proxies = @()
$ADUser.ProxyAddresses | ForEach-Object {
  $_ = $_ -creplace 'SMTP', 'smtp'
  if ($_ -match $NoweMail) {
      $_ = $_ -creplace 'smtp', 'SMTP'
      $ProxyOK = $true
  }
  $Proxies += $_
}
if (!($ProxyOK)) { $Proxies += ("SMTP:$($NoweMail)") }
...
if ($Proxies) {
    $AttrToReplace.Add("ProxyAddresses", [string[]]$Proxies)
}
if ($AttrToReplace.Count -gt 0) {
    $Attr.Add("Replace", $AttrToReplace)
}
Set-ADUser -Identity $ADUser.sAMAccountName -Server $ADDC @Attr #-PassThru -WhatIf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM