Solved

Exchange Management Shell - Scripts not executed only one line commands

Posted on 2013-05-11
20
400 Views
Last Modified: 2013-05-19
Hello,

i've installed Server2008 with Exchange 2013 in a virtual Environment. I like to execute a script in EMS (as administrator) before the security policy is set to unrestricted, but
nothing happens. The variables not stored. I can run the same in Windows Powershell
everything ok without the special CMDlets for Exchange.
If i'm going to type only one line in EMS e.g.  $Variable = "test@domain.com" or

Get-Mailbox Jeff.Horton@acme.com | Set-Mailbox -PrimarySmtpAddress Jeff.Horton@acme.anvil.com -EmailAddressPolicyEnabled $false

Open in new window


everything is working as designed. Only the whole script executed as script.ps1
not working. Or is there sth wrong in the code?

# create hashtable for each company with correct suffix and write to a variable
$company=@{
"Test company" = 'testecompany.net'
"Test Company 2" = 'testcompany2.com'
}

$ADUser = Get-AdUser -identity USER -Properties Company,EmailAddress

#$ADUser = Get-AdUser -identity $Entry.UserID

ForEach($Key in $company.Keys){
# if the key = User.Company
IF($Key -like $ADUser.Company){

# create smtp depending of the company
$NewSMTP = "{0}.{1}@{2}" -f $ADUser.GivenName,$ADUser.Surname,$company[$Key]
If ($ADUser.EmailAddress)
{ "$($ADUser.GivenName) $($ADUser.SurName) already has an email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
}
else
{
[b]Get-Mailbox User | Set-Mailbox -PrimarySmtpAddress User -EmailAddressPolicyEnabled $false[/b]
}
}
}

Open in new window

0
Comment
Question by:Mandy_
  • 10
  • 10
20 Comments
 
LVL 68

Expert Comment

by:Qlemo
ID: 39158014
The script doesn't make much sense to me, and I can't see which parts should be really dynamic. Are you manually replacing USER with a real user name each time, or should that be a parameter of the script / read from env vars?
And what do you mean with "nothing happens. The variables not stored."? There are no vars to keep set in the script - it should either output an "error" message or assign the email address without any feedback.

Line 13: -like should be -eq. Like is a pattern matching operator, and you want exact matches.
Line 22: The [ b ] tag is there by accident and only in the above post, I assume?
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39158065
Yes there will be normaly a import-csv included. I just checking with only one user. It's $ADUSER and $newsmtp. If i'm running that with WindowsPowershell the Data will be read from Active directory and the smtp build correctly from the hash-table and stored.
But the CMDLET Get and Set-mailbox not running under windows powershell.
The "b" its just an accident. Not possible to bold at code area.
If i used only in EMS
Get-Mailbox User | Set-Mailbox -PrimarySmtpAddress User -EmailAddressPolicyEnabled $false
The existing smtp will be overwritten but as i said already with whole script nothing.
What else could be wrong with EMS?  The policy is already set to unrestricted.
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39158082
Certain that the company matches? Check with a correctly filled $company and $ADUser:
$company.keys -contain $ADUser.Company

Open in new window

If that is not the case, the script won't do anything.
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39158216
$company.keys -contains $ADUser.Company in windowsPS and EMS i'm getting "true"
but the smtp still not overwritten. :(
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39158605
Inserting debug output is always a good idea if you don't know why something does not work.
BTW, you have tried to set the email address to just "User".
# create hashtable for each company with correct suffix and write to a variable
$company = @{
  "Test company" = 'testecompany.net'
  "Test Company 2" = 'testcompany2.com'
}

$User = "User"
#$ADUser = Get-AdUser -identity $Entry.UserID
$ADUser = Get-AdUser -identity $User -Properties Company,E mailAddress

ForEach ($Key in $company.Keys) {
  # if the key = User.Company
  Write-Host -ForegroundColor Blue "Checking for $Key membership"
  if ($Key -eq $ADUser.Company) {
    # create smtp depending of the company
    $NewSMTP = "{0}.{1}@{2}" -f $ADUser.GivenName, $ADUser.Surname, $company[$Key]
    Write-Host -ForegroundColor Blue "Found company. New SMTP is $NewSMTP"
    If ($ADUser.EmailAddress)
    {
      "$($ADUser.GivenName) $($ADUser.SurName) already has an email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
    } else {
      Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled $false
    }
  }
}

Open in new window

You can remove the Write-Host commands if the script runs as intended.

Having said that, I would code it different:
# create hashtable for each company with correct suffix and write to a variable
$company = @{
  'Test company'   = 'testecompany.net'
  'Test Company 2' = 'testcompany2.com'
}

$User = 'User'
#$ADUser = Get-AdUser -identity $Entry.UserID
$ADUser = Get-AdUser -identity $User -Properties Company,E mailAddress

if ($co = $company[$ADUser.Company])
{
  If ($ADUser.EmailAddress)
  {
    "$($ADUser.GivenName) $($ADUser.SurName) already has an email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
  } else {
    # create smtp depending of the company
    $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $company[$co]
    Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled $false
  }
} else {
  Write-Host "$User not in company list!"
}

Open in new window

0
 
LVL 2

Author Comment

by:Mandy_
ID: 39159296
This is the 2nd step of my work i've done. In the 1st step i enable mbx from a CSV list.
At this step the primary smtp will be set by system policy like useralias@mothercompany.com e.g. Z234567@mothercompany.com. Later this one will be the 2nd smtp for all user.

The primary smtp will be build from first and lastname with special internal company domain as we did in the code above. What i have to do is to compare if the primary smtp already exists in the system and if so write it to the errorlog. Then i'm going to take a look to errorlog and change the smtp manually of all user with existing smtps to an alternate.

Now the problem is, that within the code i cannot add the new smtp as primary and the existing 2nd smtp as secondary.
If i'm executing the line alone everthing works as desinged. But within the script
nothing happens. The script should check if the same smtp already exists, not any other smtp. This alone do what i want to do:
Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled $false
How can i solve this one?  

 
At the thirt code i like to add the descriptions with OrderId for all User.  This should not be the problem but also i have to write back all used smtp as a new column to the CSV.
The given CSV looks like that:
UserID   OrderId    Product  
Z12345   O123456  MBX2010
Z23456   O234567  MBX2010

After finished it should looks as follows
UserID   OrderId    Product      SMTP
Z12345   O123456  MBX2010   john.contoso@company22.com
Z23456   O234567  MBX2010   dave.brubeck@company1.com

How can i write back this? I think i've to read it from AD for all user and write it to a complety new csv.

appreciate for your help
Mandy
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39159527
I reckon you are aware that
Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled $false

Open in new window

won't fulfill the requirement of
(a) checking for any mail already set and
(b) making the primary email the secondary if one is set
so the statement "If i'm executing the line alone everthing works as desinged." is wrong.

The secondary email address thingy is a new requirement, and not reflected in the code. The same applies to the "same address" check.

This code should honour the new requirements.
# create hashtable for each company with correct suffix and write to a variable
$company = @{
  'Test company'   = 'testecompany.net'
  'Test Company 2' = 'testcompany2.com'
}

$User = 'User'
#$ADUser = Get-AdUser -identity $Entry.UserID
$ADUser = Get-AdUser -identity $User -Properties Company, EmailAddress

if ($co = $company[$ADUser.Company])
{
  # create smtp depending of the company
  $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $company[$co]
  If ($ADUser.EmailAddress -eq $NewSMTP)
  {
    "$($ADUser.GivenName) $($ADUser.SurName) already has the correct email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
  }
  elseif ($ADUser.EmailAddress)
  {
    "$($ADUser.GivenName) $($ADUser.SurName) already has the a different email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
  } else {
    Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled $false
  }
} else {
  Write-Host "$User not in company list!"
}

Open in new window

There are a lot of potential issues here. Since I cannot test it, I can only guess about them:
You might want to set EmailAddresses (a mail address collation) instead of PrimarySMTPAddress, as that allows to add a primary address and maintaining the aliases used.
You might want to use Get-Mailbox instead of Get-ADUser to retrieve the Email address (if set).
You might have to use the ADUser object for Get-Mailbox to retrieve the mailbox object.

If you still do not get ahead, I encourage you to use the ISE in the Exchange shell (just copy  the ISE link's commandline into that shell), and then go and debug by executing stepwise. Or use the much more advanced free PowerGUI from Quest for that purpose (see www.powergui.org).
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39161283
Thanks you so much for your answer. I'm already using powergui and checked everything of the code partial. Today i did it on Exchange 2010 Live System. Always the same.
If iam using the whole code the mailadress created but not write to the system as
primary SMTP.  This alone " Get-Mailbox $User | Set-Mailbox -PrimarySmtpAddress $NewSMTP -EmailAddressPolicyEnabled  is working. With this below it's working.
How can i include that into my code?

$MailboxList = Get-Mailbox  Username
 
$MailboxList | % {
 
$LoweredList = @()
$RenamedList = @()
 
foreach ($Address in $_.EmailAddresses){
if ($Address.prefixstring -eq "SMTP"){
$RenamedList += $Address.smtpaddress + "TempRename"
$LoweredList += $Address.smtpaddress.ToLower()
}
}
Set-mailbox $_ -emailaddresses $RenamedList -EmailAddressPolicyEnabled $false
Set-mailbox $_ -emailaddresses $LoweredList
 
#Without this line the "Reply To" Address could be lost on recipients with more than one proxy address:
Set-mailbox $_ -PrimarySmtpAddress $_.PrimarySmtpAddress
} 

Open in new window

0
 
LVL 2

Author Comment

by:Mandy_
ID: 39162961
I got it. It's working now. Could you pls take a look. maybe you can optimize sth, thx in advance. mandy

$company = @{
  "Test inc." = 'testinc.com'
  "Test3 inc." = 'test3.com'
}

#ForEach ($Entry in  Import-Csv  'E:\temp\import.csv') {
#$ADUser = Get-AdUser -identity $Entry.UserID

$User = "UserId"
#$ADUser = Get-AdUser -identity $Entry.UserID
$ADUser = Get-AdUser -identity $User -Properties Company,EmailAddress


$ADUser | % {
$LoweredList = @()
$RenamedList = @()
foreach ($Address in $Aduser){
if ($Address.prefixstring -eq "SMTP"){
$RenamedList += $Address.smtpaddress + "TempRename"
$LoweredList += $Address.smtpaddress.ToLower()
}
}
Set-mailbox $user -emailaddresses $RenamedList -EmailAddressPolicyEnabled $false
Set-mailbox $user -emailaddresses $LoweredList
}

ForEach ($Key in $company.Keys) {
  # if the key = User.Company
  Write-Host -ForegroundColor blue "Checking for $Key membership"
  if ($Key -eq $ADUser.Company) {
    # create smtp depending of the company
    $NewSMTP = "{0}.{1}@{2}" -f $ADUser.GivenName, $ADUser.Surname, $company[$key]
    Write-Host -ForegroundColor green "Found company. For $user the New SMTP is $NewSMTP"
    If ($ADUser.EmailAddress)
    {
      "$($ADUser.GivenName) $($ADUser.SurName) already has an email address: $($ADUser.EmailAddress)" | Tee-Object c:\temp\errorlog.txt -Append
    } 
	else
	{


	Set-mailbox $user -PrimarySmtpAddress $NewSMTP

    }
  }
}

Open in new window

0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39163147
??? Besides the renaming of the emailaddresses content that is the same as already posted, and why should it work now?
Further, are you certain you need a double rename, first with  ...Tempname, then with the original email addresses in lowercase?
All that doesn't sound like it should work as intended.
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39165292
The rename to lower smtp let the script replace the existing primary smtp. I tried to
do it with ad-user or set-mailbase with different parameters but its not working.
You can not overwrite the primary smtp set by system policy. Anyone knows a better
solution? The problem i'm still have that all other X400 or 2nd smtp already set by
system, will be deleted. Thats crap. I'm on the way and with external help i will
hope i can resolve.

appreciate for your help
mandy
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39166142
This is how I would do that.
$company = @{
	"Test inc." = 'testinc.com'
	"Test3 inc." = 'test3.com'
}

# Import-Csv  'E:\temp\import.csv' | select -Expand UserID |
'User' |
	foreach {
		$ADUser = Get-ADUser -identity $_ -Properties Company	# EmailAddress not needed
		$mbox   = Get-Mailbox $_
		if ($co = $company[$ADUser.Company])
		{
			$mb | Set-Mailbox -EmailAddressPolicyEnabled $false
	    $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $company[$co]
			If ($mbox.PrimarySMTPAddress -ne $NewSMTP)
			{
				Write-Host "Setting primary SMTP address for $_"
				$mb | Set-Mailbox -EmailAddresses @($NewSMTP)+$mb.EmailAddresses
			} else {
				Write-Host "$_ already has correct primary SMTP address"
			}
		} else {
			Write-Host "$_User not in company list!"
		}
	}

Open in new window

0
 
LVL 2

Author Comment

by:Mandy_
ID: 39166440
Thank you so much. The $newsmtp will not be build correctly. It's only "givenname.surname@"  The prefix will not be added. The user company is set to Test inc. but the output is "user not in company list". Also there is sth wrong with piping. I did not understand what the pipe 'user' should do?

select -Expand UserID |'User' |
      foreach

bye
mandy
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39166547
That line starts with an hash - that is a comment! Lines 6 and 7 are to use alternatively. Line 7 is for testing with a particular user, while line 6 (after removing or commenting line 7, and removing the hash from line 6) is what you will use with a CSV file containing the user names.

Line 14 is wrong (sorry for that), and should sound:
	    $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $co

Open in new window

Line 23 reports something incorrect, and should be:
			Write-Host "$_ not in company list!"

Open in new window

In regard of the company name, please check the value of $ADUser and $ADUser.Company after line 9 is executed.
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39168945
The smtp building correct now. But the piping on line 13, 18 not working this form

$mb | Set-Mailbox -EmailAddressPolicyEnabled $false
$mb | Set-Mailbox -EmailAddresses @($NewSMTP)+$mb.EmailAddresses

Where the variable of $MB is set?

If you exclude the import-csv. Where you set the $_.

For checking i'm including the $user = "User" and replace $_ with $user.
The smtp will not be set if i remove the pipe |$mb

Important for me is to replace the existing primary and use the existing as
secondary.  The check should be for a SMTP already exists with same name.
e.g. john.smith@
0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39169150
Sorry, $mb should be $mbox (all occurances).
$_ is set by the foreach. In the script as-is we pipe a single string 'User' into foreach, and that makes $_ then.
Here is the adjusted code:
$company = @{
  "Test inc." = 'testinc.com'
  "Test3 inc." = 'test3.com'
}

# Import-Csv  'E:\temp\import.csv' | select -Expand UserID |
'User' |
  foreach {
    $ADUser = Get-ADUser -identity $_ -Properties Company  # EmailAddress not needed
    $mbox   = Get-Mailbox $_
    if ($co = $company[$ADUser.Company])
    {
      $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $co
      If ($mbox.PrimarySMTPAddress -ne $NewSMTP)
      {
        Write-Host "Setting primary SMTP address for $_"
        $mbox | Set-Mailbox -EmailAddresses @($NewSMTP)+$mbox.EmailAddresses
      } else {
        Write-Host "$_ already has correct primary SMTP address"
      }
    } else {
      Write-Host "$_ not in company list!"
    }
  }

Open in new window

The code checks for exact match of the SMTP primary address (but case insensitive). If it does not match, the new SMTP address is set as primary, line 18 should do that (after replacing $mb with $mbox, of course). The description of the cmdlet says that setting the EMailAddresses collection also sets the primary address, which is the first one of the collection.
0
 
LVL 2

Author Comment

by:Mandy_
ID: 39172280
appreciate for your help. The following code i'm using now only leaves me with one problem. How should i handle double-names in surname like meyer jones?

 $NewSMTP = '{0}.{1}.{2}@{3}' -f $ADUser.GivenName, $ADUser.Surname, $ADUser.Surname2,  $co



import-module activedirectory
$company = @{
  "TEST INC" = 'test.com'
  
}
#
ForEach ($Entry in Import-Csv 'c:\export7.csv') {
#$ADUser = Get-ADUser -identity $Entry.UserID -Properties Company  


    $ADUser = Get-ADUser -identity $Entry.UserID -Properties Company  
    $mbox   = Get-Mailbox $Entry.UserID
    if ($co = $company[$ADUser.Company])
    {
      $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $co
      If ($mbox.PrimarySMTPAddress -ne $NewSMTP)
      {
        Write-Host  -ForegroundColor Green "Setting primary SMTP $newsmtp address for $entry.UserID "
		Write-Host  -ForegroundColor Green "$newsmtp"
       set-mailbox -identity $Entry.UserID -PrimarySmtpAddress $newsmtp -EmailAddressPolicyEnabled $false
		
      } else {
        Write-Host -ForegroundColor red -backgroundcolor yellow "$entry.UserID has an SMTP-Adress already exists in system"
      }
    } else {
      Write-Host -ForegroundColor yellow -backgroundcolor blue "$entry.UserID not in company list!"
    }
	 }

Open in new window

0
 
LVL 68

Expert Comment

by:Qlemo
ID: 39172324
You can replace
      $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $co

Open in new window

with
      if ($ADUser.Surname2)
      {
        $NewSMTP = '{0}.{1}.{2}@{3}' -f $ADUser.GivenName, $ADUser.Surname, $ADUser.Surname2,  $co
      } else {
        $NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname, $co
      }

Open in new window

0
 
LVL 2

Author Comment

by:Mandy_
ID: 39172501
hi,

thanks for your fast response. The Ad-Attribute surname2 does not exists i found
middlename but its not stored. Do you know how can i read this information from AD.
0
 
LVL 68

Accepted Solution

by:
Qlemo earned 500 total points
ID: 39173027
Didn't check whether the Surname2 you provided was in fact an AD attribute - just trusted in what you have posted ;-).
Middlename is the wrong attribute, it is for the second (given) name.

A double surname is still stored in the Surname attribute. Depending on the country that names is from, there are different forms, like "Meyer Jones" and "Meyer-Jones".
While IMHO "Donald.Meyer-Jones@testdomain.com" makes an acceptable email address, "Donald.Meyer.Jones@testdomain.com" does not, and should be "Donald.MeyerJones@testdomain.com" instead.
My recommendation is
$NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname.Replace(' ', ''), $co

Open in new window

but if you insist, we will add a dot:
$NewSMTP = '{0}.{1}@{2}' -f $ADUser.GivenName, $ADUser.Surname.Replace(' ', '.'), $co

Open in new window

0

Join & Write a Comment

Utilizing an array to gracefully append to a list of EmailAddresses
"Migrate" an SMTP relay receive connector to a new server using info from an old server.
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now