none
EWS Managed api - create calendar appointments for all users RRS feed

  • Question

  • Hello,

    I would like to create programmaticaly appointments for all user calendars at once... I have an Exchange 2010 and I am using the EWS managed api 2.0.

    Can you please help me on this one?

    I have wright permissions on every Mailbox calender in the Exchange Organisation.

    Thank you.

    Regards

    Ioannis

    Friday, November 15, 2013 3:37 PM

Answers

  • Hello Ioannis,

    sorry I missed that first one. Would this work out better?:

    // Old
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "Distributiongroup Member Emailaddress");
    
    // New
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, Address.Address

    Cheers,
    Fred

    There's no place like 127.0.0.1

    Thursday, November 21, 2013 3:36 PM
  • Hi Ioannis,

    the trick is, to simply drop it from the save call :)

    appointment.Save(WellKnownFolderName.Calendar);

    This will save the appointment to the 'own' calendar folder. And since you're impersonating the user in question, that will be his/her calendar folder instead.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Thursday, November 21, 2013 2:43 PM

All replies

  • Hello Ioannis,

    welcome to the Exchange Development forums.

    What tools do you want to use for this? PowerShell? C#? Something else?
    How frequent do you want to do this? As a permanent Service that runs? As an application where you push individual calendars?

    The process itself is 'fairly simple':

    - Connect to Exchange Server
    - Grab all folders
    - For each folder create the appointment
    - Save the Appointment to the folder.

    Just how you go about this is dependent on a lot of factors, most notably tools and scale.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Friday, November 15, 2013 3:59 PM
  • Hello Fred,

    thank you very much for the reply.

    I would like to to this with Visual Studio C#, in order to make also a GUI for the application. Our Human Recourses Departmen wishes a tool, in orden to save Appointments in the Calendars of all empolyes at once, like Christmas Holydays or National Holydays.

    I have managed to make a console application that saves a single appointment to in my calendar, but I have no idea how I can save with a singel action an appointment to multiple calendars. I have a distribution group with all the employes inside, but I can't find any informations on how to realise this action.

    Cheers

    Ioannis

    Monday, November 18, 2013 2:27 PM
  • Hello Fred,

    I have managed with the EWS Managed API to create Appointmants in a Users calnedar, throw impersonation (userA creates an appointment in userB calendar) Hier is some code:

    namespace EWS_Service
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;

                //Instantiate the ExchangeService class
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
                
                // Connect by using the credentials of ws\kalenderuser.
                service.Credentials = new NetworkCredential("userA", "password", "domain");

                // Use Autodiscover to set the URL endpoint
                service.AutodiscoverUrl("userA", RedirectionUrlValidationCallback);

               //Set the ImpersonatedUserId property of the ExchangeService object to identify the impersonated user
                service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "userB@domain");

                //Appointment creation
                Appointment appointment = new Appointment(service);

                //Eigenschaften des Termines
                appointment.Subject = "EWS2010";
                appointment.Body = "Created with EWS API!!!";
                appointment.Start = new DateTime(2013, 12, 12, 0, 0, 0);
                appointment.End = appointment.Start.AddDays(1);
                
                //Der Termin wird gespeichert
                appointment.Save(SendInvitationsMode.SendToNone);
                Console.WriteLine("The appontmend is crated.");

            }

            private static bool RedirectionUrlValidationCallback(string redirectionUrl)
            {
                // The default for the validation callback is to reject the URL.
                bool result = false;

                Uri redirectionUri = new Uri(redirectionUrl);

                // Validate the contents of the redirection URL. In this simple validation
                // callback, the redirection URL is considered valid if it is using HTTPS
                // to encrypt the authentication credentials.
                if (redirectionUri.Scheme == "https")
                {
                    result = true;
                }
                return result;
            }

            private static bool CertificateValidationCallBack(
            object sender,
            System.Security.Cryptography.X509Certificates.X509Certificate certificate,
            System.Security.Cryptography.X509Certificates.X509Chain chain,
            System.Net.Security.SslPolicyErrors sslPolicyErrors)
            {
                // If the certificate is a valid, signed certificate, return true.
                if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
                {
                    return true;
                }

                // If there are errors in the certificate chain, look at each error to determine the cause.
                if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
                {
                    if (chain != null && chain.ChainStatus != null)
                    {
                        foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                        {
                            if ((certificate.Subject == certificate.Issuer) &&
                               (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                            {
                                // Self-signed certificates with an untrusted root are valid.
                                continue;
                            }
                            else
                            {
                                if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                                {
                                    // If there are any other errors in the certificate chain, the certificate is invalid,
                                    // so the method returns false.
                                    return false;
                                }
                            }
                        }
                    }

                    // When processing reaches this line, the only errors in the certificate chain are
                    // untrusted root errors for self-signed certificates. These certificates are valid
                    // for default Exchange server installations, so return true.
                    return true;
                }
                else
                {
                    // In all other cases, return false.
                    return false;
                }
            }
        }
    }

    My problem is, how can I do this for all Mail Users in my Exchange Organisation. I thowgt of extrxactin the emlpoyes Distribution group:

                // Return the expanded group and display the group members
                ExpandGroupResults myGroupMembers = service.ExpandGroup("Distributiongroup");
                foreach (EmailAddress address in myGroupMembers.Members)
                {
                   Console.WriteLine("Email Address: {0}", address);                    
                }

    But I havo no idea how to import the Email list in my program...

    You wrote I could "Grab all folders" (I think you mean the calendar Folders from each Mailbox), but I have no qlue on how I could do this programaticaly.

    Can you give me some help on this?

    Cheers

    Ioannis

    Thursday, November 21, 2013 9:35 AM
  • Hello Ioannis,

    let's start this from the GUI then ...

    Your users will enter the relevant parameters in a GUI and press a button. That button will call a static function (which accepts the relevant parameters as ... parameters). Let's call this function 'Function A'.

    Function A then grabs all said group-members as you did in your example. Only instead of writing them to the console, for each one you call another static function ('Function B'), passing all the previous parameters to it plus the address.

    Function B will then autoconnect to the exchange as you did in your example, impersonating the user you gave it in a parameter. Then Function B binds to the calendar folder (a wellknownfoldername) using the bind method on the folder class of EWS MA, creates a new calendar object from all these parameters you passed it and writes it to the folder.

    That ought to get you your desired results.

    Cheers,
    Fred

    Ps.: Please note that Impersonation needs the proper permissions on the Exchange Server by the executing user ('ApplicationImpersonation'), which can be ... abused, by someone in the know. You may want to run this as a service with the users using the GUI to feed the service with data, instead of building this into the user-side application.


    There's no place like 127.0.0.1


    • Edited by FWN Thursday, November 21, 2013 12:35 PM
    Thursday, November 21, 2013 11:10 AM
  • Hello Fred,

    and thank you for the quick answer!

    I have tried to get the Funktion B "inside" the Funktion A, but I am having problems in defining the impresonator for each email address of the distribution members...

    Here is what I am trying to to:

                // Return the expanded group and create appointments for each member
                ExpandGroupResults myGroupMembers = service.ExpandGroup("Distributiongroup");
                foreach (EmailAddress address in myGroupMembers.Members)
                {
                    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "Distributiongroup Member Emailaddress");
                 
                   Appointment appointment = new Appointment(service);
                    
                    appointment.Subject = "EWS2010";
                    appointment.Body = "Erstellt mit dem EWS API!!!";
                    appointment.Start = new DateTime(2013, 12, 11, 0, 0, 0);
                    appointment.End = appointment.Start.AddDays(1);

                    appointment.Save(new FolderId(WellKnownFolderName.Calendar, "Distributiongroup Member Emailaddress"));
                    Console.WriteLine("The appontmend is crated.");

                }

    I am struggeling like crazy, but I just can't figure out how I can resolve/import the "Distributiongroup Member Emailaddress"...

    I am normaly an Systemadministrator and not a programmer... I've just started learning visual c# on my own. I am trying to get this Programm going as a console application and then I will try to make a GUI out of this ;-).

    Cheers

    Ioannis


    Thursday, November 21, 2013 1:51 PM
  • Hi Ioannis,

    the trick is, to simply drop it from the save call :)

    appointment.Save(WellKnownFolderName.Calendar);

    This will save the appointment to the 'own' calendar folder. And since you're impersonating the user in question, that will be his/her calendar folder instead.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Thursday, November 21, 2013 2:43 PM
  • Hi Fred,

    thanks again!

    ...But I am still not able to define the impersonated user:

    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "Distributiongroup Member Emailaddress");

    When I am running the application with "appointment.Save(WellKnownFolderName.Calendar);" the appointment is saved in the impersonators calendar... and exactly so many times as the number of the distribution group members.

    Cheers

    Ioannis

    Thursday, November 21, 2013 2:57 PM
  • Hello Ioannis,

    sorry I missed that first one. Would this work out better?:

    // Old
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "Distributiongroup Member Emailaddress");
    
    // New
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, Address.Address

    Cheers,
    Fred

    There's no place like 127.0.0.1

    Thursday, November 21, 2013 3:36 PM
  • Hi Fred,

    Thank you!!!!! You are my Hero!!!

    Cheers

    Ioannis

    Thursday, November 21, 2013 3:53 PM