Link to home
Start Free TrialLog in
Avatar of Mandy_
Mandy_

asked on

Exchange Management Shell - Scripts not executed only one line commands

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

Avatar of Qlemo
Qlemo
Flag of Germany image

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?
Avatar of Mandy_
Mandy_

ASKER

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.
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.
Avatar of Mandy_

ASKER

$company.keys -contains $ADUser.Company in windowsPS and EMS i'm getting "true"
but the smtp still not overwritten. :(
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

Avatar of Mandy_

ASKER

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
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).
Avatar of Mandy_

ASKER

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

Avatar of Mandy_

ASKER

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

??? 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.
Avatar of Mandy_

ASKER

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
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

Avatar of Mandy_

ASKER

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
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.
Avatar of Mandy_

ASKER

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@
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.
Avatar of Mandy_

ASKER

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

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

Avatar of Mandy_

ASKER

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.
ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial