Example #1
0
        public static ISubscribedSku GetSubscribedSkus(ActiveDirectoryClient activeDirectoryClient, string skuID)
        {
            //Try to get the subscribed skus for the tenant.
            IPagedCollection <ISubscribedSku> skus = null;

            try
            {
                skus = activeDirectoryClient.SubscribedSkus.ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Applications {0} {1}", e.Message,
                                  e.InnerException != null ? e.InnerException.Message : "");
            }

            //  Loop through all the available skus for the tenant until the SKU provided in the XML is found and return this Sku to be used later.
            ISubscribedSku sku = null;

            do
            {
                List <ISubscribedSku> subscribedSkus = skus.CurrentPage.ToList();
                foreach (ISubscribedSku s in subscribedSkus)
                {
                    if (s.SkuId == new Guid(skuID))
                    {
                        sku = s;
                    }
                }
                skus = skus.GetNextPageAsync().Result;
            } while (skus != null);

            return(sku);
        }
Example #2
0
        public static bool CheckForLicense(User retrievedUser, ISubscribedSku sku, Collection <string> assignedPlans, Collection <string> disabledPlans)
        {
            //************************************************************************************************************************************************************************************
            //  To be sure we dont make unneccessary calls to the Graph API which counts against our throttling policy we should check to see if the user already has the plans that you want
            //  enabled.  To accomplish this, we loop through all the user's currently assigned licenses and find the SKU we want to evaluate.  For those plans in the matching sku we check to
            //  see if the service plans are not in that user's disabled plans, this tells us if that service plan is already assigned.
            //
            //  Now that we have all the plans that are currently assigned to the user we can compare them against the plans you want to assign to the use, that are passed in from the config
            //  XML file.  If the plans all match return false, if a plan is found that isnt in the users assigned plans, immediately return true.
            //************************************************************************************************************************************************************************************

            bool check = true;
            Collection <string> userPlans = new Collection <string>();

            #region Get all users enabled plans for the SKU passed

            //  Find all the user's assigned plans for the SKU passed.
            foreach (AssignedLicense lic in retrievedUser.AssignedLicenses)
            {
                if (lic.SkuId == sku.SkuId)
                {
                    foreach (ServicePlanInfo sp in sku.ServicePlans)
                    {
                        if (!lic.DisabledPlans.Contains(new Guid(sp.ServicePlanId.Value.ToString())))
                        {
                            userPlans.Add(sp.ServicePlanId.ToString());
                        }
                    }
                }
            }
            #endregion

            #region Check all the plans you want assigned against the user's currently assigned plans.

            //  Compare assigned plans with the plans passed in from the XML file.
            foreach (string planToCheck in assignedPlans)
            {
                if (userPlans.Contains(planToCheck))
                {
                    check = false;
                }
                else
                {
                    check = true;
                    break;
                }
            }
            #endregion

            return(check);
        }
Example #3
0
        public static Collection <string> GetDisabledPlans(ISubscribedSku sku, Collection <string> enabledPlans)
        {
            //************************************************************************************************************************************************************************************
            //  Loop through the plans for the sku you want to enable, retrieved from graph.  If the service plan does not match one of the plans that you want to enable for this user (plans
            //  from the XML config file), then add the plan to the collection of disabled plans.
            //
            //  The logic for this is that you have to give the plans you want disabled when assigning a sku.  However, we want to do our check for enabled plans since we dont want to have two
            //  of these processes fighting back and forth, enabling and disabling users.
            //
            //  Also, note that Yammer is always in pending activation, no matter what and therefore needs to be excluded.
            //************************************************************************************************************************************************************************************
            #region Get Disabled Plans from Sku
            Collection <string> disabledPlans = new Collection <string>();

            foreach (ServicePlanInfo lic in sku.ServicePlans)
            {
                if (!enabledPlans.Contains(lic.ServicePlanId.ToString()) && (!lic.ServicePlanName.Contains("YAMMER")))
                {
                    disabledPlans.Add(lic.ServicePlanId.ToString());
                }
            }
            #endregion
            return(disabledPlans);
        }
Example #4
0
        static void Main(string[] args)
        {
            #region Ensure Log File is Created
            CheckLogFile();
            #endregion

            #region Check Args Passed To App
            bool verbose = CheckArgs(args);
            #endregion

            #region Read XML Config
            //*************************************************************************************************************************************************************************************
            //  Read in the configuration information from the XML file (config.xml) in the same directory as the application.  These will be the variables used to connect to Azure Active
            //  Directory and ensure the right licenses for each user is assigned.  In most cases where the XML variable provided isnt multivalue, we use the .First() function to be sure
            //  we dont get a null reference exception when loading the XML.
            //*************************************************************************************************************************************************************************************
            XElement xml             = XElement.Load("config.xml");
            var      tenantName      = xml.Descendants("tenantname").First().Value;
            var      tenantID        = xml.Descendants("tenantid").First().Value;
            var      clientID        = xml.Descendants("clientid").First().Value;
            var      clientSecret    = xml.Descendants("clientsecret").First().Value;
            var      adminUPN        = xml.Descendants("adminupn").First().Value;
            var      adminPass       = xml.Descendants("adminpassword").First().Value;
            var      groupbased      = xml.Descendants("groupbased").First().Value;
            var      aadgroup        = xml.Descendants("aadgroupobjectid").First().Value;
            var      assignedPlanID  = xml.Descendants("skuid").First().Value;
            var      enabledPlansXML = xml.Descendants("enabledplanid");
            var      removeSku       = xml.Descendants("removeskuid");

            Collection <string> removeSkus = new Collection <string>();
            foreach (var rs in removeSku)
            {
                removeSkus.Add(rs.Value.ToString());
            }

            Collection <string> enabledPlans = new Collection <string>();

            foreach (var ep in enabledPlansXML)
            {
                enabledPlans.Add(ep.Value.ToString());
            }

            #endregion

            #region Setup Active Directory Client

            //*************************************************************************************************************************************************************************************
            //  Setup the Active Directory Client, thanks to Danny Strockis (https://github.com/AzureADSamples/ConsoleApp-GraphAPI-DotNet) for the Helper and Authentication Helper classes.  This
            //  will create a connection to AAD via Graph based on the information provided in the above XML config file.  The authentication is done using an application object of the clientID
            //  provided.
            //*************************************************************************************************************************************************************************************
            ActiveDirectoryClient activeDirectoryClient;
            Console.WriteLine("Connecting to AAD Graph...");
            try
            {
                activeDirectoryClient = AuthenticationHelper.GetActiveDirectoryClientAsApplication(tenantID, clientID, clientSecret, tenantName);
            }
            catch (AuthenticationException ex)
            {
                ToggleConsoleColor();
                Console.WriteLine("Acquiring a token failed with the following error: {0}", ex.Message);
                WriteLogs("Error", "Unable to Authenticate with AAD.  " + ex.Message, "ActiveDirectoryClient");
                if (ex.InnerException != null)
                {
                    Console.WriteLine("Error detail: {0}", ex.InnerException.Message);
                    WriteLogs("Error", "Unable to Authenticate with AAD.  " + ex.InnerException.Message, "ActiveDirectoryClient");
                }
                ToggleConsoleColor();
                return;
            }

            #endregion

            #region Get Usage Location if None Provided
            //  We get the usage location from the Tenant information.
            string usageLocation = GetUsageLocation(activeDirectoryClient, tenantName);
            #endregion

            #region Get Users to License
            //  Create a collection of strings to hold the users to apply a license to.
            //  Check to see if we are going to be licensing a group or all unlicensed users.
            Collection <string> unlicensedUsers = new Collection <string>();
            if (groupbased.ToLower() == "false")
            {
                Console.WriteLine("Getting all Unlicensed users...");
                unlicensedUsers = GetUnlicensedUsers(adminUPN, adminPass);
            }
            else if (groupbased.ToLower() == "true")
            {
                Console.WriteLine("Getting all user in group " + aadgroup.ToString() + "...");
                unlicensedUsers = GetUnlicensedUsers(aadgroup.ToString(), adminUPN, adminPass);
            }
            #endregion

            #region Get Available Licenses from Tenant
            //  Get the License information for the SKU ID matching the SKU ID passed through the XML file.
            ISubscribedSku sku = GetSubscribedSkus(activeDirectoryClient, assignedPlanID);
            #endregion

            #region AssignLicenses
            //*************************************************************************************************************************************************************************************
            //  Assign Licenses to the users returned in the group search or unlicensed users search.  We need to do some queries first to ensure the user information retrieved from graph.
            //  We then use that user information to ensure the user location is set correctly (or else license assignment will fail), get the disabled plans for the user's sku that is to
            //  be assigned.  Finally, check to see if the user's license set is already has the plans you want to enable for that user.
            //*************************************************************************************************************************************************************************************
            foreach (string upn in unlicensedUsers)
            {
                User retrievedUser = FindUser(upn, activeDirectoryClient);

                //  If user info isnt null and the user location doesnt match the tenants location, set the location
                if (retrievedUser.UsageLocation != usageLocation.ToString() && retrievedUser.UserPrincipalName != null)
                {
                    SetUserLocation(retrievedUser, usageLocation);
                }

                //  If the user is found and valid, find the plans you need to enable / disable.
                if (retrievedUser.UserPrincipalName != null)
                {
                    Collection <string> disabledPlans = GetDisabledPlans(sku, enabledPlans);
                    bool checkLicense = CheckForLicense(retrievedUser, sku, enabledPlans, disabledPlans);

                    //  If user already has the licences you want to assign, dont assign them again.
                    if (checkLicense)
                    {
                        //  If there are SKUs to be removed as part of the licensing process use the overload that removes sku's.
                        if (removeSkus.Count > 0)
                        {
                            AssignLicense(retrievedUser, assignedPlanID, disabledPlans, removeSkus, verbose);
                        }
                        else
                        {
                            AssignLicense(retrievedUser, assignedPlanID, disabledPlans, verbose);
                        }
                    }
                    else
                    {
                        //  If -v is passed then write to the screen.
                        if (verbose)
                        {
                            Console.WriteLine(retrievedUser.UserPrincipalName + " already has these plans enabled for this SKU.");
                        }
                    }
                }
            }
            #endregion
        }