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; }
// 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); } } }
public static void DeleteCatalog(string name) { try { string script = ScriptNames.DeleteDesktopGroupScript; logger.Info("Deleting Catalog corresponding with name " + name); Dictionary<string, object> psargs = new Dictionary<string, object>(); psargs.Add("ddcAddress", DT2.Properties.Settings.Default.XenDesktopAdminAddress); psargs.Add("catalogName", name); psargs.Add("desktopGrpName", name + ScriptNames.DesktopGroupSuffix); var jsonEquiv2 = Newtonsoft.Json.JsonConvert.SerializeObject(psargs); logger.Info("Calling " + script + " with args: " + jsonEquiv2); var poshScript = new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder, script)); poshScript.IgnoreExceptions.Add(PoshSdkConsts.PartialDataException); LoginViewModel clientId = LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket); string ndcContext = log4net.NDC.Pop(); log4net.NDC.Push(ndcContext); Task.Run(() => RunLongScript(poshScript, psargs, clientId, ndcContext)); } catch (Exception e) { var errMsg = e.Message; logger.Error(errMsg); } }
public static void CreateCatalog(Catalog newCat) { try { var jsonEquiv = Newtonsoft.Json.JsonConvert.SerializeObject(newCat); logger.Info("Creating Catalog corresponding to " + Newtonsoft.Json.JsonConvert.ToString(jsonEquiv)); Dictionary<string, object> psargs = new Dictionary<string, object>(); psargs.Add("ddcAddress", DT2.Properties.Settings.Default.XenDesktopAdminAddress); psargs.Add("catalogName", newCat.Name); psargs.Add("catalogDesc", newCat.Description); psargs.Add("catalogSessionSupport", GetXenDesktopDesktopSessionSupport(newCat.DesktopType)); psargs.Add("desktopAllocationType", GetXenDesktopDesktopAllocationType(newCat.DesktopType)); psargs.Add("persistUserChanges", GetXenDesktopDesktopPersistUserChanges(newCat.DesktopType)); psargs.Add("desktopCleanOnBoot", GetXenDesktopDesktopCleanOnBoot(newCat.DesktopType)); psargs.Add("desktopDomain", DT2.Properties.Settings.Default.XenDesktopDomain); psargs.Add("templatePath", newCat.Template); psargs.Add("networkPath", newCat.Network); psargs.Add("hostingUnitName", DT2.Properties.Settings.Default.XenDesktopHostingUnitName); psargs.Add("controllerAddress", DT2.Properties.Settings.Default.XenDesktopDDC); logger.Info("Catalog has " + newCat.Users.Length + " AD accounts and " + newCat.Count + " machines."); psargs.Add("desktopCount", newCat.Count); psargs.Add("computerOffering", newCat.ComputeOffering); // Naming scheme: Remove spaces and other special characters from the pool name, truncate at 12 characters string desktopNamingScheme = newCat.Name.Replace(" ", string.Empty); desktopNamingScheme = desktopNamingScheme.Length > 12 ? desktopNamingScheme.Substring(0, 12) : desktopNamingScheme; desktopNamingScheme += "###"; psargs.Add("desktopNamingScheme", desktopNamingScheme); // Parameters required to setup the corresponding desktopgroup psargs.Add("userNames", newCat.Users); psargs.Add("desktopGrpName", newCat.Name + ScriptNames.DesktopGroupSuffix); psargs.Add("machineCount", newCat.Count); string secGrps = DT2.Properties.Settings.Default.SecurityGroups; secGrps = secGrps ?? String.Empty; if (!string.IsNullOrEmpty((newCat.SecurityGroup))) { secGrps = newCat.SecurityGroup; } psargs.Add("securityGroups", secGrps); var poshScript = new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder, ScriptNames.CreateDesktopGroupScript)); var jsonEquiv2 = Newtonsoft.Json.JsonConvert.SerializeObject(psargs); logger.Info("Calling " + ScriptNames.CreateDesktopGroupScript + " with args: " + jsonEquiv2); var exToIgnore = "Citrix.Broker.Admin.SDK.SdkOperationException"; poshScript.IgnoreExceptions.Add(exToIgnore); logger.Info("Ignoring exceptions of type " + exToIgnore + " because the SDK generates them for Get-BrokerUser calls as part of normal operation."); // Assert if (newCat.DesktopType == PublishedDesktops) { if ("Random" != (string) psargs["desktopAllocationType"]) { var errMsg = "Wrong desktopAllocationType for " + newCat.Name + " of type " + newCat.DesktopType; throw new ArgumentException(errMsg); } if ("MultiSession" != (string) psargs["catalogSessionSupport"]) { var errMsg = "Wrong catalogSessionSupport for " + newCat.Name + " of type " + newCat.DesktopType; throw new ArgumentException(errMsg); } if ("Discard" != (string) psargs["persistUserChanges"]) { var errMsg = "Wrong persistUserChanges for " + newCat.Name + " of type " + newCat.DesktopType; throw new ArgumentException(errMsg); } if (psargs["desktopCleanOnBoot"] == null) { var errMsg = "Wrong desktopCleanOnBoot for " + newCat.Name + " of type " + newCat.DesktopType; throw new ArgumentException(errMsg); } } if (DT2.Properties.Settings.Default.TestDisableCatalogCreate) { logger.Warn("Skipping Catalog create, as TestDisableCatalogCreate is set true"); } else { // Enable Windows Authentication in ASP.NET *and* IIS to ensure User.Identity is a FormsIdentity LoginViewModel clientId = LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket); // add the ndc context string ndcContext = log4net.NDC.Pop(); log4net.NDC.Push(ndcContext); Task.Run(() => RunLongScript(poshScript, psargs, clientId, ndcContext,() => { EmailAdmin(newCat, clientId); })); } } catch (Exception e) { var errMsg = e.Message; logger.Error(errMsg); } }
public static void AddMachineToCatalog(Catalog newCat) { try { var jsonEquiv = Newtonsoft.Json.JsonConvert.SerializeObject(newCat); logger.Info("Adding Machine to Catalog corresponding to " + Newtonsoft.Json.JsonConvert.ToString(jsonEquiv)); Dictionary<string, object> psargs = new Dictionary<string, object>(); psargs.Add("ddcAddress", DT2.Properties.Settings.Default.XenDesktopAdminAddress); psargs.Add("catalogName", newCat.Name); psargs.Add("newDesktopCount", newCat.Count); // Parameters required to setup the corresponding desktopgroup psargs.Add("desktopGrpName", newCat.Name + ScriptNames.DesktopGroupSuffix); var poshScript = new PsWrapper(Path.Combine(DT2.Properties.Settings.Default.PowerShellScriptsFolder, ScriptNames.AddToDesktopGroupScript)); var jsonEquiv2 = Newtonsoft.Json.JsonConvert.SerializeObject(psargs); logger.Info("Calling " + ScriptNames.AddToDesktopGroupScript + " with args: " + jsonEquiv2); var exToIgnore = "Citrix.Broker.Admin.SDK.SdkOperationException"; poshScript.IgnoreExceptions.Add(exToIgnore); logger.Info("Ignoring exceptions of type " + exToIgnore + " because the SDK generates them for Get-BrokerUser calls as part of normal operation."); // Enable Windows Authentication in ASP.NET *and* IIS to ensure User.Identity is a FormsIdentity LoginViewModel clientId = LoginViewModel.JsonDeserialize(((FormsIdentity) HttpContext.Current.User.Identity).Ticket); // add the ndc context string ndcContext = log4net.NDC.Pop(); log4net.NDC.Push(ndcContext); Task.Run(() => RunLongScript(poshScript, psargs, clientId, ndcContext, () => { EmailAdmin(newCat, clientId); })); } catch (Exception e) { var errMsg = e.Message; logger.Error(errMsg); } }
/// <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. }