简体   繁体   中英

Invoking PowerShell cmdlets more quickly in C#

I am able to fetch user details from O365 using Powershell cmdlets in C#. The problem is the fetching time. That is too slow.

It takes 2 seconds to each user so it will lead to a time problem if I have the bulk of users.

Here I am just want to print all the user's info like name, group details, licenses. How can I do it more quickly?

Tried one:

        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        Pipeline UserDetailsPipe = runspace.CreatePipeline();
        UserDetailsPipe.Commands.AddScript("Get-AzureADUser");
        foreach (PSObject info in UserDetailsPipe.Invoke())  /////////*******
        {
            ArrayList Groups = new ArrayList();   // to hold memberOf
            ArrayList Licenses = new ArrayList(); // to hold of licenses

            string UserPrincipalName = info.Members["UserPrincipalName"].Value.ToString();
            string DisplayName = info.Members["DisplayName"].Value.ToString();

            //Getting MemberOf
            Pipeline memberPipe = runspace.CreatePipeline();
            memberPipe.Commands.AddScript("Get-AzureADUser -ObjectId '" + UserPrincipalName + "'| Get-AzureADUserMembership");

            //Getting Licenses
            Pipeline licensePipe = runspace.CreatePipeline();
            licensePipe.Commands.AddScript("$license = Get-AzureADUserLicenseDetail -ObjectId '" + UserPrincipalName + "' | select ServicePlans ");
            licensePipe.Commands.AddScript("$license.ServicePlans");


                foreach (var licensenames in licensePipe.Invoke())////////*****
                {
                    Licenses.Add(licensenames.Members["ServicePlanName"].Value.ToString());
                }

            foreach (var memberOf in memberPipe.Invoke())////////*******
            {
                Groups.Add(memberOf.Members["DisplayName"].Value.ToString());
            }
       }

I know that I am invoking many pipelines. So how to get my answers by using only one invoke? (It may be in PowerShell class too).

It appears the best solution will be to combine into as few scripts as possible to reduce the number of pipelines. I also would suggest using the PowerShell object instead of Runspaces

Also in order to get all results in the final Collection after invoking, use the .AddStatement() method. This is demonstrated below. Documentation for AddStatement

This will need to be modified to your environment as I am simply getting the date twice to demonstrate returning both dates to the final collection.

using (PowerShell powershell = PowerShell.Create()) {
    powershell.AddScript("Get-Date");
    powershell.AddStatement().AddScript("Get-Date");

    Collection<PSObject> result = powershell.Invoke();
}

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