简体   繁体   中英

Run powershell from c# most efficient way to create multiple mailcontacts in Exchange Online

I wish to create multiple mailcontacts (external Contacts) in the GAL in Microsoft Online by running Powershell command from C#. The code below works, but is very slow and takes about 15-20 min to run for 400 mailcontacts.

foreach(EmailAdressVM emailAddressVM in emailList.emailAddresses1)
{
    //Create New MailContact.
    Pipeline pplNewMailContact = runspace.CreatePipeline();

    Command cmdNewMailContact = new Command("New-MailContact");
    cmdNewMailContact.Parameters.Add("Name", emailAddressVM.sExternalEmailAddress);
    cmdNewMailContact.Parameters.Add("Displayname", emailAddressVM.sFullName.Trim());
    cmdNewMailContact.Parameters.Add("Lastname", emailAddressVM.sLastName.Trim());
    cmdNewMailContact.Parameters.Add("Firstname", emailAddressVM.sFirstName.Trim());
    cmdNewMailContact.Parameters.Add("ExternalEmailAddress", emailAddressVM.sExternalEmailAddress.Trim());

    pplNewMailContact.Commands.Add(cmdNewMailContact);
    pplNewMailContact.Invoke();
    pplNewMailContact.Stop();
    pplNewMailContact.Dispose();
}

I am guessing that this is slow since I create a new Pipeline for every new mailcontact that is added and there has to be a more eficient way of doing this since running...

import-csv <filename> | ForEach {
    new-mailcontact -name $_.emailaddress -displayname $_.FullName -lastname $_.lastname -firstname $_.firstname -externalemailaddress $_.emailaddress -alias $_.alias
}

...is much faster.

I have found some references after many hours of searching the web that you can do something similar to using a CSV when running Powershell commands from C#, ie send a list (or array) of values to a command (in this case the "new-mailcontact" command). But, I have not found any good example of how to send more than one value to a command and I need to supply many values (for example: -name $ .emailAddress -displayname $ .FullName, etc.) to the "new-mailcontact" command.

Is it possible to send a list (or array) in a similar way as the "import-csv" command (when using regular powershell) and will this be faster, or is there an evan better way? Would I get better performance if I use Powershell 3 instead of 1 (as I am using now).

Please provide working sample code i C#!

Please note that I cannot save a CSV file to disk and the execute powershell from CMD since I do not have write access to disk and that I do not think that I can run an entire script remotely (since remote scripting probably is disabled on Exchange Online).

The biggest reason I would think is because for each address you are creating a new Powershell instance and you are not multithreaded.

You code looks something like this from above:

Foreach email address{
    Declare a new Powershell process
    Add attributes to call later
    Start Powershell and pipe stuff in
    Close Powershell instance
}

I think you would be better off creating the Powershell instance / pipe once and then sending each object into it. More along the lines of:

Create PS Pipe
    Foreach email address{
     PS.SendArguments(Email, Name, DN, etc.);
     }

I am not in an environment to get something working or tested right now, so hopefully this gives you at least most of what you need...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM