Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

like image 401
saravanan ks Avatar asked Nov 08 '22 04:11

saravanan ks


1 Answers

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();
}
like image 65
ivcubr Avatar answered Nov 14 '22 23:11

ivcubr