// TODO: are Catalogs available limited to this user?
        public static List<Machine> GetMachines(string catalogName)
        {
            var result = new List<Machine>();

            try
            {
                // Catalog query provides user-defined descriptions such as Name and Description
                Dictionary<string, object> psargs = new Dictionary<string, object>();
                var getDetailsScript = new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,ScriptNames.GetMachines));

                logger.Info("Getting the details for Catalog corresponding to " + catalogName );
                psargs.Add("catalogName", catalogName);
                var jsonEquiv = Newtonsoft.Json.JsonConvert.SerializeObject(psargs);
                logger.Info("Calling " + ScriptNames.GetMachines + " with args: " + jsonEquiv);

                getDetailsScript.IgnoreExceptions.Add(PoshSdkConsts.PartialDataException);

                LoginViewModel clientId =
                    LoginViewModel.JsonDeserialize(((FormsIdentity)HttpContext.Current.User.Identity).Ticket);
                var psCats = getDetailsScript.RunPowerShell(psargs, clientId);

                foreach (PSObject item in psCats)
                {
                    var newMachine = new Machine();
                    newMachine.AssociatedUserNames = (string[])(item.Members["AssociatedUserNames"].Value ?? new String[0]);
                    newMachine.Capabilities = (string[])(item.Members["Capabilities"].Value ?? new String[0]);
                    newMachine.CatalogName = (string)(item.Members["CatalogName"].Value ?? string.Empty);
                    newMachine.CatalogUid = (int)(item.Members["CatalogUid"].Value ?? string.Empty);
                    newMachine.DesktopGroupName = (string)(item.Members["DesktopGroupName"].Value ?? string.Empty);
                    newMachine.DesktopGroupUid = (int)(item.Members["DesktopGroupUid"].Value ?? string.Empty);
                    newMachine.DesktopKind = (item.Members["DesktopKind"].Value ?? string.Empty).ToString();
                    newMachine.DesktopUid = (int)(item.Members["DesktopUid"].Value ?? string.Empty);
                    newMachine.DNSName = (string)(item.Members["DNSName"].Value ?? string.Empty);
                    newMachine.HypervisorConnectionUid = (int)(item.Members["HypervisorConnectionUid"].Value ?? string.Empty);
                    newMachine.InMaintenanceMode = (bool)(item.Members["InMaintenanceMode"].Value ?? string.Empty);
                    newMachine.MachineName = (string)(item.Members["MachineName"].Value ?? string.Empty);
                    newMachine.PersistUserChanges = (item.Members["PersistUserChanges"].Value ?? string.Empty).ToString();
                    newMachine.PowerState = (item.Members["PowerState"].Value ?? string.Empty).ToString(); ;
                    newMachine.RegistrationState = (item.Members["RegistrationState"].Value ?? string.Empty).ToString();
                    newMachine.SessionCount = (int)(item.Members["SessionCount"].Value ?? string.Empty);
                    newMachine.SupportedPowerActions = (string[])(item.Members["SupportedPowerActions"].Value ?? new String[0]);
                    newMachine.Uid = (int)(item.Members["Uid"].Value ?? string.Empty);

                    var newMachineJson = Newtonsoft.Json.JsonConvert.SerializeObject(newMachine);
                    logger.Info("Discovered Machine: " + newMachineJson);
                    result.Add(newMachine);
                } // End foreach.
            }
            catch (Exception e)
            {
                var errMsg = e.Message;
                logger.Error(errMsg);
            }

            return result;
        }
 private static void RunLongScript(PsWrapper script, Dictionary<string, object> psargs, LoginViewModel clientId,
     string ndcContext,
     Action callAction = null)
 {
     using (log4net.NDC.Push(ndcContext))
     {
         try
         {
             script.RunPowerShell(psargs, clientId);
             logger.Info("Completed RunPowerShell ");
             if (callAction != null)
             {
                 logger.Info("Completed RunPowerShell, and calling callAction");
                 callAction();
             }
         }
         catch (Exception e)
         {
             var errMsg = e.Message;
             logger.Error("In RunLongScript we saw exception with message " + errMsg);
         }
     }
 }
 private static Collection<PSObject> InvokeScript(string scriptName, string xenDestkopPath)
 {
     Dictionary<string, object> psargs = new Dictionary<string, object>();
     psargs.Add("path", xenDestkopPath);
     var listNetsScript = new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder, scriptName));
     LoginViewModel clientId = LoginViewModel.JsonDeserialize(((FormsIdentity)HttpContext.Current.User.Identity).Ticket);
     
     var psNets = listNetsScript.RunPowerShell(psargs, clientId);
     return psNets;
 }
        /// <summary>
        /// The list of users associated with a DesktopGroup is in the DesktopGroupAccessPolicy.  In our case, 
        /// there are two per desktop group.  One is used when accessing the group through an AG (Access Gateway).
        /// The other is used when accessing the desktop directly.
        /// </summary>
        /// <param name="catalogName"></param>
        /// <param name="results"></param>
        private static void GetBrokerCatalogUsers(string catalogName, List<Catalog> result)
        {
            string desktopGrpAccessPolicyName = string.IsNullOrEmpty(catalogName)
                ? null
                : catalogName + ScriptNames.DesktopGroupSuffix + ScriptNames.AccessPolicySuffixForDirect;
            Dictionary<string, object> psargs = new Dictionary<string, object>();
            psargs.Add("desktopGroupPolicyName", desktopGrpAccessPolicyName);

            var listProvScript =
                new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,
                    ScriptNames.GetDesktopGroupsAccessPolicy));
            LoginViewModel clientId =
                LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket);
            var psProvs = listProvScript.RunPowerShell(psargs, clientId);

            // TODO:  add the users to the list.
            foreach (PSObject item in psProvs)
            {
                dynamic includedUsers = item.Members["IncludedUsers"].Value;
                dynamic excludedUsers = item.Members["ExcludedUsers"].Value;
                string name = (string) item.Members["Name"].Value;

                // assertions
                if (includedUsers.Length < 1)
                {
                    var errMsg = "DesktopGroup for broker catalog " + catalogName + " has no included users!";
                    logger.Error(errMsg);
                }
                if (excludedUsers.Length > 0)
                {
                    var errMsg = "DesktopGroup for broker catalog " + catalogName + " *has* excluded users!";
                    logger.Error(errMsg);
                }

                List<string> userList = new List<string>();
                foreach (dynamic user in includedUsers)
                {
                    userList.Add(user.Name);
                }

                // Update corresponding Catalog
                int assertUsage = 0;
                foreach (var cat in result)
                {
                    if (catalogName + ScriptNames.DesktopGroupSuffix + ScriptNames.AccessPolicySuffixForDirect == name)
                    {
                        assertUsage++;
                        cat.Users = userList.ToArray();
                    }
                }

                // Make sure there is a value for 'Users'
                foreach (var cat in result)
                {
                    if (cat.Users == null)
                    {
                        cat.Users = new string[0];
                        var infoMsg = "DesktopGroup for broker catalog " + catalogName + " has NO users!";
                        logger.Error(infoMsg);
                    }
                }

                // Assert
                if (assertUsage > 1)
                {
                    var errMsg = "Provisioning scheme used in multiple catalogs: name " + name;
                    logger.Error(errMsg);
                }
            } // End foreach.
        }
        /// <summary>
        /// Use this to determine if the logged in user has sufficient permissions to create a catalog.
        /// Specifically, the New-AcctADAccount call will fail if the user does not have sufficient privilege for the 
        /// domain in which new desktop machine accounts are being registered.
        /// TODO: may need to write code to reset the PowerShell environment after the script has run.
        /// </summary>
        /// <param name="catalogName"></param>
        /// <param name="results"></param>
        public static void TestADaccess()
        {
            Dictionary<string, object> psargs = new Dictionary<string, object>();
            psargs.Add("ddcAddress", DT2.Properties.Settings.Default.XenDesktopAdminAddress);
            psargs.Add("desktopDomain", DT2.Properties.Settings.Default.XenDesktopDomain);

            var listProvScript =
                new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,
                    ScriptNames.TestADAccess));
            LoginViewModel clientId =
                LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket);
            var psProvs = listProvScript.RunPowerShell(psargs, clientId);
        }
        private static void GetBrokerCatalogInfo(string catalogName, List<Catalog> result)
        {
            Dictionary<string, object> psargs = new Dictionary<string, object>();
            psargs.Add("catalogName", catalogName);

            // Catalog query provides user-defined descriptions such as Name and Description
            var listCatScript =
                new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,
                    ScriptNames.GetCatalogsDetailsScript));
            LoginViewModel clientId =
                LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket);
            var psCats = listCatScript.RunPowerShell(psargs, clientId);

            foreach (PSObject item in psCats)
            {
                string name = (string) item.Members["Name"].Value;
                int id = (int) item.Members["Uid"].Value;
                string description = (string) (item.Members["Description"].Value ?? String.Empty);
                string provid = (item.Members["ProvisioningSchemeId"].Value ?? String.Empty).ToString();

                string sessionSupport = item.Members["SessionSupport"].Value.ToString();
                string allocationType = item.Members["AllocationType"].Value.ToString();
                string desktopType = GetXenDesktopDesktopType(allocationType, sessionSupport);

                var metadata = (System.Collections.Generic.Dictionary<string, string>) item.Members["MetadataMap"].Value;
                string diaasStatus = "Undetermined";
                if (metadata.ContainsKey("DIaaS_Status"))
                {
                    diaasStatus = metadata["DIaaS_Status"];
                }

                var newCat = new Catalog()
                {
                    Name = name,
                    Description = description,
                    Id = id.ToString(),
                    // TODO: verify that count is correct.
                    Count = (int) item.Members["UnassignedCount"].Value + (int) item.Members["AssignedCount"].Value,
                    ProvisioningSchemeId = provid,
                    DesktopType = desktopType,
                    Status = diaasStatus
                };

                result.Add(newCat);
            } // End foreach.
        }
        private static void GetDesktopGroupDetails(string catalogName, List<Catalog> result)
        {
            string desktopGrpName = string.IsNullOrEmpty(catalogName)
                ? null
                : catalogName + ScriptNames.DesktopGroupSuffix;
            Dictionary<string, object> psargs = new Dictionary<string, object>();
            psargs.Add("desktopGroupName", desktopGrpName);

            var listProvScript =
                new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,
                    ScriptNames.GetDesktopGroupDetailsScript));
            LoginViewModel clientId =
                LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket);
            var psProvs = listProvScript.RunPowerShell(psargs, clientId);

            foreach (PSObject item in psProvs)
            {
                var itemtype = item.BaseObject.GetType().FullName;
                logger.Debug("GetDesktopGroupDetails processing obj of type " + itemtype);
                int totalDesktops = (int) item.Members["TotalDesktops"].Value;
                int totalSessions = (int) item.Members["Sessions"].Value;
                string name = (string) item.Members["Name"].Value;
                // Update corresponding Catalog
                int assertUsage = 0;
                foreach (var cat in result)
                {
                    if (cat.Name + ScriptNames.DesktopGroupSuffix == name)
                    {
                        assertUsage++;
                        cat.CountInUse = totalSessions;
                        cat.Count = totalDesktops;
                    }
                }

                // Assert
                if (assertUsage > 1)
                {
                    var errMsg = "Provisioning scheme used in multiple catalogs: name " + name;
                    logger.Error(errMsg);
                }
            } // End foreach.
        }
        private static void GetProvSchemeDetails(string catalogName, List<Catalog> result)
        {
            Dictionary<string, object> psargs = new Dictionary<string, object>();
            psargs.Add("catalogName", catalogName);

            var listProvScript =
                new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder,
                    ScriptNames.GetProvSchemesScript));

            LoginViewModel clientId =
                LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket);
            var psProvs = listProvScript.RunPowerShell(psargs, clientId);

            foreach (PSObject item in psProvs)
            {
                string provName = (string) item.Members["ProvisioningSchemeName"].Value;
                Guid provId = (Guid) item.Members["ProvisioningSchemeUid"].Value;
                string templatePath = (string) item.Members["MasterImageVM"].Value;
                string serviceOffering = (string) item.Members["ServiceOffering"].Value;
                string[] securityGroups = (item.Members["SecurityGroups"] == null
                    ? new string[0]
                    : (string[]) item.Members["SecurityGroups"].Value);
                string securityGroup = securityGroups.Length > 0 ? securityGroups[0] : "";
                // Assert
                if (templatePath == null)
                {
                    var errMsg = "No template for provisioning scheme " + provName;
                    logger.Error(errMsg);
                    continue;
                }

                // Assert
                if (serviceOffering == null)
                {
                    var errMsg = "No Desktop compute offering for provisioning scheme " + provName;
                    logger.Error(errMsg);
                    continue;
                }

                string[] templateSplitPath = templatePath.Split(new char[] {'\\'});
                string template = templateSplitPath[templateSplitPath.Length - 1];

                // Assert
                if (!template.EndsWith(".template"))
                {
                    var errMsg = "Template ends with wrong extension, path is " + templatePath + " template name is " +
                                 template;
                    logger.Error(errMsg);
                    continue;
                }

                // Update corresponding Catalog
                int assertUsage = 0;
                foreach (var cat in result)
                {
                    if (cat.ProvisioningSchemeId == provId.ToString())
                    {
                        assertUsage++;
                        cat.Template = template.Substring(0, template.Length - ".template".Length);
                        cat.ComputeOffering = serviceOffering.Substring(0,
                            serviceOffering.Length - ".serviceoffering".Length);
                        cat.DiskSize = (int) item.Members["DiskSize"].Value;

                        // TODO: ask SDK team for alternative to dyanamic variables
                        dynamic networkList = item.Members["NetworkMaps"].Value;
                        dynamic netDetails = networkList[0];
                        string networkPath = (string) netDetails.NetworkPath;

                        string[] networkSplitPath = networkPath.Split(new char[] {'\\'});
                        string networkName = networkSplitPath[networkSplitPath.Length - 1];
                        cat.Network = networkName.Substring(0, networkName.Length - ".network".Length);
                        cat.SecurityGroup = securityGroup;
                    }
                }

                // Assert
                if (assertUsage > 1)
                {
                    var errMsg = "Provisioning scheme used in multiple catalogs: name " + provName + " UUID " + provId;
                    logger.Error(errMsg);
                }
            } // End foreach.
        }