2
votes

So basically, I want to set AD's user license (Powershell script) from C# code. Here is the code:

//adminUser & adminPassword from app.config

    public static string SetUserLicense(string userPrincipalName, string adminUser, SecureString adminPassword, string licenses)
            {
                string strReturn = "";
                try
                {
                    // Create Initial Session State for runspace.
                    InitialSessionState initialSession = InitialSessionState.CreateDefault();
                    initialSession.ImportPSModule(new[] { "MSOnline" });
                    // Create credential object.
                    PSCredential credential = new PSCredential(adminUser, adminPassword);
                    // Create command to connect office 365.
                    Command connectCommand = new Command("Connect-MsolService");
                    connectCommand.Parameters.Add((new CommandParameter("Credential", credential)));

                    Command userCommand = new Command("Set-MsolUser");
                    userCommand.Parameters.Add((new CommandParameter("UserPrincipalName", userPrincipalName)));
                    userCommand.Parameters.Add((new CommandParameter("UsageLocation", "ID")));

                    Command licCommand = new Command("Set-MsolUserLicense");
                    licCommand.Parameters.Add((new CommandParameter("UserPrincipalName", userPrincipalName)));
                    licCommand.Parameters.Add((new CommandParameter("AddLicenses", licenses)));

                    using (Runspace psRunSpace = RunspaceFactory.CreateRunspace(initialSession))
                    {
                        // Open runspace.
                        psRunSpace.Open();

                        //Iterate through each command and executes it.
                        foreach (var com in new Command[] { connectCommand, userCommand, licCommand })
                        {
                            if (com != null)
                            {
                                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 == licCommand)
                                {
                                    strReturn = error[0].ToString();
                                }
                                else if (results.Count >= 0 && com == licCommand)
                                {
                                    strReturn = "User License update successfully.";
                                }
                            }
                        }
                        // Close the runspace.
                        psRunSpace.Close();
                    }
                }
                catch (Exception ex)
                {

                    strReturn = ex.Message;
                }
                return strReturn;
            }

However, when I run it, everything works well (unlicensed now become licensed). Then, I published the code so I get the DLLs & Services.asmx which run on the server. After that, I make a service agent and added service reference (web service URL), so periodically, the agent can call SetUserLicense function.

Here is code from service agent which calls the Web Service:

NewWSOffice365.ServicesSoapClient Service = new NewWSOffice365.ServicesSoapClient();
string Result = Service.SetUserLicense("[email protected]");

The problem is when the service agent runs, I get error:

You must call the Connect-MsolService cmdlet before calling any other cmdlets.

The weird thing, I've put Connect-MsolService in my C# code (see above). Everything meets its requirement, here: http://code.msdn.microsoft.com/office/Office-365-Manage-licenses-fb2c6413 and set IIS AppPool UserProfile to true (default: false).

1
Did you run the PowerShell script on the server?Matt
@Matt the PowerShell script runs on the server which called from web service (lets say 10.21.50.43:81). The problem is when I call the web service, it returns error (written above) whereas when I debug the web service project, the PowerShell script runs perfectly.user2393874
One possible reason is the different privilege. Can you check if the web service is running under local system account? if it is, change to administrator account and try again.Matt
I'd love to know if there's a MS.Graph API C# equivalent of this available.peteski

1 Answers

2
votes

You need to add Powershell session before using "Connect-MsolService" credential is your above credential.

PSCommand psSession = new PSCommand();
psSession.AddCommand("New-PSSession");
psSession.AddParameter("ConfigurationName", "Microsoft.Exchange");
psSession.AddParameter("ConnectionUri", new Uri("https://outlook.office365.com/powershell-liveid/"));
psSession.AddParameter("Credential", credential);
psSession.AddParameter("Authentication", "Basic");
psSession.AddParameter("AllowRedirection");

powershell.Commands = psSession;
powershell.Invoke();

PSCommand connect = new PSCommand();
connect.AddCommand("Connect-MsolService");
connect.AddParameter("Credential", credential);

powershell.Commands = connect;
powershell.Invoke();