diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs index 8b6f1e32..fee2d2d2 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/RemoteDesktopServicesProxy.cs @@ -515,8 +515,9 @@ namespace WebsitePanel.EnterpriseServer { /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetFreeRdsServersPaged", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] - public RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { + public RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { object[] results = this.Invoke("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, @@ -526,8 +527,9 @@ namespace WebsitePanel.EnterpriseServer { } /// - public System.IAsyncResult BeginGetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, System.AsyncCallback callback, object asyncState) { + public System.IAsyncResult BeginGetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, System.AsyncCallback callback, object asyncState) { return this.BeginInvoke("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, @@ -542,16 +544,17 @@ namespace WebsitePanel.EnterpriseServer { } /// - public void GetFreeRdsServersPagedAsync(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - this.GetFreeRdsServersPagedAsync(filterColumn, filterValue, sortColumn, startRow, maximumRows, null); + public void GetFreeRdsServersPagedAsync(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { + this.GetFreeRdsServersPagedAsync(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows, null); } /// - public void GetFreeRdsServersPagedAsync(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, object userState) { + public void GetFreeRdsServersPagedAsync(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, object userState) { if ((this.GetFreeRdsServersPagedOperationCompleted == null)) { this.GetFreeRdsServersPagedOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetFreeRdsServersPagedOperationCompleted); } this.InvokeAsync("GetFreeRdsServersPaged", new object[] { + packageId, filterColumn, filterValue, sortColumn, diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs index 3179899a..e0bbf5b9 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/RemoteDesktopServices/RemoteDesktopServicesController.cs @@ -93,9 +93,9 @@ namespace WebsitePanel.EnterpriseServer return GetRdsServersPagedInternal(filterColumn, filterValue, sortColumn, startRow, maximumRows); } - public static RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) + public static RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - return GetFreeRdsServersPagedInternal(filterColumn, filterValue, sortColumn, startRow, maximumRows); + return GetFreeRdsServersPagedInternal(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows); } public static RdsServersPaged GetOrganizationRdsServersPaged(int itemId, int? collectionId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) @@ -477,17 +477,26 @@ namespace WebsitePanel.EnterpriseServer return result; } - private static RdsServersPaged GetFreeRdsServersPagedInternal(string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) + private static RdsServersPaged GetFreeRdsServersPagedInternal(int itemId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - DataSet ds = DataProvider.GetRDSServersPaged(null, null, filterColumn, filterValue, sortColumn, startRow, maximumRows); - RdsServersPaged result = new RdsServersPaged(); + Organization org = OrganizationController.GetOrganization(itemId); + + if (org == null) + { + return result; + } + + var rds = GetRemoteDesktopServices(GetRemoteDesktopServiceID(org.PackageId)); + var existingServers = rds.GetServersExistingInCollections(); + + DataSet ds = DataProvider.GetRDSServersPaged(null, null, filterColumn, filterValue, sortColumn, startRow, maximumRows); result.RecordsCount = (int)ds.Tables[0].Rows[0][0]; List tmpServers = new List(); ObjectUtils.FillCollectionFromDataView(tmpServers, ds.Tables[1].DefaultView); - + tmpServers = tmpServers.Where(x => !existingServers.Select(y => y.ToUpper()).Contains(x.FqdName.ToUpper())).ToList(); result.Servers = tmpServers.ToArray(); return result; diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs index f05d3ca3..4323237f 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esRemoteDesktopServices.asmx.cs @@ -99,10 +99,10 @@ namespace WebsitePanel.EnterpriseServer } [WebMethod] - public RdsServersPaged GetFreeRdsServersPaged(string filterColumn, string filterValue, + public RdsServersPaged GetFreeRdsServersPaged(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows) { - return RemoteDesktopServicesController.GetFreeRdsServersPaged(filterColumn, filterValue, + return RemoteDesktopServicesController.GetFreeRdsServersPaged(packageId, filterColumn, filterValue, sortColumn, startRow, maximumRows); } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs index acb3cc5d..2a9800fc 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.Base/RemoteDesktopServices/IRemoteDesktopServices.cs @@ -64,5 +64,6 @@ namespace WebsitePanel.Providers.RemoteDesktopServices string[] GetApplicationUsers(string collectionName, string applicationName); bool SetApplicationUsers(string collectionName, RemoteApplication remoteApp, string[] users); bool CheckRDSServerAvaliable(string hostname); + List GetServersExistingInCollections(); } } diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs index 77fe591f..bfb230f0 100644 --- a/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.Providers.TerminalServices.Windows2012/Windows2012.cs @@ -220,7 +220,15 @@ namespace WebsitePanel.Providers.RemoteDesktopServices try { - runSpace = OpenRunspace(); + runSpace = OpenRunspace(); + + var existingServers = GetServersExistingInCollections(runSpace); + existingServers = existingServers.Select(x => x.ToUpper()).Intersect(collection.Servers.Select(x => x.FqdName.ToUpper())).ToList(); + + if (existingServers.Any()) + { + throw new Exception(string.Format("Server{0} {1} already added to another collection", existingServers.Count == 1 ? "" : "s", string.Join(" ,", existingServers.ToArray()))); + } foreach (var server in collection.Servers) { @@ -302,6 +310,24 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return result; } + public List GetServersExistingInCollections() + { + Runspace runSpace = null; + List existingServers = new List(); + + try + { + runSpace = OpenRunspace(); + existingServers = GetServersExistingInCollections(runSpace); + } + finally + { + CloseRunspace(runSpace); + } + + return existingServers; + } + public RdsCollection GetCollection(string collectionName) { RdsCollection collection =null; @@ -1380,6 +1406,23 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return ExecuteShellCommand(runSpace, invokeCommand, false); } + internal Collection ExecuteRemoteShellCommand(Runspace runSpace, string hostName, List scripts, params string[] moduleImports) + { + Command invokeCommand = new Command("Invoke-Command"); + invokeCommand.Parameters.Add("ComputerName", hostName); + + RunspaceInvoke invoke = new RunspaceInvoke(); + string commandString = moduleImports.Any() ? string.Format("import-module {0};", string.Join(",", moduleImports)) : string.Empty; + + commandString = string.Format("{0};{1}", commandString, string.Join(";", scripts.ToArray())); + + ScriptBlock sb = invoke.Invoke(string.Format("{{{0}}}", commandString))[0].BaseObject as ScriptBlock; + + invokeCommand.Parameters.Add("ScriptBlock", sb); + + return ExecuteShellCommand(runSpace, invokeCommand, false); + } + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd) { return ExecuteShellCommand(runSpace, cmd, true); @@ -1396,6 +1439,38 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return ExecuteShellCommand(runSpace, cmd, true, out errors); } + internal Collection ExecuteShellCommand(Runspace runspace, List scripts, out object[] errors) + { + Log.WriteStart("ExecuteShellCommand"); + var errorList = new List(); + Collection results; + + using (Pipeline pipeLine = runspace.CreatePipeline()) + { + foreach (string script in scripts) + { + pipeLine.Commands.AddScript(script); + } + + results = pipeLine.Invoke(); + + if (pipeLine.Error != null && pipeLine.Error.Count > 0) + { + foreach (object item in pipeLine.Error.ReadToEnd()) + { + errorList.Add(item); + string errorMessage = string.Format("Invoke error: {0}", item); + Log.WriteWarning(errorMessage); + } + } + } + + errors = errorList.ToArray(); + Log.WriteEnd("ExecuteShellCommand"); + + return results; + } + internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors) { @@ -1517,6 +1592,29 @@ namespace WebsitePanel.Providers.RemoteDesktopServices return result; } + internal List GetServersExistingInCollections(Runspace runSpace) + { + var existingHosts = new List(); + var scripts = new List(); + scripts.Add(string.Format("$sessions = Get-RDSessionCollection -ConnectionBroker {0}", ConnectionBroker)); + scripts.Add(string.Format("foreach($session in $sessions){{Get-RDSessionHost $session.CollectionName -ConnectionBroker {0}|Select SessionHost}}", ConnectionBroker)); + object[] errors; + + var sessionHosts = ExecuteShellCommand(runSpace, scripts, out errors); + + foreach(var host in sessionHosts) + { + var sessionHost = GetPSObjectProperty(host, "SessionHost"); + + if (sessionHost != null) + { + existingHosts.Add(sessionHost.ToString()); + } + } + + return existingHosts; + } + #endregion } } diff --git a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs index 79bd1a40..65ca3c47 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server.Client/RemoteDesktopServicesProxy.cs @@ -71,6 +71,8 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { private System.Threading.SendOrPostCallback CheckRDSServerAvaliableOperationCompleted; + private System.Threading.SendOrPostCallback GetServersExistingInCollectionsOperationCompleted; + /// public RemoteDesktopServices() { this.Url = "http://localhost:9003/RemoteDesktopServices.asmx"; @@ -139,6 +141,9 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { /// public event CheckRDSServerAvaliableCompletedEventHandler CheckRDSServerAvaliableCompleted; + /// + public event GetServersExistingInCollectionsCompletedEventHandler GetServersExistingInCollectionsCompleted; + /// [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/CreateCollection", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] @@ -1068,6 +1073,45 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { } } + /// + [System.Web.Services.Protocols.SoapHeaderAttribute("ServiceProviderSettingsSoapHeaderValue")] + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/server/GetServersExistingInCollections", RequestNamespace="http://smbsaas/websitepanel/server/", ResponseNamespace="http://smbsaas/websitepanel/server/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public string[] GetServersExistingInCollections() { + object[] results = this.Invoke("GetServersExistingInCollections", new object[0]); + return ((string[])(results[0])); + } + + /// + public System.IAsyncResult BeginGetServersExistingInCollections(System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("GetServersExistingInCollections", new object[0], callback, asyncState); + } + + /// + public string[] EndGetServersExistingInCollections(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((string[])(results[0])); + } + + /// + public void GetServersExistingInCollectionsAsync() { + this.GetServersExistingInCollectionsAsync(null); + } + + /// + public void GetServersExistingInCollectionsAsync(object userState) { + if ((this.GetServersExistingInCollectionsOperationCompleted == null)) { + this.GetServersExistingInCollectionsOperationCompleted = new System.Threading.SendOrPostCallback(this.OnGetServersExistingInCollectionsOperationCompleted); + } + this.InvokeAsync("GetServersExistingInCollections", new object[0], this.GetServersExistingInCollectionsOperationCompleted, userState); + } + + private void OnGetServersExistingInCollectionsOperationCompleted(object arg) { + if ((this.GetServersExistingInCollectionsCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.GetServersExistingInCollectionsCompleted(this, new GetServersExistingInCollectionsCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { base.CancelAsync(userState); @@ -1509,4 +1553,30 @@ namespace WebsitePanel.Providers.RemoteDesktopServices { } } } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + public delegate void GetServersExistingInCollectionsCompletedEventHandler(object sender, GetServersExistingInCollectionsCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class GetServersExistingInCollectionsCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal GetServersExistingInCollectionsCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public string[] Result { + get { + this.RaiseExceptionIfNecessary(); + return ((string[])(this.results[0])); + } + } + } } diff --git a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs index facdb011..3af935f3 100644 --- a/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.Server/RemoteDesktopServices.asmx.cs @@ -410,5 +410,22 @@ namespace WebsitePanel.Server throw; } } + + [WebMethod, SoapHeader("settings")] + public List GetServersExistingInCollections() + { + try + { + Log.WriteStart("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName); + var result = RDSProvider.GetServersExistingInCollections(); + Log.WriteEnd("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName); + return result; + } + catch (Exception ex) + { + Log.WriteError(String.Format("'{0}' GetServersExistingInCollections", ProviderSettings.ProviderName), ex); + throw; + } + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx index f3dc6d89..27771dda 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/App_GlobalResources/WebsitePanel_SharedResources.ascx.resx @@ -5626,4 +5626,7 @@ You cannot use a IDN domain name for organizations + + Collection not created + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs index 8b8f8f72..1af8a885 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/Code/Helpers/RDSHelper.cs @@ -71,9 +71,9 @@ namespace WebsitePanel.Portal return rdsServers.Servers; } - public RdsServer[] GetFreeRDSServers() + public RdsServer[] GetFreeRDSServers(int packageId) { - return ES.Services.RDS.GetFreeRdsServersPaged("", "", "", 0, 1000).Servers; + return ES.Services.RDS.GetFreeRdsServersPaged(packageId, "", "", "", 0, 1000).Servers; } #endregion diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs index cd879f04..f0ed0cd1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/AddRDSServer.ascx.cs @@ -50,7 +50,7 @@ namespace WebsitePanel.Portal.RDS private void BindRDSServers() { - ddlServers.DataSource = new RDSHelper().GetFreeRDSServers(); + ddlServers.DataSource = new RDSHelper().GetFreeRDSServers(PanelRequest.ItemID); ddlServers.DataTextField = "Name"; ddlServers.DataValueField = "Id"; ddlServers.DataBind(); diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs index ba53d8a8..e8ee55af 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/RDS/RDSCreateCollection.ascx.cs @@ -50,7 +50,9 @@ namespace WebsitePanel.Portal.RDS protected void btnSave_Click(object sender, EventArgs e) { if (!Page.IsValid) + { return; + } try { @@ -59,14 +61,15 @@ namespace WebsitePanel.Portal.RDS messageBox.ShowErrorMessage("RDS_CREATE_COLLECTION_RDSSERVER_REQUAIRED"); return; } + RdsCollection collection = new RdsCollection{ Name = txtCollectionName.Text, Servers = servers.GetServers(), Description = "" }; - ES.Services.RDS.AddRdsCollection(PanelRequest.ItemID, collection); - - Response.Redirect(EditUrl("ItemID", PanelRequest.ItemID.ToString(), "rds_collections", - "SpaceID=" + PanelSecurity.PackageId)); + Response.Redirect(EditUrl("ItemID", PanelRequest.ItemID.ToString(), "rds_collections", "SpaceID=" + PanelSecurity.PackageId)); + } + catch (Exception ex) + { + messageBox.ShowErrorMessage("RDSCOLLECTION_NOT_CREATED", ex); } - catch { } } } } \ No newline at end of file