diff --git a/WebsitePanel/Database/update_db.sql b/WebsitePanel/Database/update_db.sql
index 351f7e6b..1547a587 100644
--- a/WebsitePanel/Database/update_db.sql
+++ b/WebsitePanel/Database/update_db.sql
@@ -450,6 +450,18 @@ INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName]
VALUES (1401, 41, N'Lync2013', N'Microsoft Lync Server 2013 Multitenant Hosting Pack', N'WebsitePanel.Providers.HostedSolution.Lync2013, WebsitePanel.Providers.HostedSolution.Lync2013', N'Lync', NULL)
END
GO
+
+UPDATE Providers SET DisplayName = N'Microsoft Lync Server 2013 Enterprise Edition' WHERE ProviderID = 1401
+GO
+
+IF NOT EXISTS (SELECT * FROM [dbo].[Providers] WHERE [ProviderName] = 'Lync2013HP')
+BEGIN
+INSERT [dbo].[Providers] ([ProviderID], [GroupID], [ProviderName], [DisplayName], [ProviderType], [EditorControl], [DisableAutoDiscovery])
+VALUES (1402, 41, N'Lync2013HP', N'Microsoft Lync Server 2013 Multitenant Hosting Pack', N'WebsitePanel.Providers.HostedSolution.Lync2013HP, WebsitePanel.Providers.HostedSolution.Lync2013HP', N'Lync', NULL)
+END
+GO
+
+
-- add Application Pools Restart Quota
IF NOT EXISTS (SELECT * FROM [dbo].[Quotas] WHERE ([QuotaName] = N'Web.AppPoolsRestart'))
diff --git a/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Core.dll b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Core.dll
new file mode 100644
index 00000000..03bab582
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Core.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Hosted.dll b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Hosted.dll
new file mode 100644
index 00000000..e7106119
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.Hosted.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.WritableConfig.dll b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.WritableConfig.dll
new file mode 100644
index 00000000..7979e9ed
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Lync2013HP/Microsoft.Rtc.Management.WritableConfig.dll differ
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Lync2013HP/Lync2013HP.cs b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Lync2013HP/Lync2013HP.cs
new file mode 100644
index 00000000..5b50555a
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Lync2013HP/Lync2013HP.cs
@@ -0,0 +1,1546 @@
+// Copyright (c) 2012, Outercurve Foundation.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the Outercurve Foundation nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Reflection;
+using System.Globalization;
+using System.DirectoryServices;
+
+using Microsoft.Win32;
+
+using WebsitePanel.Providers;
+using WebsitePanel.Providers.HostedSolution;
+using WebsitePanel.Providers.Utils;
+using WebsitePanel.Server.Utils;
+
+using System.Management;
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+
+//using Microsoft.Rtc.Management.Hosted;
+using Microsoft.Rtc.Management.WritableConfig.Settings.Edge;
+using Microsoft.Rtc.Management.WritableConfig.Settings.SimpleUrl;
+
+
+namespace WebsitePanel.Providers.HostedSolution
+{
+ public class Lync2013HP : HostingServiceProviderBase, ILyncServer
+ {
+
+ #region Static constructor
+ static Lync2013HP()
+ {
+ LyncRegistryPath = "SOFTWARE\\Microsoft\\Real-Time Communications";
+ }
+
+ public static string LyncRegistryPath
+ {
+ get;
+ set;
+ }
+
+ #endregion
+
+
+ #region Properties
+
+ ///
+ /// Pool FQDN
+ ///
+ private string PoolFQDN
+ {
+ get { return ProviderSettings[LyncConstants.PoolFQDN]; }
+ }
+
+ private string SimpleUrlRoot
+ {
+ get { return ProviderSettings[LyncConstants.SimpleUrlRoot]; }
+ }
+
+ internal string PrimaryDomainController
+ {
+ get { return ProviderSettings["PrimaryDomainController"]; }
+ }
+
+ private string RootOU
+ {
+ get { return ProviderSettings["RootOU"]; }
+ }
+
+ private string RootDomain
+ {
+ get { return ServerSettings.ADRootDomain; }
+ }
+
+
+ #endregion
+
+ #region ILyncServer implementation
+
+ public string CreateOrganization(string organizationId, string sipDomain, bool enableConferencing, bool enableConferencingVideo, int maxConferenceSize, bool enabledFederation, bool enabledEnterpriseVoice)
+ {
+ return CreateOrganizationInternal(organizationId, sipDomain, enableConferencing, enableConferencingVideo, maxConferenceSize, enabledFederation, enabledEnterpriseVoice);
+ }
+
+ public bool DeleteOrganization(string organizationId, string sipDomain)
+ {
+ return DeleteOrganizationInternal(organizationId, sipDomain);
+ }
+
+ public bool CreateUser(string organizationId, string userUpn, LyncUserPlan plan)
+ {
+ return CreateUserInternal(organizationId, userUpn, plan);
+ }
+
+ public LyncUser GetLyncUserGeneralSettings(string organizationId, string userUpn)
+ {
+ return GetLyncUserGeneralSettingsInternal(organizationId, userUpn);
+ }
+
+ public bool SetLyncUserGeneralSettings(string organizationId, string userUpn, LyncUser lyncUser)
+ {
+ return SetLyncUserGeneralSettingsInternal(organizationId, userUpn, lyncUser);
+ }
+
+
+ public bool SetLyncUserPlan(string organizationId, string userUpn, LyncUserPlan plan)
+ {
+ return SetLyncUserPlanInternal(organizationId, userUpn, plan, null);
+ }
+
+ public bool DeleteUser(string userUpn)
+ {
+ return DeleteUserInternal(userUpn);
+ }
+
+ public LyncFederationDomain[] GetFederationDomains(string organizationId)
+ {
+ return GetFederationDomainsInternal(organizationId);
+ }
+
+ public bool AddFederationDomain(string organizationId, string domainName, string proxyFqdn)
+ {
+ return AddFederationDomainInternal(organizationId, domainName, proxyFqdn);
+ }
+
+ public bool RemoveFederationDomain(string organizationId, string domainName)
+ {
+ return RemoveFederationDomainInternal(organizationId, domainName);
+ }
+
+ public void ReloadConfiguration()
+ {
+ ReloadConfigurationInternal();
+ }
+
+ public string[] GetPolicyList(LyncPolicyType type, string name)
+ {
+ return GetPolicyListInternal(type, name);
+ }
+
+ #endregion
+
+ #region organization
+ private string CreateOrganizationInternal(string organizationId, string sipDomain, bool enableConferencing, bool enableConferencingVideo, int maxConferenceSize, bool enabledFederation, bool enabledEnterpriseVoice)
+ {
+ sipDomain = sipDomain.ToLower();
+ HostedSolutionLog.LogStart("CreateOrganizationInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("sipDomain: {0}", sipDomain);
+
+ string TenantId = string.Empty;
+
+ LyncTransaction transaction = StartTransaction();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ // create sip domain
+ Command cmd = new Command("New-CsSipDomain");
+ cmd.Parameters.Add("Identity", sipDomain);
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ transaction.RegisterNewSipDomain(sipDomain);
+
+ //set the msRTCSIP-Domains, TenantID, ObjectID
+ Guid id = Guid.NewGuid();
+
+ string path = AddADPrefix(GetOrganizationPath(organizationId));
+ DirectoryEntry ou = ActiveDirectoryUtils.GetADObject(path);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(ou, "msRTCSIP-Domains", sipDomain);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(ou, "msRTCSIP-TenantId", id);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(ou, "msRTCSIP-ObjectId", id);
+ ou.CommitChanges();
+
+ //Create simpleurls
+ CreateSimpleUrl(runSpace, sipDomain, id);
+ transaction.RegisterNewSimpleUrl(sipDomain, id.ToString());
+
+ //create conferencing policy
+ cmd = new Command("New-CsConferencingPolicy");
+ cmd.Parameters.Add("Identity", organizationId);
+
+ cmd.Parameters.Add("MaxMeetingSize", ((maxConferenceSize == -1) | (maxConferenceSize > 250)) ? 250 : maxConferenceSize);
+ cmd.Parameters.Add("AllowIPVideo", enableConferencingVideo);
+ ExecuteShellCommand(runSpace, cmd, false);
+ transaction.RegisterNewConferencingPolicy(organizationId);
+
+ //create external access policy
+ cmd = new Command("New-CsExternalAccessPolicy");
+ cmd.Parameters.Add("Identity", organizationId);
+ cmd.Parameters.Add("EnableFederationAccess", true);
+ cmd.Parameters.Add("EnableOutsideAccess", true);
+ cmd.Parameters.Add("EnablePublicCloudAccess", false);
+ cmd.Parameters.Add("EnablePublicCloudAudioVideoAccess", false);
+ ExecuteShellCommand(runSpace, cmd, false);
+ transaction.RegisterNewCsExternalAccessPolicy(organizationId);
+
+ //Enable for federation
+ AllowList allowList = new AllowList();
+ DomainPattern domain = new DomainPattern(sipDomain);
+ allowList.AllowedDomain.Add(domain);
+
+ cmd = new Command("Set-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", id);
+ cmd.Parameters.Add("AllowFederatedUsers", true);
+ cmd.Parameters.Add("AllowedDomains", allowList);
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ //create mobility policy
+ cmd = new Command("New-CsMobilityPolicy");
+ cmd.Parameters.Add("Identity", organizationId + " EnableOutSideVoice");
+ cmd.Parameters.Add("EnableMobility", true);
+ cmd.Parameters.Add("EnableOutsideVoice", true);
+ ExecuteShellCommand(runSpace, cmd, false);
+ transaction.RegisterNewCsMobilityPolicy(organizationId + " EnableOutSideVoice");
+
+ cmd = new Command("New-CsMobilityPolicy");
+ cmd.Parameters.Add("Identity", organizationId + " DisableOutSideVoice");
+ cmd.Parameters.Add("EnableMobility", true);
+ cmd.Parameters.Add("EnableOutsideVoice", false);
+ ExecuteShellCommand(runSpace, cmd, false);
+ transaction.RegisterNewCsMobilityPolicy(organizationId + " DisableOutSideVoice");
+
+ cmd = new Command("Invoke-CsManagementStoreReplication");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+
+ TenantId = id.ToString();
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("CreateOrganizationInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+
+ HostedSolutionLog.LogEnd("CreateOrganizationInternal");
+
+ return TenantId;
+ }
+
+
+
+ private bool DeleteOrganizationInternal(string organizationId, string sipDomain)
+ {
+ HostedSolutionLog.LogStart("DeleteOrganizationInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("sipDomain: {0}", sipDomain);
+
+ bool ret = true;
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ Guid tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ // create sip domain
+ string path = AddADPrefix(GetOrganizationPath(organizationId));
+ DirectoryEntry ou = ActiveDirectoryUtils.GetADObject(path);
+ string[] sipDs = (string[])ActiveDirectoryUtils.GetADObjectPropertyMultiValue(ou, "msRTCSIP-Domains");
+
+ foreach (string sipD in sipDs)
+ DeleteSipDomain(runSpace, sipD);
+
+ //clear the msRTCSIP-Domains, TenantID, ObjectID
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(ou, "msRTCSIP-Domains");
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(ou, "msRTCSIP-TenantId");
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(ou, "msRTCSIP-ObjectId");
+ ou.CommitChanges();
+
+ try
+ {
+ DeleteConferencingPolicy(runSpace, organizationId);
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteExternalAccessPolicy(runSpace, organizationId);
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteMobilityPolicy(runSpace, organizationId + " EnableOutSideVoice");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteMobilityPolicy(runSpace, organizationId + " DisableOutSideVoice");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteSimpleUrl(runSpace, sipDomain, tenantId);
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ cmd = new Command("Invoke-CsManagementStoreReplication");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ HostedSolutionLog.LogError("DeleteOrganizationInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("DeleteOrganizationInternal");
+ return ret;
+ }
+ #endregion
+
+ #region Users
+ private bool CreateUserInternal(string organizationId, string userUpn, LyncUserPlan plan)
+ {
+ HostedSolutionLog.LogStart("CreateUserInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("userUpn: {0}", userUpn);
+
+ bool ret = true;
+ Guid tenantId = Guid.Empty;
+
+ LyncTransaction transaction = StartTransaction();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ string[] tmp = userUpn.Split('@');
+ if (tmp.Length < 2) return false;
+
+ // Get SipDomains and verify existence
+ bool bSipDomainExists = false;
+ cmd = new Command("Get-CsSipDomain");
+ Collection sipDomains = ExecuteShellCommand(runSpace, cmd, false);
+
+ foreach (PSObject domain in sipDomains)
+ {
+ string d = (string)GetPSObjectProperty(domain, "Name");
+ if (d.ToLower() == tmp[1].ToLower())
+ {
+ bSipDomainExists = true;
+ break;
+ }
+ }
+
+ string path = string.Empty;
+
+ if (!bSipDomainExists)
+ {
+ // Create Sip Domain
+ cmd = new Command("New-CsSipDomain");
+ cmd.Parameters.Add("Identity", tmp[1].ToLower());
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ transaction.RegisterNewSipDomain(tmp[1].ToLower());
+
+
+ path = AddADPrefix(GetOrganizationPath(organizationId));
+ DirectoryEntry ou = ActiveDirectoryUtils.GetADObject(path);
+ string[] sipDs = (string[])ActiveDirectoryUtils.GetADObjectPropertyMultiValue(ou, "msRTCSIP-Domains");
+ List listSipDs = new List();
+ listSipDs.AddRange(sipDs);
+ listSipDs.Add(tmp[1]);
+
+ ActiveDirectoryUtils.SetADObjectPropertyValue(ou, "msRTCSIP-Domains", listSipDs.ToArray());
+ ou.CommitChanges();
+
+ //Create simpleurls
+ CreateSimpleUrl(runSpace, tmp[1].ToLower(), tenantId);
+ transaction.RegisterNewSimpleUrl(tmp[1].ToLower(), tenantId.ToString());
+ }
+
+ //enable for lync
+ cmd = new Command("Enable-CsUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("RegistrarPool", PoolFQDN);
+ cmd.Parameters.Add("SipAddressType", "UserPrincipalName");
+ ExecuteShellCommand(runSpace, cmd);
+
+ transaction.RegisterNewCsUser(userUpn);
+
+ //set groupingID and tenantID
+ cmd = new Command("Get-CsAdUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ result = ExecuteShellCommand(runSpace, cmd);
+
+ path = AddADPrefix(GetResultObjectDN(result));
+ DirectoryEntry user = ActiveDirectoryUtils.GetADObject(path);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(user, "msRTCSIP-GroupingID", tenantId);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(user, "msRTCSIP-TenantId", tenantId);
+
+ if (tmp.Length > 0)
+ {
+ string Url = SimpleUrlRoot + tmp[1];
+ ActiveDirectoryUtils.SetADObjectPropertyValue(user, "msRTCSIP-BaseSimpleUrl", Url.ToLower());
+ }
+ user.CommitChanges();
+
+ //set-plan
+ SetLyncUserPlanInternal(organizationId, userUpn, plan, runSpace);
+
+ //initiate addressbook generation
+ cmd = new Command("Update-CsAddressBook");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ //initiate user database replication
+ cmd = new Command("Update-CsUserDatabase");
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ else
+ {
+ ret = false;
+ HostedSolutionLog.LogError("Failed to retrieve tenantID", null);
+ }
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ HostedSolutionLog.LogError("CreateUserInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("CreateUserInternal");
+ return ret;
+ }
+
+ private LyncUser GetLyncUserGeneralSettingsInternal(string organizationId, string userUpn)
+ {
+ HostedSolutionLog.LogStart("GetLyncUserGeneralSettingsInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("userUpn: {0}", userUpn);
+
+ LyncUser lyncUser = new LyncUser();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-CsUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject user = result[0];
+
+ lyncUser.DisplayName = (string)GetPSObjectProperty(user, "DisplayName");
+ lyncUser.SipAddress = (string)GetPSObjectProperty(user, "SipAddress");
+ lyncUser.LineUri = (string)GetPSObjectProperty(user, "LineURI");
+
+ lyncUser.SipAddress = lyncUser.SipAddress.ToLower().Replace("sip:", "");
+ lyncUser.LineUri = lyncUser.LineUri.ToLower().Replace("tel:+", "");
+ lyncUser.LineUri = lyncUser.LineUri.ToLower().Replace("tel:", "");
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("GetLyncUserGeneralSettingsInternal", ex);
+ throw;
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("GetLyncUserGeneralSettingsInternal");
+ return lyncUser;
+ }
+
+ private bool SetLyncUserGeneralSettingsInternal(string organizationId, string userUpn, LyncUser lyncUser)
+ {
+ HostedSolutionLog.LogStart("SetLyncUserGeneralSettingsInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("userUpn: {0}", userUpn);
+
+ bool ret = true;
+ Runspace runSpace = null;
+ Guid tenantId = Guid.Empty;
+ LyncTransaction transaction = StartTransaction();
+
+ try
+ {
+ runSpace = OpenRunspace();
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ string[] tmp = userUpn.Split('@');
+ if (tmp.Length < 2) return false;
+
+ // Get SipDomains and verify existence
+ bool bSipDomainExists = false;
+ cmd = new Command("Get-CsSipDomain");
+ Collection sipDomains = ExecuteShellCommand(runSpace, cmd, false);
+
+ foreach (PSObject domain in sipDomains)
+ {
+ string d = (string)GetPSObjectProperty(domain, "Name");
+ if (d.ToLower() == tmp[1].ToLower())
+ {
+ bSipDomainExists = true;
+ break;
+ }
+ }
+
+ string path = string.Empty;
+
+ if (!bSipDomainExists)
+ {
+ // Create Sip Domain
+ cmd = new Command("New-CsSipDomain");
+ cmd.Parameters.Add("Identity", tmp[1].ToLower());
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ transaction.RegisterNewSipDomain(tmp[1].ToLower());
+
+
+ path = AddADPrefix(GetOrganizationPath(organizationId));
+ DirectoryEntry ou = ActiveDirectoryUtils.GetADObject(path);
+ string[] sipDs = (string[])ActiveDirectoryUtils.GetADObjectPropertyMultiValue(ou, "msRTCSIP-Domains");
+ List listSipDs = new List();
+ listSipDs.AddRange(sipDs);
+ listSipDs.Add(tmp[1]);
+
+ ActiveDirectoryUtils.SetADObjectPropertyValue(ou, "msRTCSIP-Domains", listSipDs.ToArray());
+ ou.CommitChanges();
+
+ //Create simpleurls
+ CreateSimpleUrl(runSpace, tmp[1].ToLower(), tenantId);
+ transaction.RegisterNewSimpleUrl(tmp[1].ToLower(), tenantId.ToString());
+
+ path = AddADPrefix(GetResultObjectDN(result));
+ DirectoryEntry user = ActiveDirectoryUtils.GetADObject(path);
+
+ if (tmp.Length > 0)
+ {
+ string Url = SimpleUrlRoot + tmp[1];
+ ActiveDirectoryUtils.SetADObjectPropertyValue(user, "msRTCSIP-BaseSimpleUrl", Url.ToLower());
+ }
+ user.CommitChanges();
+ }
+ }
+
+ cmd = new Command("Set-CsUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ if (!string.IsNullOrEmpty(lyncUser.SipAddress)) cmd.Parameters.Add("SipAddress", "SIP:" + lyncUser.SipAddress);
+ if (!string.IsNullOrEmpty(lyncUser.LineUri)) cmd.Parameters.Add("LineUri", "TEL:+" + lyncUser.LineUri);
+ else cmd.Parameters.Add("LineUri", null);
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ if (!String.IsNullOrEmpty(lyncUser.PIN))
+ {
+ cmd = new Command("Set-CsClientPin");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("Pin", lyncUser.PIN);
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+
+
+ //initiate addressbook generation
+ cmd = new Command("Update-CsAddressBook");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ //initiate user database replication
+ cmd = new Command("Update-CsUserDatabase");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ HostedSolutionLog.LogError("SetLyncUserGeneralSettingsInternal", ex);
+ RollbackTransaction(transaction);
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("SetLyncUserGeneralSettingsInternal");
+ return ret;
+ }
+
+
+
+ private bool SetLyncUserPlanInternal(string organizationId, string userUpn, LyncUserPlan plan, Runspace runSpace)
+ {
+ HostedSolutionLog.LogStart("SetLyncUserPlanInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("userUpn: {0}", userUpn);
+ bool ret = true;
+ bool bCloseRunSpace = false;
+
+ try
+ {
+ if (runSpace == null)
+ {
+ runSpace = OpenRunspace();
+ bCloseRunSpace = true;
+ }
+
+ // EnterpriseVoice
+ Command cmd = new Command("Set-CsUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("EnterpriseVoiceEnabled", plan.EnterpriseVoice);
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ //CsExternalAccessPolicy
+ cmd = new Command("Grant-CsExternalAccessPolicy");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("PolicyName", plan.Federation ? organizationId : null);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //CsConferencingPolicy
+ cmd = new Command("Grant-CsConferencingPolicy");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("PolicyName", plan.Federation ? organizationId : null);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //CsMobilityPolicy
+ cmd = new Command("Grant-CsMobilityPolicy");
+ cmd.Parameters.Add("Identity", userUpn);
+ if (plan.Mobility)
+ cmd.Parameters.Add("PolicyName", plan.MobilityEnableOutsideVoice ? organizationId + " EnableOutSideVoice" : organizationId + " DisableOutSideVoice");
+ else
+ cmd.Parameters.Add("PolicyName", null);
+ ExecuteShellCommand(runSpace, cmd);
+
+ // ArchivePolicy
+ cmd = new Command("Grant-CsArchivingPolicy");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("PolicyName", string.IsNullOrEmpty(plan.ArchivePolicy) ? null : plan.ArchivePolicy);
+ ExecuteShellCommand(runSpace, cmd);
+
+ // DialPlan
+ cmd = new Command("Grant-CsDialPlan");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("PolicyName", string.IsNullOrEmpty(plan.TelephonyDialPlanPolicy) ? null : plan.TelephonyDialPlanPolicy);
+ ExecuteShellCommand(runSpace, cmd);
+
+ // VoicePolicy
+ cmd = new Command("Grant-CsVoicePolicy");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("PolicyName", string.IsNullOrEmpty(plan.TelephonyVoicePolicy) ? null : plan.TelephonyVoicePolicy);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //initiate user database replication
+ cmd = new Command("Update-CsUserDatabase");
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ HostedSolutionLog.LogError("SetLyncUserPlanInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ if (bCloseRunSpace) CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("SetLyncUserPlanInternal");
+ return ret;
+ }
+
+
+ private bool DeleteUserInternal(string userUpn)
+ {
+ HostedSolutionLog.LogStart("DeleteUserInternal");
+ HostedSolutionLog.DebugInfo("userUpn: {0}", userUpn);
+
+ bool ret = true;
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ //Delete User
+ DeleteUser(runSpace, userUpn);
+
+ //Clear groupingID and tenantID
+ Command cmd = new Command("Get-CsAdUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ string path = AddADPrefix(GetResultObjectDN(result));
+ DirectoryEntry user = ActiveDirectoryUtils.GetADObject(path);
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(user, "msRTCSIP-GroupingID");
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(user, "msRTCSIP-TenantId");
+ ActiveDirectoryUtils.ClearADObjectPropertyValue(user, "msRTCSIP-BaseSimpleUrl");
+ user.CommitChanges();
+
+ //initiate addressbook generation
+ cmd = new Command("Update-CsAddressBook");
+ ExecuteShellCommand(runSpace, cmd, false);
+
+ //initiate user database replication
+ cmd = new Command("Update-CsUserDatabase");
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ HostedSolutionLog.LogError("DeleteUserInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("DeleteUserInternal");
+ return ret;
+ }
+
+ internal void DeleteUser(Runspace runSpace, string userUpn)
+ {
+ HostedSolutionLog.LogStart("DeleteUser");
+ HostedSolutionLog.DebugInfo("userUpn : {0}", userUpn);
+ Command cmd = new Command("Disable-CsUser");
+ cmd.Parameters.Add("Identity", userUpn);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd, false);
+ HostedSolutionLog.LogEnd("DeleteUser");
+ }
+
+ #endregion
+
+ #region SipDomains
+ internal void DeleteSipDomain(Runspace runSpace, string id)
+ {
+ HostedSolutionLog.LogStart("DeleteSipDomain");
+ HostedSolutionLog.DebugInfo("SipDomain : {0}", id);
+ Command cmd = new Command("Remove-CsSipDomain");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("Force", true);
+ ExecuteShellCommand(runSpace, cmd, false);
+ HostedSolutionLog.LogEnd("DeleteSipDomain");
+ }
+
+ private void CreateSimpleUrl(Runspace runSpace, string sipDomain, Guid id)
+ {
+ //Create the simpleUrlEntry
+ Command cmd = new Command("Get-CsSipDomain");
+ Collection sipDomains = ExecuteShellCommand(runSpace, cmd, false);
+
+ IList SimpleUrls = new List();
+
+
+ foreach (PSObject domain in sipDomains)
+ {
+ string d = (string)GetPSObjectProperty(domain, "Name");
+ string Url = SimpleUrlRoot + d;
+
+
+ //Create the simpleUrlEntry
+ cmd = new Command("New-CsSimpleUrlEntry");
+ cmd.Parameters.Add("Url", Url);
+ Collection simpleUrlEntry = ExecuteShellCommand(runSpace, cmd, false);
+
+ //Create the simpleUrl
+ cmd = new Command("New-CsSimpleUrl");
+ cmd.Parameters.Add("Component", "meet");
+ cmd.Parameters.Add("Domain", d);
+ cmd.Parameters.Add("SimpleUrl", simpleUrlEntry[0]);
+ cmd.Parameters.Add("ActiveUrl", Url);
+ Collection simpleUrl = ExecuteShellCommand(runSpace, cmd, false);
+
+ SimpleUrls.Add(simpleUrl[0]);
+ }
+
+ //PSListModifier
+ cmd = new Command("Set-CsSimpleUrlConfiguration");
+ cmd.Parameters.Add("Identity", "Global");
+ cmd.Parameters.Add("Tenant", id);
+ cmd.Parameters.Add("SimpleUrl", SimpleUrls);
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+
+
+ internal void DeleteSimpleUrl(Runspace runSpace, string sipDomain, Guid id)
+ {
+ /*
+ //build the url
+ string Url = SimpleUrlRoot + sipDomain;
+
+ //Create the simpleUrlEntry
+ Command cmd = new Command("New-CsSimpleUrlEntry");
+ cmd.Parameters.Add("Url", Url);
+ Collection simpleUrlEntry = ExecuteShellCommand(runSpace, cmd, false);
+
+ //Create the simpleUrl
+ cmd = new Command("New-CsSimpleUrl");
+ cmd.Parameters.Add("Component", "meet");
+ cmd.Parameters.Add("Domain", sipDomain);
+ cmd.Parameters.Add("SimpleUrl", simpleUrlEntry[0]);
+ cmd.Parameters.Add("ActiveUrl", Url);
+ Collection simpleUrl = ExecuteShellCommand(runSpace, cmd, false);
+
+ //PSListModifier
+
+ Hashtable properties = new Hashtable();
+ properties.Add("Remove", simpleUrl[0]);
+
+ cmd = new Command("Set-CsSimpleUrlConfiguration");
+ cmd.Parameters.Add("Identity", "Global");
+ cmd.Parameters.Add("Tenant", id);
+ cmd.Parameters.Add("SimpleUrl", properties);
+ ExecuteShellCommand(runSpace, cmd, false);
+ */
+ }
+
+
+ #endregion
+
+ #region Policies
+
+ internal void DeleteConferencingPolicy(Runspace runSpace, string policyName)
+ {
+ HostedSolutionLog.LogStart("DeleteConferencingPolicy");
+ HostedSolutionLog.DebugInfo("policyName : {0}", policyName);
+ Command cmd = new Command("Remove-CsConferencingPolicy");
+ cmd.Parameters.Add("Identity", policyName);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("Force", true);
+ ExecuteShellCommand(runSpace, cmd, false);
+ HostedSolutionLog.LogEnd("DeleteConferencingPolicy");
+ }
+
+ internal void DeleteExternalAccessPolicy(Runspace runSpace, string policyName)
+ {
+ HostedSolutionLog.LogStart("DeleteExternalAccessPolicy");
+ HostedSolutionLog.DebugInfo("policyName : {0}", policyName);
+ Command cmd = new Command("Remove-CsExternalAccessPolicy");
+ cmd.Parameters.Add("Identity", policyName);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("Force", true);
+ ExecuteShellCommand(runSpace, cmd, false);
+ HostedSolutionLog.LogEnd("DeleteExternalAccessPolicy");
+ }
+
+ internal void DeleteMobilityPolicy(Runspace runSpace, string policyName)
+ {
+ HostedSolutionLog.LogStart("DeleteMobilityPolicy");
+ HostedSolutionLog.DebugInfo("policyName : {0}", policyName);
+ Command cmd = new Command("Remove-CsMobilityPolicy");
+ cmd.Parameters.Add("Identity", policyName);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("Force", true);
+ ExecuteShellCommand(runSpace, cmd, false);
+ HostedSolutionLog.LogEnd("DeleteMobilityPolicy");
+ }
+
+ internal string[] GetPolicyListInternal(LyncPolicyType type, string name)
+ {
+ List ret = new List();
+
+ switch (type)
+ {
+ case LyncPolicyType.Archiving:
+ {
+ Runspace runSpace = OpenRunspace();
+ Command cmd = new Command("Get-CsArchivingPolicy");
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ foreach (PSObject res in result)
+ {
+ string Identity = GetPSObjectProperty(res, "Identity").ToString();
+ ret.Add(Identity);
+ }
+ }
+ }
+ break;
+ case LyncPolicyType.DialPlan:
+ {
+ Runspace runSpace = OpenRunspace();
+ Command cmd = new Command("Get-CsDialPlan");
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ foreach (PSObject res in result)
+ {
+ string Identity = GetPSObjectProperty(res, "Identity").ToString();
+ string Description = "" + (string)GetPSObjectProperty(res, "Description");
+ if (Description.ToLower().IndexOf(name.ToLower()) == -1) continue;
+ ret.Add(Identity);
+ }
+
+
+ }
+ }
+ break;
+ case LyncPolicyType.Voice:
+ {
+ Runspace runSpace = OpenRunspace();
+ Command cmd = new Command("Get-CsVoicePolicy");
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ foreach (PSObject res in result)
+ {
+ string Identity = GetPSObjectProperty(res, "Identity").ToString();
+ string Description = "" + (string)GetPSObjectProperty(res, "Description");
+ if (Description.ToLower().IndexOf(name.ToLower()) == -1) continue;
+
+ ret.Add(Identity);
+ }
+
+
+ }
+ }
+ break;
+ case LyncPolicyType.Pin:
+ {
+ Runspace runSpace = OpenRunspace();
+ Command cmd = new Command("Get-CsPinPolicy");
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ foreach (PSObject res in result)
+ {
+ string Identity = GetPSObjectProperty(res, "Identity").ToString();
+ string str = "" + GetPSObjectProperty(res, name);
+ ret.Add(str);
+ }
+ }
+ }
+ break;
+
+ }
+
+
+
+ return ret.ToArray();
+ }
+
+ #endregion
+
+ #region Sytsem Related Methods
+ private void ReloadConfigurationInternal()
+ {
+ HostedSolutionLog.LogStart("ReloadConfigurationInternal");
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Enable-CsComputer");
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("ReloadConfigurationInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("ReloadConfigurationInternal");
+ }
+
+
+ #endregion
+
+ #region Federation Domains
+ private LyncFederationDomain[] GetFederationDomainsInternal(string organizationId)
+ {
+
+ HostedSolutionLog.LogStart("GetFederationDomainsInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+
+
+ LyncFederationDomain[] domains = null;
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Guid tenantId = Guid.Empty;
+
+ domains = GetFederationDomainsInternal(runSpace, organizationId, ref tenantId);
+
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("GetFederationDomainsInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("GetFederationDomainsInternal");
+
+ return domains;
+ }
+
+ private LyncFederationDomain[] GetFederationDomainsInternal(Runspace runSpace, string organizationId, ref Guid tenantId)
+ {
+ //Get TenantID
+ List domains = null;
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ //Get-CSTenantFederationConfiguration (AllowedDomains)
+ cmd = new Command("Get-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", tenantId);
+ result = ExecuteShellCommand(runSpace, cmd, false);
+
+ if ((result != null) && (result.Count > 0))
+ {
+ domains = new List();
+
+ if (GetPSObjectProperty(result[0], "AllowedDomains").GetType().ToString() == "Microsoft.Rtc.Management.WritableConfig.Settings.Edge.AllowList")
+ {
+ AllowList allowList = (AllowList)GetPSObjectProperty(result[0], "AllowedDomains");
+
+ foreach (DomainPattern d in allowList.AllowedDomain)
+ {
+ LyncFederationDomain domain = new LyncFederationDomain();
+ domain.DomainName = d.Domain.ToString();
+ domains.Add(domain);
+ }
+ }
+ }
+ }
+
+ if (domains != null)
+ return domains.ToArray();
+ else
+ return null;
+ }
+
+
+ private bool AddFederationDomainInternal(string organizationId, string domainName, string proxyFqdn)
+ {
+ HostedSolutionLog.LogStart("AddFederationDomainInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("domainName: {0}", domainName);
+
+ domainName = domainName.ToLower();
+ proxyFqdn = proxyFqdn.ToLower();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Guid tenantId = Guid.Empty;
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ //Get-CSTenantFederationConfiguration (AllowedDomains)
+ cmd = new Command("Get-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", tenantId);
+ result = ExecuteShellCommand(runSpace, cmd, false);
+
+ if ((result != null) && (result.Count > 0))
+ {
+ AllowList allowList = null;
+
+ if (GetPSObjectProperty(result[0], "AllowedDomains").GetType().ToString() == "Microsoft.Rtc.Management.WritableConfig.Settings.Edge.AllowList")
+ {
+ allowList = (AllowList)GetPSObjectProperty(result[0], "AllowedDomains");
+ DomainPattern domain = new DomainPattern(domainName);
+ allowList.AllowedDomain.Add(domain);
+ }
+ else
+ {
+ allowList = new AllowList();
+ DomainPattern domain = new DomainPattern(domainName);
+ allowList.AllowedDomain.Add(domain);
+ }
+
+ cmd = new Command("Set-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", tenantId);
+ cmd.Parameters.Add("AllowedDomains", allowList);
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("AddFederationDomainInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("AddFederationDomainInternal");
+
+ return true;
+ }
+
+ private bool RemoveFederationDomainInternal(string organizationId, string domainName)
+ {
+ HostedSolutionLog.LogStart("RemoveFederationDomainInternal");
+ HostedSolutionLog.DebugInfo("organizationId: {0}", organizationId);
+ HostedSolutionLog.DebugInfo("domainName: {0}", domainName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Guid tenantId = Guid.Empty;
+ Command cmd = new Command("Get-CsTenant");
+ cmd.Parameters.Add("Identity", GetOrganizationPath(organizationId));
+ Collection result = ExecuteShellCommand(runSpace, cmd, false);
+ if ((result != null) && (result.Count > 0))
+ {
+ tenantId = (Guid)GetPSObjectProperty(result[0], "TenantId");
+
+ //Get-CSTenantFederationConfiguration (AllowedDomains)
+ cmd = new Command("Get-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", tenantId);
+ result = ExecuteShellCommand(runSpace, cmd, false);
+
+ if ((result != null) && (result.Count > 0))
+ {
+ AllowList allowList = null;
+
+ if (GetPSObjectProperty(result[0], "AllowedDomains").GetType().ToString() == "Microsoft.Rtc.Management.WritableConfig.Settings.Edge.AllowList")
+ {
+ HostedSolutionLog.DebugInfo("Remove DomainName: {0}", domainName);
+ allowList = (AllowList)GetPSObjectProperty(result[0], "AllowedDomains");
+ DomainPattern domain = null;
+ foreach (DomainPattern d in allowList.AllowedDomain)
+ {
+ if (d.Domain.ToLower() == domainName.ToLower())
+ {
+ domain = d;
+ break;
+ }
+ }
+ if (domain != null)
+ allowList.AllowedDomain.Remove(domain);
+ }
+
+ cmd = new Command("Set-CsTenantFederationConfiguration");
+ cmd.Parameters.Add("Tenant", tenantId);
+ cmd.Parameters.Add("AllowedDomains", allowList);
+ ExecuteShellCommand(runSpace, cmd, false);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("RemoveFederationDomainInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ HostedSolutionLog.LogEnd("RemoveFederationDomainInternal");
+
+ return true;
+ }
+
+
+
+
+ #endregion
+
+ #region PowerShell integration
+ private static InitialSessionState session = null;
+
+ internal virtual Runspace OpenRunspace()
+ {
+ HostedSolutionLog.LogStart("OpenRunspace");
+
+ if (session == null)
+ {
+ session = InitialSessionState.CreateDefault();
+ session.ImportPSModule(new string[] { "ActiveDirectory", "Lync", "LyncOnline" });
+ }
+ Runspace runSpace = RunspaceFactory.CreateRunspace(session);
+ //
+ runSpace.Open();
+ //
+ runSpace.SessionStateProxy.SetVariable("ConfirmPreference", "none");
+ HostedSolutionLog.LogEnd("OpenRunspace");
+ return runSpace;
+ }
+
+ internal void CloseRunspace(Runspace runspace)
+ {
+ try
+ {
+ if (runspace != null && runspace.RunspaceStateInfo.State == RunspaceState.Opened)
+ {
+ runspace.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ HostedSolutionLog.LogError("Runspace error", ex);
+ }
+ }
+
+ internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd)
+ {
+ return ExecuteShellCommand(runSpace, cmd, true);
+ }
+
+ internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController)
+ {
+ object[] errors;
+ return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors);
+ }
+
+ internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, out object[] errors)
+ {
+ return ExecuteShellCommand(runSpace, cmd, true, out errors);
+ }
+
+ internal Collection ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors)
+ {
+ HostedSolutionLog.LogStart("ExecuteShellCommand");
+ List