Somasekhar Digumarthi
Somasekhar Digumarthi

Reputation: 11

Multiple users trying to getting Office 365 profile data using power shell commands in asp.net

We are using powershell commands to get user profile data when user logged in to our website using Office 365 credentials. Now we are getting problem when 4 to 6 users come to my website and hit the login button of office 365, When ever I pass these credentials to powershell, 3 users sessions are created but not for other users. I googled myself and found the link which states the same. Here is the link:

https://4sysops.com/forums/topic/office-365-you-have-exceeded-the-maximum-number-of-connections-allowed-3/

Can I have any resolution for this as I need to expect multiple users to my website at a time.

Here is My Sample Code:

 try
        {
            Collection<PSObject> userList = null;
            // Create Initial Session State for runspace.
            InitialSessionState initialSession = InitialSessionState.CreateDefault();
            initialSession.ImportPSModule(new[] { "MSOnline" });
            // Create credential object.
            PSCredential credential = new PSCredential(UserCredential.UserName, UserCredential.Password);
            // Create command to connect office 365.
            Command connectCommand = new Command("Connect-MsolService");
            connectCommand.Parameters.Add((new CommandParameter("Credential", credential)));
            Command getUserCommand = new Command("Get-MsolUser");
            getUserCommand.Parameters.Add((new CommandParameter("UserPrincipalName", UserCredential.UserName)));

            using (Runspace psRunSpace = RunspaceFactory.CreateRunspace(initialSession))
            {
                // Open runspace.
                psRunSpace.Open();
                //Iterate through each command and executes it.
                foreach (var com in new Command[] { connectCommand, getUserCommand })
                {
                    var pipe = psRunSpace.CreatePipeline();
                    pipe.Commands.Add(com);
                    // Execute command and generate results and errors (if any).
                    Collection<PSObject> results = pipe.Invoke();
                    var error = pipe.Error.ReadToEnd();
                    if (error.Count > 0 && com == connectCommand)
                    {
                        //    MessageBox.Show(error[0].ToString(), "Problem in login");
                        //this.Close();
                        return null;
                    }
                    if (error.Count > 0 && com == getUserCommand)
                    {
                        // MessageBox.Show(error[0].ToString(), "Problem in getting users");
                        // this.Close();
                        return null;
                    }
                    else
                    {
                        userList = results;
                        Session["office365userslist"] = userList;

                    }
                }
                // Close the runspace.
                psRunSpace.Close();
            }
            return userList;
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
            throw;
        }

Upvotes: 0

Views: 375

Answers (1)

Jeffrey Chen
Jeffrey Chen

Reputation: 4690

PowerShell is not recommended for such kind of scenario (Web App).

To get the user profile of a user in your web app, I suggest you using the Microsoft Graph API - Get user.

Request:

GET https://graph.microsoft.com/v1.0/me

Response:

HTTP/1.1 200 OK
Content-type: application/json
Content-length: 491

{
  "businessPhones": [
       "businessPhones-value"
   ],
   "displayName": "displayName-value",
   "givenName": "givenName-value",
   "jobTitle": "jobTitle-value",
   "mail": "mail-value",
   "mobilePhone": "mobilePhone-value",
   "officeLocation": "officeLocation-value",
   "preferredLanguage": "preferredLanguage-value",
   "surname": "surname-value",
   "userPrincipalName": "userPrincipalName-value",
   "id": "id-value"
}

About how to integrate the Microsoft Graph API in your web app, you can reference the sample project on GitHub Office 365 Starter Project for ASP.NET MVC.

UPDATE#1

Is there any alternative to add disclaimer text in exchange server through API?

But the graph API does not provide the function to set the disclaimer html. You can submit a feedback to Office 365 Developer Platform User Voice.

In this scenario, the possible workaround could be sequencing the requests.

For example, put all the requests in a queue and handle requests in 3 threads (max concurrency).

Sample code for your reference:

public class SequencedRequestsDemo
{
    private class SampleRequest
    {
        public string ActionName { get; set; }

        public UserCredential UserCredential { get; set; }
    }

    private class UserCredential
    {
        public string UserName { get; set; }

        public string Password { get; set; }
    }

    private ConcurrentQueue<SampleRequest> _queue = new ConcurrentQueue<SampleRequest>();

    public override void Run()
    {
        _queue.Enqueue(new SampleRequest { ActionName = "action_name1", UserCredential = new UserCredential() });

        _queue.Enqueue(new SampleRequest { ActionName = "action_name2", UserCredential = new UserCredential() });

        _queue.Enqueue(new SampleRequest { ActionName = "action_name3", UserCredential = new UserCredential() });

        _queue.Enqueue(new SampleRequest { ActionName = "action_name4", UserCredential = new UserCredential() });

        _queue.Enqueue(new SampleRequest { ActionName = "action_name5", UserCredential = new UserCredential() });

        _queue.Enqueue(new SampleRequest { ActionName = "action_name6", UserCredential = new UserCredential() });

        var thread1 = new System.Threading.Thread(() => {
            WaitForRequest();
        });

        var thread2 = new System.Threading.Thread(() => {
            WaitForRequest();
        });

        var thread3 = new System.Threading.Thread(() => {
            WaitForRequest();
        });

        thread1.Start();

        thread2.Start();

        thread3.Start();
    }

    private void WaitForRequest()
    {
        while(true)
        {
            SampleRequest request;

            if (_queue.TryDequeue(out request))
            {
                HandleRequest(request);
            }
            else
            {
                System.Threading.Thread.Sleep(1000);
            }
        }
    }

    private void HandleRequest(SampleRequest request)
    {
        Console.WriteLine("Handle request {0} - {1}", request.ActionName, System.Threading.Thread.CurrentThread.ManagedThreadId);
    }
}

Upvotes: 1

Related Questions