Powershell script to change custom attribute 1 for mailbox

Hello,

i have an adress rules to set "domain.com" at primary smtp adresse when the custom attribute 1 is set to "domain.com".

Now i need a powershell script to modify the the custom attribute 1 to "domain.com" for all mailbox in specific OU.

The script must also verify the custom attribute 5 and set it to null (empty) if this attribute is informed.

thanks for your help.
cawasakiAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dale HarrisProfessional Services EngineerCommented:
Cawasaki,

Have you tried using Quest Active Directory CMDLets?

If it's installed, and you have the Exchange Snapin Installed, you can do this:

$domain = "domain.com"
$users = get-qaduser -sizelimit 0 -searchroot "ou=users,ou=HR,dc=domain,dc=com" -includedproperties "extensionattribute1"
foreach ($object in $objects){
if ($object.type -eq "user"){
set-qadobject $object -objectattributes @{extensionattribute1 = "$domain"}
}#end if
}#end foreach



HTH,

Dale Harris
cawasakiAuthor Commented:
hi DaleHarris,

sorry, not possible to use quest command.

i need powershell script.

Dale HarrisProfessional Services EngineerCommented:
Cawasaki,

Quest AD CMDLets are an addon to Powershell.

This is Powershell, but with some CMDLets installed.

All you have to do is go to

http://www.quest.com/powershell/activeroles-server.aspx

And install the CMDLets on your computer (just like the Exchange Addon is a set of CMDLets, this doesn't actually hurt you, but makes your Powershell much more powerful)
And in each script or your $profile script, type in the following:
Add-PSSnapin Quest.ActiveRoles.Admanagement

It's free and great!  Many people can attest to using these sets of CMDLets added into their Powershell as a snapin.

Dale Harris
Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

cawasakiAuthor Commented:
yes i know, but for this client, i am not able to install anything for this.
Dale HarrisProfessional Services EngineerCommented:
Unfortunately I was looking at the "Get-User" command from Exchange and I don't see how it's possible to get the ExtensionAttribute1 this way.

Can you remote into the Exchange Server and install it on there?  Maybe you can't install it on the Client, but if you are going to be managing Users and Computers for the next few years of your life, it would be in your best interests to install this somewhere you can remote into and run scripts from.

Just trying to help.

Dale Harris
cawasakiAuthor Commented:
harris,

not sure to install quest powershell,but i will ty it.

in your script:

1- it select all ad user in OU, i need just to do it to maibox.

2-The script must also verify the custom attribute 5 and set it to null (empty) if this attribute is informed.

thanks
Dale HarrisProfessional Services EngineerCommented:
Cawasaki,

Thanks for at least giving Quest a try.  They make a solid product that has been helping me manage our users for over 3 years.

$domain = "domain.com"
$users = get-qaduser -sizelimit 0 -searchroot "ou=users,ou=HR,dc=domain,dc=com" -includedproperties "extensionattribute1","extensionattribute5"
foreach ($object in $users){
if (($object.type -eq "user") -and ($object.email -ne $null)){
set-qadobject $object -objectattributes @{extensionattribute1 = "$domain";extensionattribute5 = ""}
}#end if
}#end foreach



Dale Harris
cawasakiAuthor Commented:
ok will try it tomorow in my exchange lab.

just a question: get-qaduser select all user or just mailbox user?

thanks
Dale HarrisProfessional Services EngineerCommented:
Cawasaki,

Get-qaduser selects all users, but $object.email -ne $null makes it only select mail enabled users from the list.

Dale
cawasakiAuthor Commented:
ok
Chris DentPowerShell DeveloperCommented:

I believe Set-Mailbox or Set-User (Exchange 2007 / 2010 CmdLets) can modify extensionAttribute1 / CustomAttribute1.

It is entirely possible with native PS, just harder work than with Quest's CmdLets.

Chris
Dale HarrisProfessional Services EngineerCommented:
Chris,

I looked into Set-Mailbox, and when I did a test of setting customattribute1 and then pulled up my extension attribute, it still came out as null.

So I'm not sure how to set the extensionattribute through set-mailbox.

Dale
Chris DentPowerShell DeveloperCommented:

ExtensionAttribute1 and Custom Attribute 1 are the same thing. If you see any disparity you'd have to check the DC you were making the change against (potential replication delays).

Chris
cawasakiAuthor Commented:
Hi Chris,

can you help me plz with a native PS script?

thanks
Chris DentPowerShell DeveloperCommented:
Sure.  It can go like this. The verbose message will show if you set $VerbosePreference to Continue (it defaults to SilentlyContinue).

Chris
# The OU you wish to find users in
$SearchRoot = [ADSI]"LDAP://OU=Somewhere,DC=domain,DC=com"
# Filter to limit the results to mailbox-enabled users
$LdapFilter = "(&(objectClass=user)(objectCategory=person)(mail=*))"

# Create the searcher
$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
# Enable paging in case there are more than 1000 results
$Searcher.PageSize = 1000
$Searcher.FindAll() | ForEach-Object {

  Write-Verbose "Modifying Custom Attribute 1 for $($_.Properties['name'][0])"

  # Change the search result to a DirectoryEntry
  $User = $_.GetDirectoryEntry()
  # Set Custom Attribute 1
  $User.Put("extensionAttribute1", "domain.com")
  # Commit the change
  $User.SetInfo()
}

Open in new window

cawasakiAuthor Commented:
hi chris,

can you plz add this to the script:

The script must also verify the custom attribute 5 and set it to null (empty) if this attribute is informed.

thanks
Chris DentPowerShell DeveloperCommented:

Sure.

Chris
# A constant
$AdsPropertyClear = 1

# The OU you wish to find users in
$SearchRoot = [ADSI]"LDAP://OU=Somewhere,DC=domain,DC=com"
# Filter to limit the results to mailbox-enabled users
$LdapFilter = "(&(objectClass=user)(objectCategory=person)(mail=*))"

# Create the searcher
$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
# Enable paging in case there are more than 1000 results
$Searcher.PageSize = 1000
$Searcher.FindAll() | ForEach-Object {

  Write-Verbose "Modifying Custom Attribute 1 for $($_.Properties['name'][0])"

  # Change the search result to a DirectoryEntry
  $User = $_.GetDirectoryEntry()
  # Set Custom Attribute 1
  $User.Put("extensionAttribute1", "domain.com")
  # Commit the change
  $User.SetInfo()

  # Check and clear Custom Attribute 5
  If ($User.Get("extensionAttribute5")) {
    $User.PutEx($AdsPropertyClear, "extensionAttribute5", 0)
    $User.SetInfo()
  }
}

Open in new window

cawasakiAuthor Commented:
ok i test this.

can you explain me plz this line:

 Write-Verbose "Modifying Custom Attribute 1 for $($_.Properties['name'][0])"
Chris DentPowerShell DeveloperCommented:

It writes out the object (user) name to the Verbose output stream. Just a way of checking the scripts progress.

You can make the stream visible with:

$VerbosePreference = "Continue"

By default, verbose output is not displayed.

$_ is a SearchResult in this case, and the name property itself is stored as part of the Properties collection. This is not the simplest interface to work with.

Chris
cawasakiAuthor Commented:
ok,

i need to add this $VerbosePreference = "Continue" if i want to display it.

where i can put this in the script?
Chris DentPowerShell DeveloperCommented:

Anywhere before Write-Verbose, but I'd put it right at the beginning. If you'd prefer not to bother about that we can change Write-Verbose to Write-Host.

I've added another for extensionAttribute5 as well so you can watch that change.

Chris
# A constant
$AdsPropertyClear = 1

# The OU you wish to find users in
$SearchRoot = [ADSI]"LDAP://OU=Somewhere,DC=domain,DC=com"
# Filter to limit the results to mailbox-enabled users
$LdapFilter = "(&(objectClass=user)(objectCategory=person)(mail=*))"

# Create the searcher
$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
# Enable paging in case there are more than 1000 results
$Searcher.PageSize = 1000
$Searcher.FindAll() | ForEach-Object {

  Write-Host "Modifying Custom Attribute 1 for $($_.Properties['name'][0])"

  # Change the search result to a DirectoryEntry
  $User = $_.GetDirectoryEntry()
  # Set Custom Attribute 1
  $User.Put("extensionAttribute1", "domain.com")
  # Commit the change
  $User.SetInfo()

  # Check and clear Custom Attribute 5
  If ($User.Get("extensionAttribute5")) {

    Write-Host "Modifying Custom Attribute 5 for $($_.Properties['name'][0])"

    $User.PutEx($AdsPropertyClear, "extensionAttribute5", 0)
    $User.SetInfo()
  }
}

Open in new window

cawasakiAuthor Commented:
ok, i have many problem:

1- when the user have custom attribute 5 already empty, i have error :

If ($User.Get( <<<< "extensionAttribute3")) {

2-the script change successfully the custom attribute 1 in "domain.com", but the primary SMTP adress not changed!

When i put manually  "domain.com"in custom attribute 1, its work.

thanks for your help
Chris DentPowerShell DeveloperCommented:

> 1.

Oops. Fixed below I hope.

> 2-the script change successfully the custom attribute 1 in "domain.com", but the primary
> SMTP adress not changed!

You need RUS / Email Address Policy update to run. The script doesn't do this, it just changes the underlying attribute.

Update-EmailAddressPolicy, I think, is the CmdLet you want (Exchange Management Shell).

Chris
# A constant
$AdsPropertyClear = 1

# The OU you wish to find users in
$SearchRoot = [ADSI]"LDAP://OU=Somewhere,DC=domain,DC=com"
# Filter to limit the results to mailbox-enabled users
$LdapFilter = "(&(objectClass=user)(objectCategory=person)(mail=*))"

# Create the searcher
$Searcher = New-Object DirectoryServices.DirectorySearcher($SearchRoot, $LdapFilter)
# Enable paging in case there are more than 1000 results
$Searcher.PageSize = 1000
$Searcher.FindAll() | ForEach-Object {

  Write-Host "Modifying Custom Attribute 1 for $($_.Properties['name'][0])"

  # Change the search result to a DirectoryEntry
  $User = $_.GetDirectoryEntry()
  # Set Custom Attribute 1
  $User.Put("extensionAttribute1", "domain.com")
  # Commit the change
  $User.SetInfo()

  # Check and clear Custom Attribute 5
  If ($_.Properties["extensionattribute5"]) {

    Write-Host "Modifying Custom Attribute 5 for $($_.Properties['name'][0])"

    $User.PutEx($AdsPropertyClear, "extensionAttribute5", 0)
    $User.SetInfo()
  }
}

Open in new window

cawasakiAuthor Commented:
Chris,

you have help me in this question:

http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_26670757.html


Mail-enabled accounts first:

Get-Content YourFile.txt | ForEach-Object { Get-Mailbox $_ | Set-Mailbox -CustomAttribute4 "TESTATTRIBUTE" }

i am sure the error is here:

in your script you modify custom attribute of AD user not mailbox user?

thanks
cawasakiAuthor Commented:
Chris,

i have test this for 2 user and it work:

Get-Content YourFile.txt | ForEach-Object { Get-Mailbox $_ | Set-Mailbox -CustomAttribute1 "domain.com" }

the primary SMTP ADRESS changed immediatly
Chris DentPowerShell DeveloperCommented:

Sure, but Set-Mailbox is a bit more advanced than working with the underlying directory. The two entries we've been modifying are the same thing.

Still, if the method you have works then all is well :)

Chris
cawasakiAuthor Commented:
yes, but i need to use this in your script, its possible to integrate it?

or change this command to modify cutomattribute 1 and empty the custoattribute5?

thanks



Chris DentPowerShell DeveloperCommented:

I would go for this. The tricky bit is Custom Attribute 5. Oddly enough the CmdLets don't really give us a way to clear them.

In theory this gets you the best of both worlds.
Get-Mailbox -OrganizationalUnit "OU=somewhere,DC=domain,DC=com" | ForEach-Object {
  Set-Mailbox $_.DistinguishedName -CustomAttribute1 "domain.com"

  If ($_.CustomAttribute5) {
    $User = [ADSI]"LDAP://$($_.DistinguishedName)"
    $User.PutEx($AdsPropertyClear, "extensionAttribute5", 0)
    $User.SetInfo()
  }
}

Open in new window

Chris
cawasakiAuthor Commented:
Chris,

its work for CustomAttribute1 and the primary smtp adress is immediatly changed.

But Nothing Happened for customattribute5, thanks for your help
Chris DentPowerShell DeveloperCommented:
Ack, sorry, missed a line.

Chris
$AdsPropertyClear = 1

Get-Mailbox -OrganizationalUnit "OU=somewhere,DC=domain,DC=com" | ForEach-Object {
  Set-Mailbox $_.DistinguishedName -CustomAttribute1 "domain.com"

  If ($_.CustomAttribute5) {
    $User = [ADSI]"LDAP://$($_.DistinguishedName)"
    $User.PutEx($AdsPropertyClear, "extensionAttribute5", 0)
    $User.SetInfo()
  }
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
cawasakiAuthor Commented:
Now work perfect.

1-if i need just modify the customattrbute 1, i just need this command ?:

Get-Mailbox -OrganizationalUnit "OU=somewhere,DC=domain,DC=com" | ForEach-Object {
  Set-Mailbox $_.DistinguishedName -CustomAttribute1 "domain.com"

2-and if just i need to clear the customattribute 5 ?

3- if i have 3000 user in the same OU, this script can modify it or no? just to now the limit :)
Chris DentPowerShell DeveloperCommented:
1. Yes. It can be simplified a little:
Get-Mailbox -OrganizationalUnit "OU=somewhere,DC=domain,DC=com" | Set-Mailbox -CustomAttribute1 "domain.com"

Open in new window

2. Drop the "Set-Mailbox" line from the snippet above, no other changes required.

3. Needs one more parameter (everything else remains as it is):
Get-Mailbox -OrganizationalUnit "OU=somewhere,DC=domain,DC=com" -ResultSize Unlimited

Open in new window

Otherwise it'll stop after 100 / 1000, I forget the default limit.

Chris
cawasakiAuthor Commented:
Ok perfect.

can you explain me plz this:

$AdsPropertyClear = 1


thanks
Chris DentPowerShell DeveloperCommented:

A slightly less ambiguous name (AdsPropertyClear) to describe what value (1) actually does. PutEx, where we use that value, takes numerical arguments between 1 and 4, each number changes the operation. For this one it's Clear, but we can also use Update (2), Append (3) and Delete (4).

This is the source of those values with a brief description of each:

http://msdn.microsoft.com/en-us/library/aa772282%28v=vs.85%29.aspx

Chris
cawasakiAuthor Commented:
OK thanks for your help
cawasakiAuthor Commented:
very good!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.