none
Use Exchange Web Services from C# to set ForwardingSmtpAddress for a mailbox? RRS feed

  • Question

  • I would like to create a page/app/webpart that reads the ForwardingSmtpAddress from a user's own exchange 365 account and displays this on our SharePoint online site.

    In our non-profit organization most of the users have their inbox forwarded to a personal email inbox.  We set this up using PowerShell to set the ForwardingSmtpAddress to that address.   I would like to create a page on our SharePoint site that displays the current value of this information so they can easily verify that it is correct.  Optionally I'd like to be able to have them change it here also.  I intend to put this right next to some information they *need* to come to SharePoint to get, so that it has a higher probability to be reviewed and acted upon. 

    Most of these users would glaze over if I asked them to go into OWA Options and review/configure there.   It would be different if they actually used OWA, but that is a later battle.   

    I am hoping this is supported in the EWS managed API.  If it is only available using an autogenerated proxy, can someone point me at some sample code?

    -Frank Long

    Saturday, January 25, 2014 6:43 AM

Answers

  • EWS (or any of the Mailbox Access API) don't have access to that property. The only API that you can use to get\modify this are the Exchange Management Shell cmdlets (which is what ECP is using in the background). By default a normal user in Office365 should be able to execute the Set-Mailbox cmdlet on their own mailbox eg something like this should work in C#

                string PSServerName = "ps.outlook.com/PowerShell-LiveID?PSVersion=2.0";
                String UserName = "user@domain.onmicrosoft.com";
                String Password = "passwr2";
    
                System.Security.SecureString secureString = new System.Security.SecureString();
                foreach (char c in Password)
                    secureString.AppendChar(c);
                PSCredential credential = new PSCredential(UserName, secureString);
                WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("https://" + PSServerName), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);
                connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
                connectionInfo.SkipCACheck = true;
                connectionInfo.SkipCNCheck = true;
    
                connectionInfo.MaximumConnectionRedirectionCount = 4;
                Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(connectionInfo);
                runspace.Open();
                Pipeline plPileLine = runspace.CreatePipeline();
                Command smSetMailboxForward = new Command("set-mailbox");
                smSetMailboxForward.Parameters.Add("Identity", UserName);
                smSetMailboxForward.Parameters.Add("ForwardingSmtpAddress", "Forward@domain.com");
                plPileLine.Commands.Add(smSetMailboxForward);
                Collection<PSObject> RsResultsresults = plPileLine.Invoke();
                var error = plPileLine.Error.Read() as Collection<ErrorRecord>;
                if (error != null)
                {
                    foreach (ErrorRecord er in error)
                    {
                        Console.WriteLine(er);
                    }
                    plPileLine.Stop();
                }
                else
                {
                    plPileLine.Stop();
                    //Show Settings
                    plPileLine = runspace.CreatePipeline();
                    Command gmGetMailboxForward = new Command("get-mailbox");
                    gmGetMailboxForward.Parameters.Add("Identity", UserName);
                    plPileLine.Commands.Add(gmGetMailboxForward);
                    RsResultsresults = plPileLine.Invoke();
                    foreach (PSObject obj in RsResultsresults)
                    {
                        Console.WriteLine(obj.Properties["ForwardingSmtpAddress"].Value);
                    }
                    plPileLine.Stop();
                }
                runspace.Close();
                runspace.Dispose();
    Cheers
    Glen

    • Marked as answer by TrailBear1 Tuesday, January 28, 2014 11:20 AM
    Monday, January 27, 2014 4:32 AM

All replies

  • EWS (or any of the Mailbox Access API) don't have access to that property. The only API that you can use to get\modify this are the Exchange Management Shell cmdlets (which is what ECP is using in the background). By default a normal user in Office365 should be able to execute the Set-Mailbox cmdlet on their own mailbox eg something like this should work in C#

                string PSServerName = "ps.outlook.com/PowerShell-LiveID?PSVersion=2.0";
                String UserName = "user@domain.onmicrosoft.com";
                String Password = "passwr2";
    
                System.Security.SecureString secureString = new System.Security.SecureString();
                foreach (char c in Password)
                    secureString.AppendChar(c);
                PSCredential credential = new PSCredential(UserName, secureString);
                WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("https://" + PSServerName), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential);
                connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
                connectionInfo.SkipCACheck = true;
                connectionInfo.SkipCNCheck = true;
    
                connectionInfo.MaximumConnectionRedirectionCount = 4;
                Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(connectionInfo);
                runspace.Open();
                Pipeline plPileLine = runspace.CreatePipeline();
                Command smSetMailboxForward = new Command("set-mailbox");
                smSetMailboxForward.Parameters.Add("Identity", UserName);
                smSetMailboxForward.Parameters.Add("ForwardingSmtpAddress", "Forward@domain.com");
                plPileLine.Commands.Add(smSetMailboxForward);
                Collection<PSObject> RsResultsresults = plPileLine.Invoke();
                var error = plPileLine.Error.Read() as Collection<ErrorRecord>;
                if (error != null)
                {
                    foreach (ErrorRecord er in error)
                    {
                        Console.WriteLine(er);
                    }
                    plPileLine.Stop();
                }
                else
                {
                    plPileLine.Stop();
                    //Show Settings
                    plPileLine = runspace.CreatePipeline();
                    Command gmGetMailboxForward = new Command("get-mailbox");
                    gmGetMailboxForward.Parameters.Add("Identity", UserName);
                    plPileLine.Commands.Add(gmGetMailboxForward);
                    RsResultsresults = plPileLine.Invoke();
                    foreach (PSObject obj in RsResultsresults)
                    {
                        Console.WriteLine(obj.Properties["ForwardingSmtpAddress"].Value);
                    }
                    plPileLine.Stop();
                }
                runspace.Close();
                runspace.Dispose();
    Cheers
    Glen

    • Marked as answer by TrailBear1 Tuesday, January 28, 2014 11:20 AM
    Monday, January 27, 2014 4:32 AM
  • Thanks for the detailed reply.  Greatly appreciated.

    The runspace concept is something I hadn't encountered before.  Interesting way to get server side activity remotely. 

    I added a reference to System.Management.Automation and appropriate usings.  I commented out all the "set-mailbox" activity and used just the //Show Settings code.

    I did this in a web page, and it compiled fine.   Having replace the username and password with an account which is an admin in the tenant.   I tried this both locally (IIS Express) and on an Azure web site, and in both instances I get

    Connecting to remote server ps.outlook.com failed with the following error message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.

    (Occurs at runspace.Open(); )

    That topic (http://technet.microsoft.com/en-us/library/hh847850.aspx) is full of suggestions... and being a bit new to this I'm having a hard time parsing the right information out of it to be able to move forward. 

    EDIT: SUCCESS --- I am using PowerShell 3.0 and noticed that this line

     string PSServerName = "ps.outlook.com/PowerShell-LiveID?PSVersion=2.0";

    had a version 2.0 specified.  Changed this to 3.0 and Viola!  it returned the information requested.

    A great many thanks!

    -Frank





    • Edited by TrailBear1 Tuesday, January 28, 2014 11:19 AM Success
    Tuesday, January 28, 2014 2:45 AM