HOW TO: Add SMTP ProxyAddresses to a mailbox using Exchange PowerShell and Managed code.


The key here is that you will first have to read all the proxy addresses using the Get-Mailbox Cmdlet and then call the Set-mailbox Cmdlet to update the ProxyAddresses. If this is not done you end up replacing all the existing addresses with the one you just added.

To get the sample to work you will have to add a reference to the "System.Management.Automation.dll". This assembly is installed by the Windows PowerShell SDK and can be found at the following path \Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0

Sample:

using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;

namespace SetProxyAddresses
{
    class Program
    {
        static void Main(string[] args)
        {
             //To store the ProxyAddresses
            ArrayList alProxyAddresses = new ArrayList();

            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
            PSSnapInException snapInException = null;
            PSSnapInInfo info = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
            Collection<PSObject> results;
            Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
            
            myRunSpace.Open();

            Pipeline pipeLine = myRunSpace.CreatePipeline();

            Command cmdGetMailbox = new Command("get-mailbox");
            cmdGetMailbox.Parameters.Add("identity", @"mycompany\VIP");
            pipeLine.Commands.Add(cmdGetMailbox);
            results = pipeLine.Invoke();

            if (pipeLine.Error != null && pipeLine.Error.Count > 0)
            {
                foreach (object item in pipeLine.Error.ReadToEnd())
                {
                    Console.WriteLine("Error: " + item.ToString() + "\n");
                }
            }

            foreach (PSObject mailbox in results)
            {
                //define the properties to get
                foreach (String propName in new string[] {"EmailAddresses" })
                {
                    Object objValue = mailbox.Properties[propName].Value;
            
                    if (objValue is ICollection)
                    {
                        ICollection collection = (ICollection)objValue;
                        // Loop through each entry in the collection and output it
                        foreach (object value in collection)
                        {
                            alProxyAddresses.Add(value.ToString());
                        }
                        PrintIndexAndValues(alProxyAddresses);
                    }
                }
            }

            //Cleanup
            cmdGetMailbox = null;
            pipeLine.Dispose();
            pipeLine = null;
                        
            //add the additional address
            //Use SMTP as the prefix if you want to add and make it the Primary smtp address
            //Use smtp as the prefix if you just want to add a smtp address
            alProxyAddresses.Add("smtp:akashb@mycompany.com");

            //Create a new Pipeline
            pipeLine = myRunSpace.CreatePipeline();

            Command cmdSetMailbox = new Command("Set-Mailbox");
            cmdSetMailbox.Parameters.Add("Identity",@"mycompany\VIP");
            cmdSetMailbox.Parameters.Add("EmailAddressPolicyEnabled", false);
            cmdSetMailbox.Parameters.Add("EmailAddresses", (String[])alProxyAddresses.ToArray(typeof(string)));
            pipeLine.Commands.Add(cmdSetMailbox);

            results = pipeLine.Invoke();

            if (pipeLine.Error != null && pipeLine.Error.Count > 0)
            {
                foreach (object item in pipeLine.Error.ReadToEnd())
                {
                    Console.WriteLine("Error: " + item.ToString() + "\n");
                }
            }

            //Cleanup
            cmdSetMailbox = null;   
            pipeLine.Dispose();
            myRunSpace.Close();

            pipeLine = null;
            myRunSpace = null;
        
        }

        public static void PrintIndexAndValues(ArrayList myList)
        {
            int i = 0;
            foreach (Object o in myList)
                Console.WriteLine("ProxyAddress[{0}]:\t{1}", i++, o);
            Console.WriteLine();
        }
    }
}

You'll note that I don't have any references to Exchange namespaces, except adding the snapin and also that I don't treat the returned data as strong typed data. Everything is dealt with using "PSObject", which is a generic property bag that PowerShell keeps internally. This is the supported and recommended way to deal with this type of data. The pattern is to use the property collection to find props and set/get them and to use cmdlets to achieve actions like Get-Mailbox and Set-Mailbox.

Comments (3)

  1. Dave Durose says:

    Can you not do this using one pipeline?  Not sure how it works.  It’d be nice to add the 2 commands to one pipeline.  Maybe it doesn’t work that way?

  2. Akashb says:

    To pipe the output of one command to the input of another, you simply add both commands to the pipeline. In this case we have to modify the output of the first command and then pass it to the other. The single pipeline approach will not work here.

  3. qad-cmds-ftw says:

    get-qaduser -Email primary@yourdomain.com -ip proxyAddresses | foreach-object {

    $newMail = “blah@yourdomain.com”

    $pa = $.proxyAddresses+=”smtp:$newMail”

    Set-QADUser $ -oa @{proxyAddresses=$pa; mail=$newMail1}

    }

Skip to main content