diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Common.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Common.dll
new file mode 100644
index 00000000..c6a7e6fe
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Common.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Directory.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Directory.dll
new file mode 100644
index 00000000..9eb46c79
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Directory.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Storage.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Storage.dll
new file mode 100644
index 00000000..fc67917c
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.Storage.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.dll
new file mode 100644
index 00000000..b1ca6048
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Data.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Diagnostics.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Diagnostics.dll
new file mode 100644
index 00000000..6f654162
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Diagnostics.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Extensibility.Internal.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Extensibility.Internal.dll
new file mode 100644
index 00000000..f986790a
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Extensibility.Internal.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Net.dll b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Net.dll
new file mode 100644
index 00000000..15e67c9b
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Exchange2013/Microsoft.Exchange.Net.dll differ
diff --git a/WebsitePanel/Lib/References/Microsoft/Windows2012/System.Management.Automation.dll b/WebsitePanel/Lib/References/Microsoft/Windows2012/System.Management.Automation.dll
new file mode 100644
index 00000000..e77aa930
Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Windows2012/System.Management.Automation.dll differ
diff --git a/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs
new file mode 100644
index 00000000..cc70e261
--- /dev/null
+++ b/WebsitePanel/Sources/WebsitePanel.Providers.HostedSolution.Exchange2013/Exchange2013.cs
@@ -0,0 +1,6893 @@
+// 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.Configuration;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Reflection;
+using System.Globalization;
+using System.Collections;
+
+using System.DirectoryServices;
+using System.Security;
+using System.Security.Principal;
+using System.Security.AccessControl;
+
+using System.Management.Automation;
+using System.Management.Automation.Runspaces;
+
+using WebsitePanel.Providers;
+using WebsitePanel.Providers.HostedSolution;
+using WebsitePanel.Providers.Utils;
+using WebsitePanel.Server.Utils;
+using Microsoft.Exchange.Data.Directory.Recipient;
+using Microsoft.Win32;
+
+using Microsoft.Exchange.Data;
+using Microsoft.Exchange.Data.Directory;
+using Microsoft.Exchange.Data.Storage;
+
+namespace WebsitePanel.Providers.HostedSolution
+{
+ public class Exchange2013 : HostingServiceProviderBase, IExchangeServer
+ {
+
+ static private Hashtable htBbalancer = new Hashtable();
+
+ static Exchange2013()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveExchangeAssembly);
+ ExchangeRegistryPath = "SOFTWARE\\Microsoft\\ExchangeServer\\v15\\Setup";
+ }
+
+ #region Constants
+ private const string CONFIG_CLEAR_QUERYBASEDN = "WebsitePanel.Exchange.ClearQueryBaseDN";
+ #endregion
+
+ #region Properties
+
+ internal string RootOU
+ {
+ get { return ProviderSettings["RootOU"]; }
+ }
+
+ internal string StorageGroup
+ {
+ get { return ProviderSettings["StorageGroup"]; }
+ }
+
+ internal string MailboxDatabase
+ {
+ get { return ProviderSettings["MailboxDatabase"]; }
+ }
+
+ internal bool PublicFolderDistributionEnabled
+ {
+ get { return ProviderSettings.GetBool("PublicFolderDistributionEnabled"); }
+ }
+
+ internal int KeepDeletedItemsDays
+ {
+ get { return Int32.Parse(ProviderSettings["KeepDeletedItemsDays"]); }
+ }
+
+ internal int KeepDeletedMailboxesDays
+ {
+ get { return Int32.Parse(ProviderSettings["KeepDeletedMailboxesDays"]); }
+ }
+
+ internal string RootDomain
+ {
+ get { return ServerSettings.ADRootDomain; }
+ }
+
+ internal string MailboxCluster
+ {
+ get { return ProviderSettings["MailboxCluster"]; }
+ }
+
+ internal string PrimaryDomainController
+ {
+ get { return ProviderSettings["PrimaryDomainController"]; }
+ }
+
+ internal string PublicFolderServer
+ {
+ get { return ProviderSettings["PublicFolderServer"]; }
+ }
+
+ internal string OABGenerationServer
+ {
+ get { return ProviderSettings["OABServer"]; }
+ }
+
+ internal static string ExchangeRegistryPath
+ {
+ get;
+ set;
+ }
+
+ internal virtual string ExchangeSnapInName
+ {
+ get { return "Microsoft.Exchange.Management.PowerShell.E2010"; }
+ }
+
+ #endregion
+
+ #region IExchangeServer Members
+
+ #region Common
+ public bool CheckAccountCredentials(string username, string password)
+ {
+ return CheckAccountCredentialsInternal(username, password);
+ }
+ #endregion
+
+ #region Organizations
+
+ ///
+ /// Extend existing organization with exchange functionality
+ ///
+ ///
+ ///
+ ///
+ public Organization ExtendToExchangeOrganization(string organizationId, string securityGroup, bool IsConsumer)
+ {
+ return ExtendToExchangeOrganizationInternal(organizationId, securityGroup, IsConsumer);
+ }
+
+ ///
+ /// Creates organization OAB on the Client Access Server
+ ///
+ ///
+ ///
+ ///
+ public Organization CreateOrganizationOfflineAddressBook(string organizationId, string securityGroup, string oabVirtualDir)
+ {
+ return CreateOrganizationOfflineAddressBookInternal(organizationId, securityGroup, oabVirtualDir);
+ }
+
+ ///
+ /// Updates organization OAB
+ ///
+ ///
+ public void UpdateOrganizationOfflineAddressBook(string oabId)
+ {
+ UpdateOrganizationOfflineAddressBookInternal(oabId);
+ }
+
+
+ public string GetOABVirtualDirectory()
+ {
+ return GetOABVirtualDirectoryInternal();
+ }
+
+ public Organization CreateOrganizationAddressBookPolicy(string organizationId, string gal, string addressBook, string roomList, string oab)
+ {
+ return CreateOrganizationAddressBookPolicyInternal(organizationId, gal, addressBook, roomList, oab);
+ }
+
+ public bool DeleteOrganization(string organizationId, string distinguishedName,
+ string globalAddressList, string addressList, string roomList, string offlineAddressBook,
+ string securityGroup, string addressBookPolicy)
+ {
+ return DeleteOrganizationInternal(organizationId, distinguishedName, globalAddressList,
+ addressList, roomList, offlineAddressBook, securityGroup, addressBookPolicy);
+ }
+
+ public void SetOrganizationStorageLimits(string organizationDistinguishedName, long issueWarningKB, long prohibitSendKB,
+ long prohibitSendReceiveKB, int keepDeletedItemsDays)
+ {
+ SetOrganizationStorageLimitsInternal(organizationDistinguishedName, issueWarningKB, prohibitSendKB,
+ prohibitSendReceiveKB, keepDeletedItemsDays);
+ }
+
+ public ExchangeItemStatistics[] GetMailboxesStatistics(string organizationDistinguishedName)
+ {
+ return GetMailboxesStatisticsInternal(organizationDistinguishedName);
+ }
+ #endregion
+
+ #region Domains
+
+ public string[] GetAuthoritativeDomains()
+ {
+ return GetAuthoritativeDomainsInternal();
+ }
+
+ public void AddAuthoritativeDomain(string domain)
+ {
+ CreateAuthoritativeDomainInternal(domain);
+ }
+
+ public void DeleteAuthoritativeDomain(string domain)
+ {
+ DeleteAuthoritativeDomainInternal(domain);
+ }
+
+ public void ChangeAcceptedDomainType(string domainName, ExchangeAcceptedDomainType domainType)
+ {
+ ChangeAcceptedDomainTypeInternal(domainName, domainType);
+ }
+ #endregion
+
+ #region Mailboxes
+
+ public ExchangeMailbox GetMailboxPermissions(string organizationId, string accountName)
+ {
+ return GetMailboxPermissionsInternal(organizationId, accountName, null);
+ }
+
+ public void SetMailboxPermissions(string organizationId, string accountName, string[] sendAsAccounts, string[] fullAccessAccounts)
+ {
+ SetMailboxPermissionsInternal(organizationId, accountName, sendAsAccounts, fullAccessAccounts);
+ }
+
+ /*
+ public string CreateMailbox(string organizationId, string organizationDistinguishedName,
+ string mailboxDatabase, string securityGroup, string offlineAddressBook, ExchangeAccountType accountType,
+ string displayName,
+ string accountName, string name, string domain, string password, bool enablePOP, bool enableIMAP,
+ bool enableOWA, bool enableMAPI, bool enableActiveSync,
+ int issueWarningKB, int prohibitSendKB, int prohibitSendReceiveKB, int keepDeletedItemsDays)
+ {
+ return CreateMailboxInternal(organizationId, organizationDistinguishedName, mailboxDatabase, securityGroup,
+ offlineAddressBook, accountType, displayName, accountName, name, domain, password, enablePOP, enableIMAP,
+ enableOWA, enableMAPI, enableActiveSync,
+ issueWarningKB, prohibitSendKB, prohibitSendReceiveKB, keepDeletedItemsDays);
+ }
+ */
+ public void DeleteMailbox(string accountName)
+ {
+ DeleteMailboxInternal(accountName);
+ }
+
+ public ExchangeMailbox GetMailboxGeneralSettings(string accountName)
+ {
+ return GetMailboxGeneralSettingsInternal(accountName);
+ }
+
+ public void SetMailboxGeneralSettings(string accountName, bool hideFromAddressBook, bool disabled)
+ {
+ SetMailboxGeneralSettingsInternal(accountName, hideFromAddressBook, disabled);
+ }
+
+ public ExchangeMailbox GetMailboxMailFlowSettings(string accountName)
+ {
+ return GetMailboxMailFlowSettingsInternal(accountName);
+ }
+
+ public void SetMailboxMailFlowSettings(string accountName, bool enableForwarding,
+ string forwardingAccountName, bool forwardToBoth, string[] sendOnBehalfAccounts,
+ string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ SetMailboxMailFlowSettingsInternal(accountName, enableForwarding, forwardingAccountName,
+ forwardToBoth, sendOnBehalfAccounts, acceptAccounts, rejectAccounts, requireSenderAuthentication);
+ }
+
+ public ExchangeMailbox GetMailboxAdvancedSettings(string accountName)
+ {
+ return GetMailboxAdvancedSettingsInternal(accountName);
+ }
+
+ public void SetMailboxAdvancedSettings(string organizationId, string accountName, bool enablePOP,
+ bool enableIMAP, bool enableOWA, bool enableMAPI, bool enableActiveSync,
+ long issueWarningKB, long prohibitSendKB, long prohibitSendReceiveKB, int keepDeletedItemsDays, int maxRecipients, int maxSendMessageSizeKB,
+ int maxReceiveMessageSizeKB)
+ {
+ SetMailboxAdvancedSettingsInternal(organizationId, accountName, enablePOP, enableIMAP, enableOWA,
+ enableMAPI, enableActiveSync, issueWarningKB,
+ prohibitSendKB, prohibitSendReceiveKB, keepDeletedItemsDays, maxRecipients, maxSendMessageSizeKB, maxReceiveMessageSizeKB);
+ }
+
+ public ExchangeEmailAddress[] GetMailboxEmailAddresses(string accountName)
+ {
+ return GetMailboxEmailAddressesInternal(accountName);
+ }
+
+ public void SetMailboxEmailAddresses(string accountName, string[] emailAddresses)
+ {
+ SetMailboxEmailAddressesInternal(accountName, emailAddresses);
+ }
+
+ public void SetMailboxPrimaryEmailAddress(string accountName, string emailAddress)
+ {
+ SetMailboxPrimaryEmailAddressInternal(accountName, emailAddress);
+ }
+
+ public ExchangeMailboxStatistics GetMailboxStatistics(string id)
+ {
+ return GetMailboxStatisticsInternal(id);
+ }
+ #endregion
+
+ #region Contacts
+ public void CreateContact(string organizationId, string organizationDistinguishedName,
+ string contactDisplayName, string contactAccountName, string contactEmail, string defaultOrganizationDomain)
+ {
+ CreateContactInternal(organizationId, organizationDistinguishedName, contactDisplayName,
+ contactAccountName, contactEmail, defaultOrganizationDomain);
+ }
+
+ public void DeleteContact(string accountName)
+ {
+ DeleteContactInternal(accountName);
+ }
+
+ public ExchangeContact GetContactGeneralSettings(string accountName)
+ {
+ return GetContactGeneralSettingsInternal(accountName);
+ }
+
+ public void SetContactGeneralSettings(string accountName, string displayName, string email,
+ bool hideFromAddressBook, string firstName, string initials, string lastName, string address,
+ string city, string state, string zip, string country, string jobTitle, string company,
+ string department, string office, string managerAccountName, string businessPhone, string fax,
+ string homePhone, string mobilePhone, string pager, string webPage, string notes, int useMapiRichTextFormat, string defaultOrganizationDomain)
+ {
+ SetContactGeneralSettingsInternal(accountName, displayName, email, hideFromAddressBook,
+ firstName, initials, lastName, address, city, state, zip, country, jobTitle,
+ company, department, office, managerAccountName, businessPhone, fax, homePhone,
+ mobilePhone, pager, webPage, notes, useMapiRichTextFormat, defaultOrganizationDomain);
+ }
+
+ public ExchangeContact GetContactMailFlowSettings(string accountName)
+ {
+ return GetContactMailFlowSettingsInternal(accountName);
+ }
+
+ public void SetContactMailFlowSettings(string accountName, string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ SetContactMailFlowSettingsInternal(accountName, acceptAccounts, rejectAccounts, requireSenderAuthentication);
+ }
+ #endregion
+
+ #region Distribution lists
+ public void CreateDistributionList(string organizationId, string organizationDistinguishedName,
+ string displayName, string accountName, string name, string domain, string managedBy, string[] addressLists)
+ {
+ CreateDistributionListInternal(organizationId, organizationDistinguishedName, displayName,
+ accountName, name, domain, managedBy, addressLists);
+ }
+
+ public void DeleteDistributionList(string accountName)
+ {
+ DeleteDistributionListInternal(accountName);
+ }
+
+ public ExchangeDistributionList GetDistributionListGeneralSettings(string accountName)
+ {
+ return GetDistributionListGeneralSettingsInternal(accountName);
+ }
+
+ public void SetDistributionListGeneralSettings(string accountName, string displayName,
+ bool hideFromAddressBook, string managedBy, string[] members, string notes, string[] addressLists)
+ {
+ SetDistributionListGeneralSettingsInternal(accountName, displayName, hideFromAddressBook,
+ managedBy, members, notes, addressLists);
+ }
+
+ public void AddDistributionListMembers(string accountName, string[] memberAccounts, string[] addressLists)
+ {
+ AddDistributionListMembersInternal(accountName, memberAccounts, addressLists);
+ }
+
+
+ public void RemoveDistributionListMembers(string accountName, string[] memberAccounts, string[] addressLists)
+ {
+ RemoveDistributionListMembersInternal(accountName, memberAccounts, addressLists);
+ }
+
+ public ExchangeDistributionList GetDistributionListMailFlowSettings(string accountName)
+ {
+ return GetDistributionListMailFlowSettingsInternal(accountName);
+ }
+
+ public void SetDistributionListMailFlowSettings(string accountName, string[] acceptAccounts,
+ string[] rejectAccounts, bool requireSenderAuthentication, string[] addressLists)
+ {
+ SetDistributionListMailFlowSettingsInternal(accountName, acceptAccounts, rejectAccounts, requireSenderAuthentication, addressLists);
+ }
+
+ public ExchangeEmailAddress[] GetDistributionListEmailAddresses(string accountName)
+ {
+ return GetDistributionListEmailAddressesInternal(accountName);
+ }
+
+ public void SetDistributionListEmailAddresses(string accountName, string[] emailAddresses, string[] addressLists)
+ {
+ SetDistributionListEmailAddressesInternal(accountName, emailAddresses, addressLists);
+ }
+
+ public void SetDistributionListPrimaryEmailAddress(string accountName, string emailAddress, string[] addressLists)
+ {
+ SetDistributionListPrimaryEmailAddressInternal(accountName, emailAddress, addressLists);
+ }
+
+ public ExchangeDistributionList GetDistributionListPermissions(string organizationId, string accountName)
+ {
+ return GetDistributionListPermissionsInternal(organizationId, accountName, null);
+ }
+
+ public void SetDistributionListPermissions(string organizationId, string accountName, string[] sendAsAccounts, string[] sendOnBehalfAccounts, string[] addressLists)
+ {
+ SetDistributionListPermissionsInternal(organizationId, accountName, sendAsAccounts, sendOnBehalfAccounts, addressLists);
+ }
+ #endregion
+
+ #region Public folders
+ public void CreatePublicFolder(string organizationId, string securityGroup, string parentFolder,
+ string folderName, bool mailEnabled, string accountName, string name, string domain)
+ {
+ CreatePublicFolderInternal(organizationId, securityGroup, parentFolder, folderName,
+ mailEnabled, accountName, name, domain);
+ }
+
+ public void DeletePublicFolder(string folder)
+ {
+ DeletePublicFolderInternal(folder);
+ }
+
+ public void EnableMailPublicFolder(string organizationId, string folder, string accountName,
+ string name, string domain)
+ {
+ EnableMailPublicFolderInternal(organizationId, folder, accountName, name, domain);
+ }
+
+ public void DisableMailbox(string id)
+ {
+ DisableMailboxInternal(id);
+ }
+
+ internal virtual void DisableMailboxInternal(string id)
+ {
+ ExchangeLog.LogStart("DisableMailboxInternal");
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ if (result != null && result.Count > 0)
+ {
+ string upn = ObjToString(GetPSObjectProperty(result[0], "UserPrincipalName"));
+
+ string addressbookPolicy = ObjToString(GetPSObjectProperty(result[0], "AddressBookPolicy"));
+
+ RemoveDevicesInternal(runSpace, id);
+
+ cmd = new Command("Disable-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+
+
+ if (addressbookPolicy == (upn + " AP"))
+ {
+ try
+ {
+ DeleteAddressBookPolicy(runSpace, upn + " AP");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteGlobalAddressList(runSpace, upn + " GAL");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteAddressList(runSpace, upn + " AL");
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+
+ }
+
+ }
+
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DisableMailboxInternal");
+ }
+
+
+ public void DisableMailPublicFolder(string folder)
+ {
+ DisableMailPublicFolderInternal(folder);
+ }
+
+ public ExchangePublicFolder GetPublicFolderGeneralSettings(string folder)
+ {
+ return GetPublicFolderGeneralSettingsInternal(folder);
+ }
+
+ public void SetPublicFolderGeneralSettings(string folder, string newFolderName,
+ bool hideFromAddressBook, ExchangeAccount[] accounts)
+ {
+ SetPublicFolderGeneralSettingsInternal(folder, newFolderName, hideFromAddressBook, accounts);
+ }
+ public ExchangePublicFolder GetPublicFolderMailFlowSettings(string folder)
+ {
+ return GetPublicFolderMailFlowSettingsInternal(folder);
+ }
+
+ public void SetPublicFolderMailFlowSettings(string folder,
+ string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ SetPublicFolderMailFlowSettingsInternal(folder, acceptAccounts, rejectAccounts, requireSenderAuthentication);
+ }
+
+ public ExchangeEmailAddress[] GetPublicFolderEmailAddresses(string folder)
+ {
+ return GetPublicFolderEmailAddressesInternal(folder);
+ }
+
+ public void SetPublicFolderEmailAddresses(string folder, string[] emailAddresses)
+ {
+ SetPublicFolderEmailAddressesInternal(folder, emailAddresses);
+ }
+
+ public void SetPublicFolderPrimaryEmailAddress(string folder, string emailAddress)
+ {
+ SetPublicFolderPrimaryEmailAddressInternal(folder, emailAddress);
+ }
+
+ public ExchangeItemStatistics[] GetPublicFoldersStatistics(string[] folders)
+ {
+ return GetPublicFoldersStatisticsInternal(folders);
+ }
+
+ public string[] GetPublicFoldersRecursive(string parent)
+ {
+ return GetPublicFoldersRecursiveInternal(parent);
+ }
+
+ public long GetPublicFolderSize(string folder)
+ {
+ return GetPublicFolderSizeInternal(folder);
+ }
+ #endregion
+
+ #region ActiveSync
+ public void CreateOrganizationActiveSyncPolicy(string organizationId)
+ {
+ CreateOrganizationActiveSyncPolicyInternal(organizationId);
+ }
+
+
+ public ExchangeActiveSyncPolicy GetActiveSyncPolicy(string organizationId)
+ {
+ return GetActiveSyncPolicyInternal(organizationId);
+ }
+
+ public void SetActiveSyncPolicy(string id, bool allowNonProvisionableDevices, bool attachmentsEnabled,
+ int maxAttachmentSizeKB, bool uncAccessEnabled, bool wssAccessEnabled, bool devicePasswordEnabled,
+ bool alphanumericPasswordRequired, bool passwordRecoveryEnabled, bool deviceEncryptionEnabled,
+ bool allowSimplePassword, int maxPasswordFailedAttempts, int minPasswordLength, int inactivityLockMin,
+ int passwordExpirationDays, int passwordHistory, int refreshInterval)
+ {
+ SetActiveSyncPolicyInternal(id, allowNonProvisionableDevices, attachmentsEnabled,
+ maxAttachmentSizeKB, uncAccessEnabled, wssAccessEnabled,
+ devicePasswordEnabled, alphanumericPasswordRequired, passwordRecoveryEnabled,
+ deviceEncryptionEnabled, allowSimplePassword, maxPasswordFailedAttempts,
+ minPasswordLength, inactivityLockMin, passwordExpirationDays, passwordHistory, refreshInterval);
+ }
+ #endregion
+
+ #region Mobile devices
+ public ExchangeMobileDevice[] GetMobileDevices(string accountName)
+ {
+ return GetMobileDevicesInternal(accountName);
+ }
+ public ExchangeMobileDevice GetMobileDevice(string id)
+ {
+ return GetMobileDeviceInternal(id);
+ }
+ public void WipeDataFromDevice(string id)
+ {
+ WipeDataFromDeviceInternal(id);
+ }
+ public void CancelRemoteWipeRequest(string id)
+ {
+ CancelRemoteWipeRequestInternal(id);
+ }
+ public void RemoveDevice(string id)
+ {
+ RemoveDeviceInternal(id);
+ }
+ #endregion
+
+ #endregion
+
+ #region IHostingServiceProvider Members
+
+ public virtual void ChangeServiceItemsState(ServiceProviderItem[] items, bool enabled)
+ {
+ foreach (ServiceProviderItem item in items)
+ {
+ if (item is Organization)
+ {
+ try
+ {
+ // make E2K7 mailboxes disabled
+ Organization org = item as Organization;
+ ChangeOrganizationState(org.DistinguishedName, enabled);
+ }
+ catch (Exception ex)
+ {
+ Log.WriteError(String.Format("Error switching '{0}' {1}", item.Name, item.GetType().Name), ex);
+ }
+ }
+ }
+ }
+
+ public virtual void DeleteServiceItems(ServiceProviderItem[] items)
+ {
+ foreach (ServiceProviderItem item in items)
+ {
+ try
+ {
+ if (item is Organization)
+ {
+ Organization org = item as Organization;
+ DeleteOrganization(org.OrganizationId, org.DistinguishedName, org.GlobalAddressList,
+ org.AddressList, org.RoomsAddressList, org.OfflineAddressBook, org.SecurityGroup, org.AddressBookPolicy);
+ }
+ else if (item is ExchangeDomain)
+ {
+ DeleteAcceptedDomain(item.Name);
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.WriteError(String.Format("Error deleting '{0}' {1}", item.Name, item.GetType().Name), ex);
+ }
+ }
+ }
+
+ public virtual ServiceProviderItemDiskSpace[] GetServiceItemsDiskSpace(ServiceProviderItem[] items)
+ {
+ List itemsDiskspace = new List();
+
+ // update items with diskspace
+ foreach (ServiceProviderItem item in items)
+ {
+ if (item is Organization)
+ {
+ try
+ {
+ Log.WriteStart(String.Format("Calculating '{0}' disk space", item.Name));
+ Organization org = item as Organization;
+ // calculate disk space
+ ServiceProviderItemDiskSpace diskspace = new ServiceProviderItemDiskSpace();
+ diskspace.ItemId = item.Id;
+ diskspace.DiskSpace = CalculateOrganizationDiskSpace(org.OrganizationId, org.DistinguishedName);
+ itemsDiskspace.Add(diskspace);
+
+ Log.WriteEnd(String.Format("Calculating '{0}' disk space", item.Name));
+ }
+ catch (Exception ex)
+ {
+ Log.WriteError(String.Format("Error calculating '{0}' Exchange organization disk space", item.Name), ex);
+ }
+ }
+ }
+
+ return itemsDiskspace.ToArray();
+ }
+
+ #endregion
+
+ #region Common
+ private bool CheckAccountCredentialsInternal(string username, string password)
+ {
+ try
+ {
+ string path = ConvertDomainName(RootDomain);
+ DirectoryEntry entry = new DirectoryEntry(path, username, password);
+ //Bind to the native AdsObject to force authentication.
+ object obj = entry.NativeObject;
+
+ DirectorySearcher search = new DirectorySearcher(entry);
+
+ search.Filter = string.Format("(userPrincipalName={0})", username);
+ search.PropertiesToLoad.Add("cn");
+ SearchResult result = search.FindOne();
+
+ if (result == null)
+ {
+ return false;
+ }
+
+ //Update the new path to the user in the directory.
+ path = result.Path;
+ string filterAttribute = (string)result.Properties["cn"][0];
+ }
+ catch (Exception)
+ {
+ return false;
+ //throw new Exception("Error authenticating user. " + ex.Message);
+ }
+ return true;
+ }
+ #endregion
+
+ #region Organizations
+
+ ///
+ /// Creates organization on Mail Server
+ ///
+ ///
+ ///
+ internal virtual Organization ExtendToExchangeOrganizationInternal(string organizationId, string securityGroup, bool IsConsumer)
+ {
+ ExchangeLog.LogStart("CreateOrganizationInternal");
+ ExchangeLog.DebugInfo(" Organization Id: {0}", organizationId);
+
+ ExchangeTransaction transaction = StartTransaction();
+ Organization info = new Organization();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ string server = GetServerName();
+ string securityGroupPath = AddADPrefix(securityGroup);
+
+ //Create mail enabled organization security group
+ EnableMailSecurityDistributionGroup(runSpace, securityGroup, organizationId);
+ transaction.RegisterMailEnabledDistributionGroup(securityGroup);
+ UpdateSecurityDistributionGroup(runSpace, securityGroup, organizationId, IsConsumer);
+
+ //create GAL
+ string galId = CreateGlobalAddressList(runSpace, organizationId);
+ transaction.RegisterNewGlobalAddressList(galId);
+ ExchangeLog.LogInfo(" Global Address List: {0}", galId);
+ UpdateGlobalAddressList(runSpace, galId, securityGroupPath);
+
+ //create AL
+ string alId = CreateAddressList(runSpace, organizationId);
+ transaction.RegisterNewAddressList(alId);
+ ExchangeLog.LogInfo(" Address List: {0}", alId);
+ UpdateAddressList(runSpace, alId, securityGroupPath);
+
+ //create RAL
+ string ralId = CreateRoomsAddressList(runSpace, organizationId);
+ transaction.RegisterNewRoomsAddressList(ralId);
+ ExchangeLog.LogInfo(" Rooms Address List: {0}", ralId);
+ UpdateAddressList(runSpace, ralId, securityGroupPath);
+
+ //create ActiveSync policy
+ string asId = CreateActiveSyncPolicy(runSpace, organizationId);
+ transaction.RegisterNewActiveSyncPolicy(asId);
+ ExchangeLog.LogInfo(" ActiveSync Policy: {0}", asId);
+
+ info.AddressList = alId;
+ info.GlobalAddressList = galId;
+ info.RoomsAddressList = ralId;
+ info.OrganizationId = organizationId;
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateOrganizationInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CreateOrganizationInternal");
+ return info;
+ }
+
+ private void CheckServiceSettings()
+ {
+ if (!ServerSettings.ADEnabled)
+ throw new Exception("Active Directory is not enabled. Check server settings.");
+ if (string.IsNullOrEmpty(RootDomain))
+ throw new Exception("Active Directory root domain is not specified. Check server settings.");
+ if (string.IsNullOrEmpty(RootOU))
+ throw new Exception("Active Directory root organizational unit is not specified. Check provider settings.");
+ if (string.IsNullOrEmpty(PrimaryDomainController))
+ throw new Exception("Primary Domain Controller is not specified. Check provider settings.");
+ }
+
+ private string GetOABVirtualDirectoryInternal()
+ {
+ ExchangeLog.LogStart("GetOABVirtualDirectoryInternal");
+ Runspace runSpace = null;
+ string virtualDir = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string server = GetServerName();
+ Command cmd = new Command("Get-OabVirtualDirectory");
+ cmd.Parameters.Add("Server", server);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ if (result.Count > 0)
+ {
+ virtualDir = ObjToString(GetPSObjectProperty(result[0], "Identity"));
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetOABVirtualDirectoryInternal");
+ return virtualDir;
+ }
+
+ private Organization CreateOrganizationOfflineAddressBookInternal(string organizationId, string securityGroup, string oabVirtualDir)
+ {
+ ExchangeLog.LogStart("CreateOrganizationOfflineAddressBookInternal");
+ ExchangeLog.LogInfo(" Organization Id: {0}", organizationId);
+ ExchangeLog.LogInfo(" Security Group: {0}", securityGroup);
+ ExchangeLog.LogInfo(" OAB Virtual Dir: {0}", oabVirtualDir);
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ Organization info = new Organization();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string server = GetOABGenerationServerName();
+
+ string securityGroupId = AddADPrefix(securityGroup);
+
+ //create OAB
+ string oabId = CreateOfflineAddressBook(runSpace, organizationId, server, oabVirtualDir);
+ transaction.RegisterNewOfflineAddressBook(oabId);
+ UpdateOfflineAddressBook(runSpace, oabId, securityGroupId);
+ info.OfflineAddressBook = oabId;
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateOrganizationOfflineAddressBookInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CreateOrganizationOfflineAddressBookInternal");
+
+
+ return info;
+ }
+
+ private string GetOABGenerationServerName()
+ {
+ string ret = null;
+ if (!string.IsNullOrEmpty(OABGenerationServer))
+ ret = OABGenerationServer;
+ else
+ ret = GetServerName();
+ return ret;
+ }
+
+ private void UpdateOrganizationOfflineAddressBookInternal(string oabId)
+ {
+ ExchangeLog.LogStart("UpdateOrganizationOfflineAddressBookInternal");
+ ExchangeLog.LogInfo(" Id: {0}", oabId);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+ Command cmd = new Command("Update-OfflineAddressBook");
+ cmd.Parameters.Add("Identity", oabId);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("UpdateOrganizationOfflineAddressBookInternal");
+ }
+
+ internal virtual Organization CreateOrganizationAddressBookPolicyInternal(string organizationId, string gal, string addressBook, string roomList, string oab)
+ {
+ ExchangeLog.LogStart("CreateOrganizationAddressBookPolicyInternal");
+ ExchangeLog.LogInfo(" Organization Id: {0}", organizationId);
+ ExchangeLog.LogInfo(" GAL: {0}", gal);
+ ExchangeLog.LogInfo(" AddressBook: {0}", addressBook);
+ ExchangeLog.LogInfo(" RoomList: {0}", roomList);
+ ExchangeLog.LogInfo(" OAB: {0}", oab);
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ Organization info = new Organization();
+ string policyName = GetAddressBookPolicyName(organizationId);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+ Command cmd = new Command("New-AddressBookPolicy");
+ cmd.Parameters.Add("Name", policyName);
+ cmd.Parameters.Add("AddressLists", addressBook);
+ cmd.Parameters.Add("RoomList", roomList);
+ cmd.Parameters.Add("GlobalAddressList", gal);
+ cmd.Parameters.Add("OfflineAddressBook", oab);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ info.AddressBookPolicy = GetResultObjectDN(result);
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateOrganizationAddressBookPolicyInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CreateOrganizationAddressBookPolicyInternal");
+ return info;
+ }
+
+
+ internal virtual bool DeleteOrganizationInternal(string organizationId, string distinguishedName,
+ string globalAddressList, string addressList, string roomList, string offlineAddressBook, string securityGroup, string addressBookPolicy)
+ {
+ ExchangeLog.LogStart("DeleteOrganizationInternal");
+ bool ret = true;
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string ou = ConvertADPathToCanonicalName(distinguishedName);
+
+ if (!DeleteOrganizationMailboxes(runSpace, ou))
+ ret = false;
+
+ if (!DeleteOrganizationContacts(runSpace, ou))
+ ret = false;
+
+ if (!DeleteOrganizationDistributionLists(runSpace, ou))
+ ret = false;
+
+ //delete AddressBookPolicy
+ try
+ {
+ if (!string.IsNullOrEmpty(addressBookPolicy))
+ DeleteAddressBookPolicy(runSpace, addressBookPolicy);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete AddressBook Policy " + addressBookPolicy, ex);
+ }
+
+ //delete OAB
+ try
+ {
+ if (!string.IsNullOrEmpty(offlineAddressBook))
+ DeleteOfflineAddressBook(runSpace, offlineAddressBook);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete Offline Address Book " + offlineAddressBook, ex);
+ }
+
+ //delete AL
+ try
+ {
+ if (!string.IsNullOrEmpty(addressList))
+ DeleteAddressList(runSpace, addressList);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete Address List " + addressList, ex);
+ }
+
+ //delete RL
+ try
+ {
+ if (!string.IsNullOrEmpty(roomList))
+ DeleteAddressList(runSpace, roomList);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete Address List " + roomList, ex);
+ }
+
+
+ //delete GAL
+ try
+ {
+ if (!string.IsNullOrEmpty(globalAddressList))
+ DeleteGlobalAddressList(runSpace, globalAddressList);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete Global Address List " + globalAddressList, ex);
+ }
+
+ //delete ActiveSync policy
+ try
+ {
+ DeleteActiveSyncPolicy(runSpace, organizationId);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not delete ActiveSyncPolicy " + organizationId, ex);
+ }
+
+ //disable mail security distribution group
+ try
+ {
+ DisableMailSecurityDistributionGroup(runSpace, securityGroup);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("Could not disable mail security distribution group " + securityGroup, ex);
+ }
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError("DeleteOrganizationInternal", ex);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DeleteOrganizationInternal");
+ return ret;
+ }
+
+ private bool CanDeleteOrganization(Runspace runSpace, string organizationId, string ou)
+ {
+ ExchangeLog.LogStart("CanDeleteOrganization");
+ bool ret = true;
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ ret = false;
+
+ if (ret)
+ {
+ cmd = new Command("Get-MailContact");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ ret = false;
+ }
+
+ if (ret)
+ {
+ cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ cmd.Parameters.Add("RecipientTypeDetails", "MailUniversalDistributionGroup");
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ ret = false;
+ }
+
+ if (ret)
+ {
+ cmd = new Command("Get-PublicFolder");
+ cmd.Parameters.Add("Identity", "\\" + organizationId);
+ cmd.Parameters.Add("GetChildren", new SwitchParameter(true));
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ ret = false;
+ }
+
+ ExchangeLog.LogEnd("CanDeleteOrganization");
+ return ret;
+ }
+
+ internal bool DeleteOrganizationMailboxes(Runspace runSpace, string ou)
+ {
+ ExchangeLog.LogStart("DeleteOrganizationMailboxes");
+ bool ret = true;
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ foreach (PSObject obj in result)
+ {
+ string id = null;
+ try
+ {
+ id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ RemoveDevicesInternal(runSpace, id);
+
+ RemoveMailbox(runSpace, id);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError(string.Format("Can't delete mailbox {0}", id), ex);
+ }
+ }
+ }
+
+ ExchangeLog.LogEnd("DeleteOrganizationMailboxes");
+ return ret;
+ }
+
+ internal bool DeleteOrganizationContacts(Runspace runSpace, string ou)
+ {
+ ExchangeLog.LogStart("DeleteOrganizationContacts");
+ bool ret = true;
+
+ Command cmd = new Command("Get-MailContact");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ foreach (PSObject obj in result)
+ {
+ string id = null;
+ try
+ {
+ id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ RemoveContact(runSpace, id);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError(string.Format("Can't delete contact {0}", id), ex);
+ }
+ }
+ }
+
+ ExchangeLog.LogEnd("DeleteOrganizationContacts");
+ return ret;
+ }
+
+ internal bool DeleteOrganizationDistributionLists(Runspace runSpace, string ou)
+ {
+ ExchangeLog.LogStart("DeleteOrganizationDistributionLists");
+ bool ret = true;
+
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("OrganizationalUnit", ou);
+ cmd.Parameters.Add("RecipientTypeDetails", "MailUniversalDistributionGroup");
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ foreach (PSObject obj in result)
+ {
+ string id = null;
+ try
+ {
+ id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ RemoveDistributionGroup(runSpace, id);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError(string.Format("Can't delete distribution list {0}", id), ex);
+ }
+ }
+ }
+
+ ExchangeLog.LogEnd("DeleteOrganizationDistributionLists");
+ return ret;
+ }
+
+ private bool DeleteOrganizationPublicFolders(Runspace runSpace, string organizationId)
+ {
+ ExchangeLog.LogStart("DeleteOrganizationPublicFolders");
+ bool ret = true;
+
+ //Delete public folders.
+ string publicFolder = "\\" + organizationId;
+ try
+ {
+ RemovePublicFolder(runSpace, publicFolder);
+ }
+ catch (Exception ex)
+ {
+ ret = false;
+ ExchangeLog.LogError(string.Format("Can't delete public folder {0}", publicFolder), ex);
+ }
+ ExchangeLog.LogEnd("DeleteOrganizationPublicFolders");
+ return ret;
+ }
+
+ private void SetOrganizationStorageLimitsInternal(string organizationDistinguishedName, long issueWarningKB,
+ long prohibitSendKB, long prohibitSendReceiveKB, int keepDeletedItemsDays)
+ {
+ ExchangeLog.LogStart("SetOrganizationStorageLimitsInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationDistinguishedName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string org = ConvertADPathToCanonicalName(organizationDistinguishedName);
+
+ Unlimited issueWarningQuota = ConvertKBToUnlimited(issueWarningKB);
+ Unlimited prohibitSendQuota = ConvertKBToUnlimited(prohibitSendKB);
+ Unlimited prohibitSendReceiveQuota = ConvertKBToUnlimited(prohibitSendReceiveKB);
+ EnhancedTimeSpan retainDeletedItemsFor = ConvertDaysToEnhancedTimeSpan(keepDeletedItemsDays);
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", org);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ foreach (PSObject obj in result)
+ {
+ string id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("IssueWarningQuota", issueWarningQuota);
+ cmd.Parameters.Add("ProhibitSendQuota", prohibitSendQuota);
+ cmd.Parameters.Add("ProhibitSendReceiveQuota", prohibitSendReceiveQuota);
+ cmd.Parameters.Add("RetainDeletedItemsFor", retainDeletedItemsFor);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetOrganizationStorageLimitsInternal");
+ }
+
+ private ExchangeItemStatistics[] GetMailboxesStatisticsInternal(string organizationDistinguishedName)
+ {
+ ExchangeLog.LogStart("GetMailboxesStatisticsInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationDistinguishedName);
+
+ List ret = new List();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string org = ConvertADPathToCanonicalName(organizationDistinguishedName);
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", org);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ foreach (PSObject obj in result)
+ {
+ string id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+
+ cmd = new Command("Get-MailboxStatistics");
+ cmd.Parameters.Add("Identity", id);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ PSObject mailbox = result[0];
+ ExchangeItemStatistics info = new ExchangeItemStatistics();
+ info.ItemName = (string)GetPSObjectProperty(mailbox, "DisplayName");
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(mailbox, "TotalItemSize");
+ info.TotalSizeMB = ConvertUnlimitedToMB(totalItemSize);
+ uint? itemCount = (uint?)GetPSObjectProperty(mailbox, "ItemCount");
+ info.TotalItems = ConvertNullableToInt32(itemCount);
+ DateTime? lastLogoffTime = (DateTime?)GetPSObjectProperty(mailbox, "LastLogoffTime");
+ DateTime? lastLogonTime = (DateTime?)GetPSObjectProperty(mailbox, "LastLogonTime");
+ info.LastLogoff = ConvertNullableToDateTime(lastLogoffTime);
+ info.LastLogon = ConvertNullableToDateTime(lastLogonTime);
+ ret.Add(info);
+ }
+ }
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxesStatisticsInternal");
+ return ret.ToArray();
+ }
+
+ private void ChangeOrganizationState(string organizationDistinguishedName, bool enabled)
+ {
+ ExchangeLog.LogStart("ChangeOrganizationState");
+ ExchangeLog.DebugInfo("Organization: {0}", organizationDistinguishedName);
+
+ Runspace runSpace = null;
+ try
+ {
+ string ouName = ConvertADPathToCanonicalName(organizationDistinguishedName);
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", ouName);
+ cmd.Parameters.Add("Filter", "CustomAttribute2 -ne 'disabled'");
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ foreach (PSObject obj in result)
+ {
+ string id = (string)GetPSObjectProperty(obj, "DistinguishedName");
+ ChangeMailboxState(id, enabled);
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("ChangeOrganizationState");
+ }
+
+
+ private long CalculateOrganizationDiskSpace(string organizationId, string organizationDistinguishedName)
+ {
+ ExchangeLog.LogStart("CalculateOrganizationDiskSpace");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationId);
+
+ long size = 0;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ size += CalculateMailboxDiskSpace(runSpace, organizationDistinguishedName);
+ size += CalculatePublicFolderDiskSpace(runSpace, "\\" + organizationId);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CalculateOrganizationDiskSpace");
+ return size;
+ }
+
+ private long CalculateMailboxDiskSpace(Runspace runSpace, string organizationDistinguishedName)
+ {
+ ExchangeLog.LogStart("CalculateMailboxDiskSpace");
+ ExchangeLog.DebugInfo("Organization DN: {0}", organizationDistinguishedName);
+
+ long size = 0;
+
+ string org = ConvertADPathToCanonicalName(organizationDistinguishedName);
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("OrganizationalUnit", org);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ foreach (PSObject obj in result)
+ {
+ string id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ cmd = new Command("Get-MailboxStatistics");
+ cmd.Parameters.Add("Identity", id);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(result[0], "TotalItemSize");
+ size += ConvertUnlimitedToBytes(totalItemSize);
+ }
+ }
+ ExchangeLog.LogEnd("CalculateMailboxDiskSpace");
+ return size;
+ }
+
+ internal virtual long CalculatePublicFolderDiskSpace(Runspace runSpace, string folder)
+ {
+ ExchangeLog.LogStart("CalculatePublicFolderDiskSpace");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ long size = 0;
+
+ Command cmd = new Command("Get-PublicFolderDatabase");
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ cmd = new Command("Get-PublicFolderStatistics");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ PSObject obj = result[0];
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(obj, "TotalItemSize");
+ size += ConvertUnlimitedToBytes(totalItemSize);
+ }
+
+ cmd = new Command("Get-PublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ cmd.Parameters.Add("GetChildren", new SwitchParameter(true));
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ result = ExecuteShellCommand(runSpace, cmd);
+ foreach (PSObject obj in result)
+ {
+ string id = ObjToString(GetPSObjectProperty(obj, "Identity"));
+ size += CalculatePublicFolderDiskSpace(runSpace, id);
+ }
+ }
+ else
+ size = 0;
+ ExchangeLog.LogEnd("CalculatePublicFolderDiskSpace");
+ return size;
+ }
+
+ #endregion
+
+ #region Mailboxes
+
+
+ private void SetExtendedRights(Runspace runSpace, string identity, string user, string rights)
+ {
+ ExchangeLog.LogStart("SetExtendedRights");
+
+ Command cmd = new Command("Add-ADPermission");
+ cmd.Parameters.Add("Identity", identity);
+ cmd.Parameters.Add("User", user);
+
+ cmd.Parameters.Add("ExtendedRights", rights);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("SetExtendedRights");
+ }
+
+ private void SetMailboxPermission(Runspace runSpace, string accountName, string user, string accessRights)
+ {
+ ExchangeLog.LogStart("SetMailboxPermission");
+
+ Command cmd = new Command("Add-MailboxPermission");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("User", user);
+ cmd.Parameters.Add("AccessRights", accessRights);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("SetMailboxPermission");
+ }
+
+ private ExchangeAccount[] GetMailboxSendAsAccounts(Runspace runSpace, string organizationId, string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxSendAsAccounts");
+
+ string cn = GetMailboxCommonName(runSpace, accountName);
+ ExchangeAccount[] ret = GetSendAsAccounts(runSpace, organizationId, cn);
+
+ ExchangeLog.LogEnd("GetMailboxSendAsAccounts");
+ return ret;
+ }
+
+ private ExchangeAccount[] GetSendAsAccounts(Runspace runSpace, string organizationId, string accountId)
+ {
+ ExchangeLog.LogStart("GetSendAsAccounts");
+
+ Command cmd = new Command("Get-ADPermission");
+ cmd.Parameters.Add("Identity", accountId);
+ Collection results = ExecuteShellCommand(runSpace, cmd);
+ List accounts = new List();
+ foreach (PSObject current in results)
+ {
+ string user = GetPSObjectProperty(current, "User").ToString();
+
+ Array extendedRights = GetPSObjectProperty(current, "ExtendedRights") as Array;
+
+ if (extendedRights != null)
+ {
+ foreach (object obj in extendedRights)
+ {
+ string strRightName = obj.ToString();
+ if (string.Compare(strRightName, "Send-as", true) == 0)
+ {
+ ExchangeAccount account = GetOrganizationAccount(runSpace, organizationId, user);
+ if (account != null)
+ accounts.Add(account);
+ }
+ }
+ }
+ }
+
+ ExchangeLog.LogEnd("GetSendAsAccounts");
+ return accounts.ToArray();
+ }
+
+
+ private ExchangeAccount[] GetMailBoxFullAccessAcounts(Runspace runSpace, string organizationId, string accountName)
+ {
+ ExchangeLog.LogStart("GetMailBoxFullAccessAcounts");
+
+ Command cmd = new Command("Get-MailboxPermission");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection results = ExecuteShellCommand(runSpace, cmd);
+
+
+ List accounts = new List();
+ foreach (PSObject current in results)
+ {
+ string user = GetPSObjectProperty(current, "User").ToString();
+
+ Array accessRights = GetPSObjectProperty(current, "AccessRights") as Array;
+
+ if (accessRights != null)
+ {
+ foreach (object obj in accessRights)
+ {
+ string strRightName = obj.ToString();
+ if (string.Compare(strRightName, "FullAccess", true) == 0)
+ {
+ ExchangeAccount account = GetOrganizationAccount(runSpace, organizationId, user);
+ if (account != null)
+ accounts.Add(account);
+ }
+ }
+ }
+ }
+
+ ExchangeLog.LogEnd("GetMailBoxFullAccessAcounts");
+ return accounts.ToArray();
+ }
+
+ private ExchangeMailbox GetMailboxPermissionsInternal(string organizationId, string accountName, Runspace runspace)
+ {
+ ExchangeLog.LogStart("GetMailboxPermissionsInternal");
+
+ if (string.IsNullOrEmpty(accountName))
+ throw new ArgumentNullException("accountName");
+
+ ExchangeMailbox exchangeMailbox = null;
+ bool closeRunspace = false;
+
+ try
+ {
+ if (runspace == null)
+ {
+ runspace = OpenRunspace();
+ closeRunspace = true;
+ }
+
+ exchangeMailbox = new ExchangeMailbox();
+ exchangeMailbox.FullAccessAccounts = GetMailBoxFullAccessAcounts(runspace, organizationId, accountName);
+ exchangeMailbox.SendAsAccounts = GetMailboxSendAsAccounts(runspace, organizationId, accountName);
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ throw ex;
+ }
+ finally
+ {
+ if (closeRunspace)
+ CloseRunspace(runspace);
+ }
+
+ ExchangeLog.LogEnd("GetMailboxPermissionsInternal");
+ return exchangeMailbox;
+ }
+
+
+ private void SetSendAsPermissions(Runspace runSpace, ExchangeAccount[] existingAccounts, string accountId, string[] accounts)
+ {
+ ExchangeLog.LogStart("SetSendAsPermissions");
+
+ if (string.IsNullOrEmpty(accountId))
+ throw new ArgumentNullException("accountId");
+
+ if (accounts == null)
+ throw new ArgumentNullException("accounts");
+
+ ExchangeTransaction transaction = null;
+ try
+ {
+ transaction = StartTransaction();
+
+ string[] resAccounts = MergeADPermission(runSpace, existingAccounts, accountId, accounts, transaction);
+ foreach (string id in resAccounts)
+ {
+ SetExtendedRights(runSpace, accountId, id, "Send-as");
+ transaction.AddSendAsPermission(accountId, id);
+ }
+
+ }
+ catch (Exception)
+ {
+ RollbackTransaction(transaction);
+ throw;
+ }
+ ExchangeLog.LogEnd("SetSendAsPermissions");
+ }
+
+
+ private void SetMailboxPermissionsInternal(string organizationId, string accountName, string[] sendAsAccounts, string[] fullAccessAccounts)
+ {
+ ExchangeLog.LogStart("SetMailboxPermissionsInternal");
+
+ if (string.IsNullOrEmpty(accountName))
+ throw new ArgumentNullException("accountName");
+
+ if (sendAsAccounts == null)
+ throw new ArgumentNullException("sendAsAccounts");
+
+
+ if (fullAccessAccounts == null)
+ throw new ArgumentNullException("fullAccessAccounts");
+
+ Runspace runSpace = null;
+ try
+ {
+
+ runSpace = OpenRunspace();
+ string cn = GetMailboxCommonName(runSpace, accountName);
+ ExchangeMailbox mailbox = GetMailboxPermissionsInternal(organizationId, accountName, runSpace);
+ SetSendAsPermissions(runSpace, mailbox.SendAsAccounts, cn, sendAsAccounts);
+ SetMailboxFullAccessPermissions(runSpace, mailbox.FullAccessAccounts, accountName, fullAccessAccounts);
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+
+ throw;
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+
+ ExchangeLog.LogEnd("SetMailboxPermissionsInternal");
+ }
+
+
+ internal void RemoveMailboxAccessPermission(Runspace runSpace, string accountName, string account, string accessRights)
+ {
+ ExchangeLog.LogStart("RemoveMailboxFullAccessPermission");
+
+ Command cmd = new Command("Remove-MailboxPermission");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("User", account);
+ cmd.Parameters.Add("AccessRights", accessRights);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("RemoveMailboxFullAccessPermission");
+ }
+
+
+ private string[] MergeMailboxFullAccessPermissions(Runspace runSpace, ExchangeAccount[] existingAccounts, string accountName, string[] newAccounts, ExchangeTransaction transaction)
+ {
+ ExchangeLog.LogStart("MergeMailboxFullAccessPermissions");
+ List temp = new List(newAccounts);
+
+ Array.Sort(newAccounts);
+ foreach (ExchangeAccount exist in existingAccounts)
+ {
+ if (Array.BinarySearch(newAccounts, exist.AccountName, StringComparer.Create(CultureInfo.InvariantCulture, true)) >= 0)
+ {
+ temp.Remove(exist.AccountName);
+ continue;
+ }
+
+ RemoveMailboxAccessPermission(runSpace, accountName, exist.AccountName, "FullAccess");
+ transaction.RemoveMailboxFullAccessPermission(accountName, exist.AccountName);
+ }
+
+ ExchangeLog.LogEnd("MergeMailboxFullAccessPermissions");
+ return temp.ToArray();
+ }
+
+
+ private void SetMailboxFullAccessPermissions(Runspace runSpace, ExchangeAccount[] existingAccounts, string accountName, string[] accounts)
+ {
+ ExchangeLog.LogStart("SetMailboxFullAccessPermissions");
+
+ if (string.IsNullOrEmpty(accountName))
+ throw new ArgumentNullException("accountName");
+
+ if (accounts == null)
+ throw new ArgumentNullException("accounts");
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ try
+ {
+
+ string[] resAccounts = MergeMailboxFullAccessPermissions(runSpace, existingAccounts, accountName, accounts, transaction);
+ foreach (string id in resAccounts)
+ {
+ SetMailboxPermission(runSpace, accountName, id, "FullAccess");
+ transaction.AddMailBoxFullAccessPermission(accountName, id);
+ }
+ }
+ catch (Exception)
+ {
+ RollbackTransaction(transaction);
+ throw;
+ }
+ ExchangeLog.LogEnd("SetMailboxFullAccessPermissions");
+
+ }
+
+
+ private void RemoveADPermission(Runspace runSpace, string identity, string account, string accessRights, string extendedRights, string properties)
+ {
+ ExchangeLog.LogStart("RemoveADPermission");
+
+ Command cmd = new Command("Remove-ADPermission");
+ cmd.Parameters.Add("Identity", identity);
+ cmd.Parameters.Add("User", account);
+ cmd.Parameters.Add("InheritanceType", "All");
+ cmd.Parameters.Add("AccessRights", accessRights);
+ cmd.Parameters.Add("ExtendedRights", extendedRights);
+ cmd.Parameters.Add("ChildObjectTypes", null);
+ cmd.Parameters.Add("InheritedObjectType", null);
+ cmd.Parameters.Add("Properties", properties);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("RemoveADPermission");
+ }
+
+ private void AddADPermission(Runspace runSpace, string identity, string user, string accessRights, string extendedRights, string properties)
+ {
+ ExchangeLog.LogStart("AddADPermission");
+
+ Command cmd = new Command("Add-ADPermission");
+ cmd.Parameters.Add("Identity", identity);
+ cmd.Parameters.Add("User", user);
+ cmd.Parameters.Add("AccessRights", accessRights);
+ cmd.Parameters.Add("ExtendedRights", extendedRights);
+ cmd.Parameters.Add("Properties", properties);
+ //cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("AddADPermission");
+ }
+
+
+ private string[] MergeADPermission(Runspace runSpace, ExchangeAccount[] existingAccounts, string identity, string[] newAccounts, ExchangeTransaction transaction)
+ {
+ ExchangeLog.LogStart("MergeADPermission");
+
+ List temp = new List(newAccounts);
+
+ Array.Sort(newAccounts);
+ foreach (ExchangeAccount current in existingAccounts)
+ {
+ if (Array.BinarySearch(newAccounts, current.AccountName, StringComparer.Create(CultureInfo.InvariantCulture, true)) >= 0)
+ {
+ temp.Remove(current.AccountName);
+ continue;
+ }
+ RemoveADPermission(runSpace, identity, current.AccountName, null, "Send-as", null);
+ transaction.RemoveSendAsPermission(identity, current.AccountName);
+ }
+
+ ExchangeLog.LogEnd("MergeADPermission");
+ return temp.ToArray();
+ }
+
+
+ public string CreateMailEnableUser(string upn, string organizationId, string organizationDistinguishedName, ExchangeAccountType accountType,
+ string mailboxDatabase, string offlineAddressBook, string addressBookPolicy,
+ string accountName, bool enablePOP, bool enableIMAP,
+ bool enableOWA, bool enableMAPI, bool enableActiveSync,
+ long issueWarningKB, long prohibitSendKB, long prohibitSendReceiveKB, int keepDeletedItemsDays,
+ int maxRecipients, int maxSendMessageSizeKB, int maxReceiveMessageSizeKB, bool hideFromAddressBook, bool IsConsumer)
+ {
+ return CreateMailEnableUserInternal(upn, organizationId, organizationDistinguishedName, accountType,
+ mailboxDatabase, offlineAddressBook, addressBookPolicy,
+ accountName, enablePOP, enableIMAP,
+ enableOWA, enableMAPI, enableActiveSync,
+ issueWarningKB, prohibitSendKB, prohibitSendReceiveKB,
+ keepDeletedItemsDays, maxRecipients, maxSendMessageSizeKB, maxReceiveMessageSizeKB, hideFromAddressBook, IsConsumer);
+ }
+
+ internal virtual string CreateMailEnableUserInternal(string upn, string organizationId, string organizationDistinguishedName, ExchangeAccountType accountType,
+ string mailboxDatabase, string offlineAddressBook, string addressBookPolicy,
+ string accountName, bool enablePOP, bool enableIMAP,
+ bool enableOWA, bool enableMAPI, bool enableActiveSync,
+ long issueWarningKB, long prohibitSendKB, long prohibitSendReceiveKB, int keepDeletedItemsDays,
+ int maxRecipients, int maxSendMessageSizeKB, int maxReceiveMessageSizeKB, bool hideFromAddressBook, bool IsConsumer)
+ {
+
+ ExchangeLog.LogStart("CreateMailEnableUserInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationId);
+
+ string ret = null;
+ ExchangeTransaction transaction = StartTransaction();
+ Runspace runSpace = null;
+
+ int attempts = 0;
+ string id = null;
+
+ try
+ {
+ runSpace = OpenRunspace();
+ Command cmd = null;
+ Collection result = null;
+
+ //try to enable mail user for 10 times
+ while (true)
+ {
+ try
+ {
+ //create mailbox
+ cmd = new Command("Enable-Mailbox");
+ cmd.Parameters.Add("Identity", upn);
+ cmd.Parameters.Add("Alias", accountName);
+ string database = GetDatabase(runSpace, PrimaryDomainController, mailboxDatabase);
+ ExchangeLog.DebugInfo("database: " + database);
+ if (database != string.Empty)
+ {
+ cmd.Parameters.Add("Database", database);
+ }
+ if (accountType == ExchangeAccountType.Equipment)
+ cmd.Parameters.Add("Equipment");
+ else if (accountType == ExchangeAccountType.Room)
+ cmd.Parameters.Add("Room");
+
+ result = ExecuteShellCommand(runSpace, cmd);
+
+ id = CheckResultObjectDN(result);
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ }
+ if (id != null)
+ break;
+
+ if (attempts > 9)
+ throw new Exception(
+ string.Format("Could not enable mail user '{0}' ", upn));
+
+ attempts++;
+ ExchangeLog.LogWarning("Attempt #{0} to enable mail user failed!", attempts);
+ // wait 5 sec
+ System.Threading.Thread.Sleep(1000);
+ }
+
+ transaction.RegisterEnableMailbox(id);
+
+ string windowsEmailAddress = ObjToString(GetPSObjectProperty(result[0], "WindowsEmailAddress"));
+
+ //update mailbox
+ cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("OfflineAddressBook", offlineAddressBook);
+ cmd.Parameters.Add("EmailAddressPolicyEnabled", false);
+ cmd.Parameters.Add("CustomAttribute1", organizationId);
+ cmd.Parameters.Add("CustomAttribute3", windowsEmailAddress);
+ cmd.Parameters.Add("PrimarySmtpAddress", upn);
+ cmd.Parameters.Add("WindowsEmailAddress", upn);
+
+ cmd.Parameters.Add("UseDatabaseQuotaDefaults", new bool?(false));
+ cmd.Parameters.Add("UseDatabaseRetentionDefaults", false);
+ cmd.Parameters.Add("IssueWarningQuota", ConvertKBToUnlimited(issueWarningKB));
+ cmd.Parameters.Add("ProhibitSendQuota", ConvertKBToUnlimited(prohibitSendKB));
+ cmd.Parameters.Add("ProhibitSendReceiveQuota", ConvertKBToUnlimited(prohibitSendReceiveKB));
+ cmd.Parameters.Add("RetainDeletedItemsFor", ConvertDaysToEnhancedTimeSpan(keepDeletedItemsDays));
+ cmd.Parameters.Add("RecipientLimits", ConvertInt32ToUnlimited(maxRecipients));
+ cmd.Parameters.Add("MaxSendSize", ConvertKBToUnlimited(maxSendMessageSizeKB));
+ cmd.Parameters.Add("MaxReceiveSize", ConvertKBToUnlimited(maxReceiveMessageSizeKB));
+ if (IsConsumer) cmd.Parameters.Add("HiddenFromAddressListsEnabled", true);
+ else
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", hideFromAddressBook);
+ cmd.Parameters.Add("AddressBookPolicy", addressBookPolicy);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //Client Access
+ cmd = new Command("Set-CASMailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("ActiveSyncEnabled", enableActiveSync);
+ if (enableActiveSync)
+ {
+ cmd.Parameters.Add("ActiveSyncMailboxPolicy", organizationId);
+ }
+ cmd.Parameters.Add("OWAEnabled", enableOWA);
+ cmd.Parameters.Add("MAPIEnabled", enableMAPI);
+ cmd.Parameters.Add("PopEnabled", enablePOP);
+ cmd.Parameters.Add("ImapEnabled", enableIMAP);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //add to the security group
+ cmd = new Command("Add-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", organizationId);
+ cmd.Parameters.Add("Member", id);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck", true);
+ ExecuteShellCommand(runSpace, cmd);
+
+ if (!IsConsumer)
+ {
+ //Set-MailboxFolderPermission for calendar
+ cmd = new Command("Add-MailboxFolderPermission");
+ cmd.Parameters.Add("Identity", id + ":\\calendar");
+ cmd.Parameters.Add("AccessRights", "Reviewer");
+ cmd.Parameters.Add("User", organizationId);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ cmd = new Command("Set-MailboxFolderPermission");
+ cmd.Parameters.Add("Identity", id + ":\\calendar");
+ cmd.Parameters.Add("AccessRights", "None");
+ cmd.Parameters.Add("User", "Default");
+ ExecuteShellCommand(runSpace, cmd);
+
+ ret = string.Format("{0}\\{1}", GetNETBIOSDomainName(), accountName);
+ ExchangeLog.LogEnd("CreateMailEnableUserInternal");
+ return ret;
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateMailEnableUserInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ }
+
+ internal virtual void SetCalendarSettings(Runspace runspace, string id)
+ {
+ ExchangeLog.LogStart("SetCalendarSettings");
+ Command cmd = new Command("Set-CalendarProcessing");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("AutomateProcessing", CalendarProcessingFlags.AutoAccept);
+ ExecuteShellCommand(runspace, cmd);
+ ExchangeLog.LogEnd("SetCalendarSettings");
+ }
+
+ internal virtual void DeleteMailboxInternal(string accountName)
+ {
+ ExchangeLog.LogStart("DeleteMailboxInternal");
+ ExchangeLog.DebugInfo("Account Name: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ if (result != null && result.Count > 0)
+ {
+ string upn = ObjToString(GetPSObjectProperty(result[0], "UserPrincipalName"));
+ string addressbookPolicy = ObjToString(GetPSObjectProperty(result[0], "AddressBookPolicy"));
+
+ RemoveDevicesInternal(runSpace, accountName);
+
+ RemoveMailbox(runSpace, accountName);
+
+ if (addressbookPolicy == (upn + " AP"))
+ {
+ try
+ {
+ DeleteAddressBookPolicy(runSpace, upn + " AP");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteGlobalAddressList(runSpace, upn + " GAL");
+ }
+ catch (Exception)
+ {
+ }
+
+ try
+ {
+ DeleteAddressList(runSpace, upn + " AL");
+ }
+ catch (Exception)
+ {
+ }
+ }
+ }
+
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DeleteMailboxInternal");
+ }
+
+
+ internal string GetDatabase(Runspace runSpace, string primaryDomainController, string dagName)
+ {
+ string database = string.Empty;
+
+ if (string.IsNullOrEmpty(dagName)) return string.Empty;
+
+ ExchangeLog.LogStart("GetDatabase");
+ ExchangeLog.LogInfo("DAG: " + dagName);
+
+ //Get Dag Servers
+ Collection dags = null;
+ Command cmd = new Command("Get-DatabaseAvailabilityGroup");
+ cmd.Parameters.Add("Identity", dagName);
+ dags = ExecuteShellCommand(runSpace, cmd);
+
+ if (htBbalancer == null)
+ htBbalancer = new Hashtable();
+
+ if (htBbalancer[dagName] == null)
+ htBbalancer.Add(dagName, 0);
+
+ if (dags != null && dags.Count > 0)
+ {
+
+ ADMultiValuedProperty servers = (ADMultiValuedProperty)GetPSObjectProperty(dags[0], "Servers");
+
+ if (servers != null)
+ {
+ System.Collections.Generic.List lstDatabase = new System.Collections.Generic.List();
+
+ foreach (object objServer in servers)
+ {
+ Collection databases = null;
+ cmd = new Command("Get-MailboxDatabase");
+ cmd.Parameters.Add("Server", ObjToString(objServer));
+ databases = ExecuteShellCommand(runSpace, cmd);
+
+ foreach (PSObject objDatabase in databases)
+ {
+ if (((bool)GetPSObjectProperty(objDatabase, "IsExcludedFromProvisioning") == false) &&
+ ((bool)GetPSObjectProperty(objDatabase, "IsSuspendedFromProvisioning") == false))
+ {
+ string db = ObjToString(GetPSObjectProperty(objDatabase, "Identity"));
+
+ bool bAdd = true;
+ foreach (string s in lstDatabase)
+ {
+ if (s.ToLower() == db.ToLower())
+ {
+ bAdd = false;
+ break;
+ }
+ }
+
+ if (bAdd)
+ {
+ lstDatabase.Add(db);
+ ExchangeLog.LogInfo("AddDatabase: " + db);
+ }
+ }
+ }
+ }
+
+ int balancer = (int)htBbalancer[dagName];
+ balancer++;
+ if (balancer >= lstDatabase.Count) balancer = 0;
+ htBbalancer[dagName] = balancer;
+ if (lstDatabase.Count != 0) database = lstDatabase[balancer];
+
+ }
+ }
+
+ ExchangeLog.LogEnd("GetDatabase");
+ return database;
+ }
+
+ internal void RemoveMailbox(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("RemoveMailbox");
+ Command cmd = new Command("Remove-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Permanent", false);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("RemoveMailbox");
+ }
+
+ private void DisableMailbox(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DisableMailbox");
+ Command cmd = new Command("Disable-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DisableMailbox");
+ }
+
+ private string GetMailboxCommonName(Runspace runSpace, string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxCommonName");
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+ string cn = GetPSObjectProperty(mailbox, "Name") as string;
+ ExchangeLog.LogEnd("GetMailboxCommonName");
+ return cn;
+ }
+
+ private ExchangeAccount GetManager(DirectoryEntry entry)
+ {
+ ExchangeAccount retUser = null;
+ string path = ActiveDirectoryUtils.GetADObjectStringProperty(entry, ADAttributes.Manager);
+ if (!string.IsNullOrEmpty(path))
+ {
+ path = ActiveDirectoryUtils.AddADPrefix(path, PrimaryDomainController);
+ if (ActiveDirectoryUtils.AdObjectExists(path))
+ {
+ DirectoryEntry user = ActiveDirectoryUtils.GetADObject(path);
+ retUser = new ExchangeAccount();
+ retUser.DisplayName = ActiveDirectoryUtils.GetADObjectStringProperty(user, ADAttributes.DisplayName);
+ retUser.AccountName = ActiveDirectoryUtils.GetADObjectStringProperty(user, ADAttributes.Name);
+ }
+ }
+
+ return retUser;
+ }
+
+ private ExchangeMailbox GetMailboxGeneralSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeMailbox info = new ExchangeMailbox();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ string id = GetResultObjectDN(result);
+ string path = AddADPrefix(id);
+ DirectoryEntry entry = GetADObject(path);
+
+
+ //ADAccountOptions userFlags = (ADAccountOptions)entry.Properties["userAccountControl"].Value;
+ //info.Disabled = ((userFlags & ADAccountOptions.UF_ACCOUNTDISABLE) != 0);
+ info.Disabled = (bool)entry.InvokeGet("AccountDisabled");
+
+ info.DisplayName = (string)GetPSObjectProperty(mailbox, "DisplayName");
+ info.HideFromAddressBook = (bool)GetPSObjectProperty(mailbox, "HiddenFromAddressListsEnabled");
+
+ Command cmd = new Command("Get-User");
+ cmd.Parameters.Add("Identity", accountName);
+ result = ExecuteShellCommand(runSpace, cmd);
+ PSObject user = result[0];
+
+ info.FirstName = (string)GetPSObjectProperty(user, "FirstName");
+ info.Initials = (string)GetPSObjectProperty(user, "Initials");
+ info.LastName = (string)GetPSObjectProperty(user, "LastName");
+
+ info.Address = (string)GetPSObjectProperty(user, "StreetAddress");
+ info.City = (string)GetPSObjectProperty(user, "City");
+ info.State = (string)GetPSObjectProperty(user, "StateOrProvince");
+ info.Zip = (string)GetPSObjectProperty(user, "PostalCode");
+ info.Country = CountryInfoToString((CountryInfo)GetPSObjectProperty(user, "CountryOrRegion"));
+ info.JobTitle = (string)GetPSObjectProperty(user, "Title");
+ info.Company = (string)GetPSObjectProperty(user, "Company");
+ info.Department = (string)GetPSObjectProperty(user, "Department");
+ info.Office = (string)GetPSObjectProperty(user, "Office");
+
+
+ info.ManagerAccount = GetManager(entry); //GetExchangeAccount(runSpace, ObjToString(GetPSObjectProperty(user, "Manager")));
+ info.BusinessPhone = (string)GetPSObjectProperty(user, "Phone");
+ info.Fax = (string)GetPSObjectProperty(user, "Fax");
+ info.HomePhone = (string)GetPSObjectProperty(user, "HomePhone");
+ info.MobilePhone = (string)GetPSObjectProperty(user, "MobilePhone");
+ info.Pager = (string)GetPSObjectProperty(user, "Pager");
+ info.WebPage = (string)GetPSObjectProperty(user, "WebPage");
+ info.Notes = (string)GetPSObjectProperty(user, "Notes");
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxGeneralSettingsInternal");
+ return info;
+ }
+
+
+ private void SetMailboxGeneralSettingsInternal(string accountName, bool hideFromAddressBook, bool disabled)
+ {
+ ExchangeLog.LogStart("SetMailboxGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ string id = GetResultObjectDN(result);
+ string path = AddADPrefix(id);
+ DirectoryEntry entry = GetADObject(path);
+ entry.InvokeSet("AccountDisabled", disabled);
+ entry.CommitChanges();
+
+ Command cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", hideFromAddressBook);
+ cmd.Parameters.Add("CustomAttribute2", (disabled ? "disabled" : null));
+ ExecuteShellCommand(runSpace, cmd);
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetMailboxGeneralSettingsInternal");
+ }
+
+ private void ChangeMailboxState(string id, bool enabled)
+ {
+ string path = AddADPrefix(id);
+ DirectoryEntry entry = GetADObject(path);
+ entry.InvokeSet("AccountDisabled", !enabled);
+ entry.CommitChanges();
+ }
+
+ private ExchangeMailbox GetMailboxMailFlowSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxMailFlowSettings");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeMailbox info = new ExchangeMailbox();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ string forwardingAddress = ObjToString(GetPSObjectProperty(mailbox, "ForwardingAddress"));
+ if (string.IsNullOrEmpty(forwardingAddress))
+ {
+ info.EnableForwarding = false;
+ info.ForwardingAccount = null;
+ info.DoNotDeleteOnForward = false;
+ }
+ else
+ {
+ info.EnableForwarding = true;
+ info.ForwardingAccount = GetExchangeAccount(runSpace, forwardingAddress);
+ info.DoNotDeleteOnForward = (bool)GetPSObjectProperty(mailbox, "DeliverToMailboxAndForward");
+ }
+
+ info.SendOnBehalfAccounts = GetSendOnBehalfAccounts(runSpace, mailbox);
+ info.AcceptAccounts = GetAcceptedAccounts(runSpace, mailbox);
+ info.RejectAccounts = GetRejectedAccounts(runSpace, mailbox);
+ info.MaxRecipients =
+ ConvertUnlimitedToInt32((Unlimited)GetPSObjectProperty(mailbox, "RecipientLimits"));
+ info.MaxSendMessageSizeKB =
+ ConvertUnlimitedToKB((Unlimited)GetPSObjectProperty(mailbox, "MaxSendSize"));
+ info.MaxReceiveMessageSizeKB =
+ ConvertUnlimitedToKB((Unlimited)GetPSObjectProperty(mailbox, "MaxReceiveSize"));
+ info.RequireSenderAuthentication = (bool)GetPSObjectProperty(mailbox, "RequireSenderAuthenticationEnabled");
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxMailFlowSettings");
+ return info;
+ }
+
+ private void SetMailboxMailFlowSettingsInternal(string accountName, bool enableForwarding,
+ string forwardingAccountName, bool forwardToBoth, string[] sendOnBehalfAccounts,
+ string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ ExchangeLog.LogStart("SetMailboxMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+
+ if (enableForwarding)
+ {
+ cmd.Parameters.Add("ForwardingAddress", forwardingAccountName);
+ cmd.Parameters.Add("DeliverToMailboxAndForward", forwardToBoth);
+ }
+ else
+ {
+ cmd.Parameters.Add("ForwardingAddress", null);
+ cmd.Parameters.Add("DeliverToMailboxAndForward", false);
+ }
+
+ cmd.Parameters.Add("GrantSendOnBehalfTo", SetSendOnBehalfAccounts(runSpace, sendOnBehalfAccounts));
+
+ MultiValuedProperty ids = null;
+ MultiValuedProperty dlIds = null;
+
+ SetAccountIds(runSpace, acceptAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("AcceptMessagesOnlyFrom", ids);
+ cmd.Parameters.Add("AcceptMessagesOnlyFromDLMembers", dlIds);
+
+ SetAccountIds(runSpace, rejectAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("RejectMessagesFrom", ids);
+ cmd.Parameters.Add("RejectMessagesFromDLMembers", dlIds);
+
+ cmd.Parameters.Add("RequireSenderAuthenticationEnabled", requireSenderAuthentication);
+
+ ExecuteShellCommand(runSpace, cmd);
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetMailboxMailFlowSettingsInternal");
+ }
+
+ private ExchangeMailbox GetMailboxAdvancedSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxAdvancedSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeMailbox info = new ExchangeMailbox();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ info.IssueWarningKB =
+ ConvertUnlimitedToKB((Unlimited)GetPSObjectProperty(mailbox, "IssueWarningQuota"));
+ info.ProhibitSendKB =
+ ConvertUnlimitedToKB((Unlimited)GetPSObjectProperty(mailbox, "ProhibitSendQuota"));
+ info.ProhibitSendReceiveKB =
+ ConvertUnlimitedToKB((Unlimited)GetPSObjectProperty(mailbox, "ProhibitSendReceiveQuota"));
+ info.KeepDeletedItemsDays =
+ ConvertEnhancedTimeSpanToDays((EnhancedTimeSpan)GetPSObjectProperty(mailbox, "RetainDeletedItemsFor"));
+
+ //Client Access
+ Command cmd = new Command("Get-CASMailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ result = ExecuteShellCommand(runSpace, cmd);
+ mailbox = result[0];
+
+ info.EnableActiveSync = (bool)GetPSObjectProperty(mailbox, "ActiveSyncEnabled");
+ info.EnableOWA = (bool)GetPSObjectProperty(mailbox, "OWAEnabled");
+ info.EnableMAPI = (bool)GetPSObjectProperty(mailbox, "MAPIEnabled");
+ info.EnablePOP = (bool)GetPSObjectProperty(mailbox, "PopEnabled");
+ info.EnableIMAP = (bool)GetPSObjectProperty(mailbox, "ImapEnabled");
+
+ //Statistics
+ cmd = new Command("Get-MailboxStatistics");
+ cmd.Parameters.Add("Identity", accountName);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result.Count > 0)
+ {
+ PSObject statistics = result[0];
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(statistics, "TotalItemSize");
+ info.TotalSizeMB = ConvertUnlimitedToMB(totalItemSize);
+ uint? itemCount = (uint?)GetPSObjectProperty(statistics, "ItemCount");
+ info.TotalItems = ConvertNullableToInt32(itemCount);
+ DateTime? lastLogoffTime = (DateTime?)GetPSObjectProperty(statistics, "LastLogoffTime"); ;
+ DateTime? lastLogonTime = (DateTime?)GetPSObjectProperty(statistics, "LastLogonTime"); ;
+ info.LastLogoff = ConvertNullableToDateTime(lastLogoffTime);
+ info.LastLogon = ConvertNullableToDateTime(lastLogonTime);
+ }
+ else
+ {
+ info.TotalSizeMB = 0;
+ info.TotalItems = 0;
+ info.LastLogoff = DateTime.MinValue;
+ info.LastLogon = DateTime.MinValue;
+ }
+
+ //domain
+ info.Domain = GetNETBIOSDomainName();
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxAdvancedSettingsInternal");
+ return info;
+ }
+
+ private void SetMailboxAdvancedSettingsInternal(string organizationId, string accountName, bool enablePOP, bool enableIMAP,
+ bool enableOWA, bool enableMAPI, bool enableActiveSync, long issueWarningKB, long prohibitSendKB,
+ long prohibitSendReceiveKB, int keepDeletedItemsDays, int maxRecipients, int maxSendMessageSizeKB,
+ int maxReceiveMessageSizeKB)
+ {
+ ExchangeLog.LogStart("SetMailboxAdvancedSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("IssueWarningQuota", ConvertKBToUnlimited(issueWarningKB));
+ cmd.Parameters.Add("ProhibitSendQuota", ConvertKBToUnlimited(prohibitSendKB));
+ cmd.Parameters.Add("ProhibitSendReceiveQuota", ConvertKBToUnlimited(prohibitSendReceiveKB));
+ cmd.Parameters.Add("RetainDeletedItemsFor", ConvertDaysToEnhancedTimeSpan(keepDeletedItemsDays));
+ cmd.Parameters.Add("RecipientLimits", ConvertInt32ToUnlimited(maxRecipients));
+ cmd.Parameters.Add("MaxSendSize", ConvertKBToUnlimited(maxSendMessageSizeKB));
+ cmd.Parameters.Add("MaxReceiveSize", ConvertKBToUnlimited(maxReceiveMessageSizeKB));
+ ExecuteShellCommand(runSpace, cmd);
+
+ //Client Access
+ cmd = new Command("Set-CASMailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("ActiveSyncEnabled", enableActiveSync);
+ if (enableActiveSync)
+ {
+ cmd.Parameters.Add("ActiveSyncMailboxPolicy", organizationId);
+ }
+ cmd.Parameters.Add("OWAEnabled", enableOWA);
+ cmd.Parameters.Add("MAPIEnabled", enableMAPI);
+ cmd.Parameters.Add("PopEnabled", enablePOP);
+ cmd.Parameters.Add("ImapEnabled", enableIMAP);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetMailboxAdvancedSettingsInternal");
+ }
+
+ private ExchangeEmailAddress[] GetMailboxEmailAddressesInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetMailboxEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ List list = new List();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ string primaryEmail = null;
+ string windowsEmail = null;
+
+ SmtpAddress smtpAddress = (SmtpAddress)GetPSObjectProperty(mailbox, "PrimarySmtpAddress");
+ if (smtpAddress != null)
+ primaryEmail = smtpAddress.ToString();
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(mailbox, "WindowsEmailAddress");
+ windowsEmail = ObjToString(GetPSObjectProperty(mailbox, "CustomAttribute3"));
+
+ ProxyAddressCollection emails = (ProxyAddressCollection)GetPSObjectProperty(mailbox, "EmailAddresses");
+ foreach (ProxyAddress email in emails)
+ {
+ //skip windows email
+ if (string.Equals(email.AddressString, windowsEmail, StringComparison.OrdinalIgnoreCase))
+ continue;
+
+ ExchangeEmailAddress item = new ExchangeEmailAddress();
+ item.Email = email.AddressString;
+ item.Primary = string.Equals(item.Email, primaryEmail, StringComparison.OrdinalIgnoreCase);
+ list.Add(item);
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxEmailAddressesInternal");
+ return list.ToArray();
+ }
+
+ private void SetMailboxEmailAddressesInternal(string accountName, string[] emailAddresses)
+ {
+ ExchangeLog.LogStart("SetMailboxEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, accountName);
+ PSObject mailbox = result[0];
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(mailbox, "WindowsEmailAddress");
+ //if (winAddress != null)
+ // windowsEmail = winAddress.ToString();
+
+ string windowsEmail = ObjToString(GetPSObjectProperty(mailbox, "CustomAttribute3"));
+
+ ProxyAddressCollection emails = new ProxyAddressCollection();
+ ProxyAddress proxy = null;
+ string upn = null;
+ if (emailAddresses != null)
+ {
+ foreach (string email in emailAddresses)
+ {
+ proxy = ProxyAddress.Parse(email);
+ emails.Add(proxy);
+ if (proxy.IsPrimaryAddress)
+ {
+ upn = proxy.AddressString;
+ }
+ }
+ }
+ //add system windows email
+ if (!string.IsNullOrEmpty(windowsEmail))
+ {
+ emails.Add(ProxyAddress.Parse(windowsEmail));
+ }
+
+ Command cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("EmailAddresses", emails);
+ if (!string.IsNullOrEmpty(upn))
+ {
+ cmd.Parameters.Add("UserPrincipalName", upn);
+ cmd.Parameters.Add("WindowsEmailAddress", upn);
+ }
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetMailboxEmailAddressesInternal");
+ }
+
+ private void SetMailboxPrimaryEmailAddressInternal(string accountName, string emailAddress)
+ {
+ ExchangeLog.LogStart("SetMailboxPrimaryEmailAddressInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ SmtpAddress primaryEmail = new SmtpAddress(emailAddress);
+ Command cmd = new Command("Set-Mailbox");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("PrimarySmtpAddress", primaryEmail);
+ cmd.Parameters.Add("UserPrincipalName", primaryEmail);
+ cmd.Parameters.Add("WindowsEmailAddress", primaryEmail);
+
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetMailboxPrimaryEmailAddressInternal");
+ }
+
+
+ private ExchangeAccount[] GetSendOnBehalfAccounts(Runspace runSpace, PSObject exchangeObject)
+ {
+ List list = new List();
+
+ IList ids =
+ (IList)GetPSObjectProperty(exchangeObject, "GrantSendOnBehalfTo");
+
+ foreach (ADObjectId id in ids)
+ {
+ ExchangeAccount account = GetExchangeAccount(runSpace, id.ToString());
+ if (account != null)
+ list.Add(account);
+ }
+ return list.ToArray();
+ }
+
+ internal MultiValuedProperty SetSendOnBehalfAccounts(Runspace runspace, string[] accounts)
+ {
+ if (accounts == null || accounts.Length == 0)
+ return MultiValuedProperty.Empty;
+ else
+ {
+ MultiValuedProperty ids = new MultiValuedProperty();
+ string dn = null;
+ foreach (string account in accounts)
+ {
+ dn = GetRecipientDistinguishedName(runspace, account);
+ ids.Add(new ADObjectId(dn));
+ }
+ return ids;
+ }
+ }
+
+ private ExchangeAccount[] GetAcceptedAccounts(Runspace runSpace, PSObject mailbox)
+ {
+ List list = new List();
+ ExchangeAccount account = null;
+ IList ids =
+ (IList)GetPSObjectProperty(mailbox, "AcceptMessagesOnlyFrom");
+ foreach (ADObjectId id in ids)
+ {
+ account = GetExchangeAccount(runSpace, id.ToString());
+ if (account != null)
+ list.Add(account);
+ }
+ ids = (IList)GetPSObjectProperty(mailbox, "AcceptMessagesOnlyFromDLMembers");
+ foreach (ADObjectId id in ids)
+ {
+ account = GetExchangeAccount(runSpace, id.ToString());
+ if (account != null)
+ list.Add(account);
+ }
+
+ return list.ToArray();
+ }
+
+ private void SetAccountIds(Runspace runspace, string[] accounts,
+ out MultiValuedProperty ids, out MultiValuedProperty dlIds)
+ {
+ ids = MultiValuedProperty.Empty;
+ dlIds = MultiValuedProperty.Empty;
+
+ if (accounts == null || accounts.Length == 0)
+ return;
+
+ ids = new MultiValuedProperty();
+ dlIds = new MultiValuedProperty();
+
+ string dn = null;
+ string type = null;
+ foreach (string account in accounts)
+ {
+ type = GetRecipientType(runspace, account, out dn);
+ if (type == "MailUniversalDistributionGroup")
+ dlIds.Add(new ADObjectId(dn));
+ else
+ ids.Add(new ADObjectId(dn));
+ }
+ if (ids.Count == 0)
+ ids = MultiValuedProperty.Empty;
+ if (dlIds.Count == 0)
+ dlIds = MultiValuedProperty.Empty;
+ }
+
+
+ private ExchangeAccount[] GetRejectedAccounts(Runspace runSpace, PSObject mailbox)
+ {
+ List list = new List();
+ ExchangeAccount account = null;
+ IList ids =
+ (IList)GetPSObjectProperty(mailbox, "RejectMessagesFrom");
+ foreach (ADObjectId id in ids)
+ {
+ account = GetExchangeAccount(runSpace, id.ToString());
+ if (account != null)
+ list.Add(account);
+ }
+ ids = (IList)GetPSObjectProperty(mailbox, "RejectMessagesFromDLMembers");
+ foreach (ADObjectId id in ids)
+ {
+ account = GetExchangeAccount(runSpace, id.ToString());
+ if (account != null)
+ list.Add(account);
+ }
+ return list.ToArray();
+ }
+
+ internal ExchangeAccount GetExchangeAccount(Runspace runSpace, string id)
+ {
+ return GetOrganizationAccount(runSpace, null, id);
+ }
+
+ internal ExchangeAccount GetOrganizationAccount(Runspace runSpace, string organizationId, string id)
+ {
+ if (string.IsNullOrEmpty(id))
+ return null;
+
+ ExchangeAccount ret = null;
+ Command cmd = new Command("Get-Recipient");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ //check for organization
+ if (!string.IsNullOrEmpty(organizationId))
+ {
+ string attr1 = (string)GetPSObjectProperty(result[0], "CustomAttribute1");
+ if (!string.Equals(organizationId, attr1, StringComparison.InvariantCultureIgnoreCase))
+ return ret;
+ }
+ ret = new ExchangeAccount();
+ ret.AccountName = (string)GetPSObjectProperty(result[0], "Alias");
+ ret.DisplayName = (string)GetPSObjectProperty(result[0], "DisplayName");
+ ret.PrimaryEmailAddress = ObjToString(GetPSObjectProperty(result[0], "PrimarySmtpAddress"));
+ ret.AccountType = ParseAccountType(ObjToString(GetPSObjectProperty(result[0], "RecipientType")));
+ if (ret.AccountType == ExchangeAccountType.Contact)
+ {
+ string email = ObjToString(GetPSObjectProperty(result[0], "ExternalEmailAddress"));
+ if (!string.IsNullOrEmpty(email) && email.StartsWith("SMTP:"))
+ ret.PrimaryEmailAddress = email.Substring(5);
+ }
+ }
+ return ret;
+ }
+
+
+
+ private ExchangeAccountType ParseAccountType(string type)
+ {
+ ExchangeAccountType ret = ExchangeAccountType.Mailbox;
+ switch (type)
+ {
+ case "UserMailbox":
+ ret = ExchangeAccountType.Mailbox;
+ break;
+ case "MailContact":
+ ret = ExchangeAccountType.Contact;
+ break;
+ case "MailUniversalDistributionGroup":
+ ret = ExchangeAccountType.DistributionList;
+ break;
+ case "PublicFolder":
+ ret = ExchangeAccountType.PublicFolder;
+ break;
+ }
+ return ret;
+ }
+
+ private string GetRecipientDistinguishedName(Runspace runSpace, string id)
+ {
+ if (string.IsNullOrEmpty(id))
+ return null;
+
+ string dn = null;
+ Command cmd = new Command("Get-Recipient");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ dn = (string)GetPSObjectProperty(result[0], "DistinguishedName");
+ }
+ return dn;
+ }
+
+ private string GetRecipientType(Runspace runSpace, string id, out string name)
+ {
+ name = null;
+ if (string.IsNullOrEmpty(id))
+ return null;
+
+ string type = null;
+ Command cmd = new Command("Get-Recipient");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ name = (string)GetPSObjectProperty(result[0], "DistinguishedName");
+ type = GetPSObjectProperty(result[0], "RecipientType").ToString();
+ }
+ return type;
+ }
+
+ private ExchangeMailboxStatistics GetMailboxStatisticsInternal(string id)
+ {
+ ExchangeLog.LogStart("GetMailboxStatisticsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", id);
+
+ ExchangeMailboxStatistics info = new ExchangeMailboxStatistics();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetMailboxObject(runSpace, id);
+ PSObject mailbox = result[0];
+
+ string dn = GetResultObjectDN(result);
+ string path = AddADPrefix(dn);
+ DirectoryEntry entry = GetADObject(path);
+ info.Enabled = !(bool)entry.InvokeGet("AccountDisabled");
+
+ info.DisplayName = (string)GetPSObjectProperty(mailbox, "DisplayName");
+ SmtpAddress smtpAddress = (SmtpAddress)GetPSObjectProperty(mailbox, "PrimarySmtpAddress");
+ if (smtpAddress != null)
+ info.PrimaryEmailAddress = smtpAddress.ToString();
+
+ info.MaxSize = ConvertUnlimitedToBytes((Unlimited)GetPSObjectProperty(mailbox, "ProhibitSendReceiveQuota"));
+ DateTime? whenCreated = (DateTime?)GetPSObjectProperty(mailbox, "WhenCreated");
+ info.AccountCreated = ConvertNullableToDateTime(whenCreated);
+ //Client Access
+ Command cmd = new Command("Get-CASMailbox");
+ cmd.Parameters.Add("Identity", id);
+ result = ExecuteShellCommand(runSpace, cmd);
+ mailbox = result[0];
+
+ info.ActiveSyncEnabled = (bool)GetPSObjectProperty(mailbox, "ActiveSyncEnabled");
+ info.OWAEnabled = (bool)GetPSObjectProperty(mailbox, "OWAEnabled");
+ info.MAPIEnabled = (bool)GetPSObjectProperty(mailbox, "MAPIEnabled");
+ info.POPEnabled = (bool)GetPSObjectProperty(mailbox, "PopEnabled");
+ info.IMAPEnabled = (bool)GetPSObjectProperty(mailbox, "ImapEnabled");
+
+ //Statistics
+ cmd = new Command("Get-MailboxStatistics");
+ cmd.Parameters.Add("Identity", id);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result.Count > 0)
+ {
+ PSObject statistics = result[0];
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(statistics, "TotalItemSize");
+ info.TotalSize = ConvertUnlimitedToBytes(totalItemSize);
+ uint? itemCount = (uint?)GetPSObjectProperty(statistics, "ItemCount");
+ info.TotalItems = ConvertNullableToInt32(itemCount);
+ DateTime? lastLogoffTime = (DateTime?)GetPSObjectProperty(statistics, "LastLogoffTime");
+ DateTime? lastLogonTime = (DateTime?)GetPSObjectProperty(statistics, "LastLogonTime");
+ info.LastLogoff = ConvertNullableToDateTime(lastLogoffTime);
+ info.LastLogon = ConvertNullableToDateTime(lastLogonTime);
+ }
+ else
+ {
+ info.TotalSize = 0;
+ info.TotalItems = 0;
+ info.LastLogoff = DateTime.MinValue;
+ info.LastLogon = DateTime.MinValue;
+ }
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetMailboxStatisticsInternal");
+ return info;
+ }
+
+ private Collection GetMailboxObject(Runspace runSpace, string id)
+ {
+ Command cmd = new Command("Get-Mailbox");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ return result;
+ }
+
+ #endregion
+
+ #region Contacts
+ private void CreateContactInternal(
+ string organizationId,
+ string organizationDistinguishedName,
+ string contactDisplayName,
+ string contactAccountName,
+ string contactEmail,
+ string defaultOrganizationDomain)
+ {
+ ExchangeLog.LogStart("CreateContactInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationId);
+ ExchangeLog.DebugInfo("Name: {0}", contactDisplayName);
+ ExchangeLog.DebugInfo("Account: {0}", contactAccountName);
+ ExchangeLog.DebugInfo("Email: {0}", contactEmail);
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string ouName = ConvertADPathToCanonicalName(organizationDistinguishedName);
+ string tempEmail = string.Format("{0}@{1}", Guid.NewGuid().ToString("N"), defaultOrganizationDomain);
+ //create contact
+ Command cmd = new Command("New-MailContact");
+ cmd.Parameters.Add("Name", contactAccountName);
+ cmd.Parameters.Add("DisplayName", contactDisplayName);
+ cmd.Parameters.Add("OrganizationalUnit", ouName);
+ cmd.Parameters.Add("Alias", contactAccountName);
+ cmd.Parameters.Add("ExternalEmailAddress", tempEmail);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectDN(result);
+
+ transaction.RegisterNewContact(id);
+
+ //update contact
+ cmd = new Command("Set-MailContact");
+ cmd.Parameters.Add("Identity", contactAccountName);
+ cmd.Parameters.Add("EmailAddressPolicyEnabled", false);
+ cmd.Parameters.Add("CustomAttribute1", organizationId);
+ cmd.Parameters.Add("WindowsEmailAddress", tempEmail);
+ ExecuteShellCommand(runSpace, cmd);
+
+ SetContactEmail(id, contactEmail);
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateContactInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+
+ ExchangeLog.LogEnd("CreateContactInternal");
+ }
+
+ private void DeleteContactInternal(string accountName)
+ {
+ ExchangeLog.LogStart("DeleteContactInternal");
+ ExchangeLog.DebugInfo("Account Name: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ RemoveContact(runSpace, accountName);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DeleteContactInternal");
+ }
+
+ private void RemoveContact(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("RemoveContact");
+ Command cmd = new Command("Remove-MailContact");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("RemoveContact");
+ }
+
+ private ExchangeContact GetContactGeneralSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetContactGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeContact info = new ExchangeContact();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-MailContact");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject contact = result[0];
+ string id = GetResultObjectDN(result);
+
+ info.DisplayName = (string)GetPSObjectProperty(contact, "DisplayName");
+ info.HideFromAddressBook = (bool)GetPSObjectProperty(contact, "HiddenFromAddressListsEnabled");
+ info.EmailAddress = GetContactEmail(id);
+ info.UseMapiRichTextFormat = (int)GetPSObjectProperty(contact, "UseMapiRichTextFormat");
+
+ cmd = new Command("Get-Contact");
+ cmd.Parameters.Add("Identity", accountName);
+ result = ExecuteShellCommand(runSpace, cmd);
+ PSObject user = result[0];
+
+ info.FirstName = (string)GetPSObjectProperty(user, "FirstName");
+ info.Initials = (string)GetPSObjectProperty(user, "Initials");
+ info.LastName = (string)GetPSObjectProperty(user, "LastName");
+
+ info.Address = (string)GetPSObjectProperty(user, "StreetAddress");
+ info.City = (string)GetPSObjectProperty(user, "City");
+ info.State = (string)GetPSObjectProperty(user, "StateOrProvince");
+ info.Zip = (string)GetPSObjectProperty(user, "PostalCode");
+ info.Country = CountryInfoToString((CountryInfo)GetPSObjectProperty(user, "CountryOrRegion"));
+ info.JobTitle = (string)GetPSObjectProperty(user, "Title");
+ info.Company = (string)GetPSObjectProperty(user, "Company");
+ info.Department = (string)GetPSObjectProperty(user, "Department");
+ info.Office = (string)GetPSObjectProperty(user, "Office");
+ info.ManagerAccount = GetExchangeAccount(runSpace, ObjToString(GetPSObjectProperty(user, "Manager")));
+ info.BusinessPhone = (string)GetPSObjectProperty(user, "Phone");
+ info.Fax = (string)GetPSObjectProperty(user, "Fax");
+ info.HomePhone = (string)GetPSObjectProperty(user, "HomePhone");
+ info.MobilePhone = (string)GetPSObjectProperty(user, "MobilePhone");
+ info.Pager = (string)GetPSObjectProperty(user, "Pager");
+ info.WebPage = (string)GetPSObjectProperty(user, "WebPage");
+ info.Notes = (string)GetPSObjectProperty(user, "Notes");
+
+ info.SAMAccountName = string.Format("{0}\\{1}", GetNETBIOSDomainName(), (string)GetPSObjectProperty(user, "Name"));
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetContactGeneralSettingsInternal");
+ return info;
+ }
+
+ private void SetContactEmail(string id, string email)
+ {
+ string cn = ActiveDirectoryUtils.AddADPrefix(id, PrimaryDomainController);
+ DirectoryEntry de = ActiveDirectoryUtils.GetADObject(cn);
+ ActiveDirectoryUtils.SetADObjectPropertyValue(de, "targetAddress", "SMTP:" + email);
+ //ActiveDirectoryUtils.SetADObjectPropertyValue(de, "mail", email);
+ de.CommitChanges();
+
+ }
+
+ private string GetContactEmail(string id)
+ {
+ string cn = ActiveDirectoryUtils.AddADPrefix(id, PrimaryDomainController);
+ DirectoryEntry de = ActiveDirectoryUtils.GetADObject(cn);
+ string email = ActiveDirectoryUtils.GetADObjectStringProperty(de, "targetAddress");
+ if (email != null && email.ToLower().StartsWith("smtp:"))
+ email = email.Substring(5);
+ return email;
+ }
+
+ private void SetContactGeneralSettingsInternal(string accountName, string displayName, string email,
+ bool hideFromAddressBook, string firstName, string initials, string lastName, string address,
+ string city, string state, string zip, string country, string jobTitle, string company,
+ string department, string office, string managerAccountName, string businessPhone, string fax,
+ string homePhone, string mobilePhone, string pager, string webPage, string notes, int useMapiRichTextFormat, string defaultDomain)
+ {
+ ExchangeLog.LogStart("SetContactGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = new Command("Get-MailContact");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ string id = GetResultObjectDN(result);
+ string tempEmail = SmtpAddressToString((SmtpAddress)GetPSObjectProperty(result[0], "PrimarySmtpAddress"));
+ string[] parts = tempEmail.Split('@');
+ if (parts != null && parts.Length > 0)
+ tempEmail = parts[0] + '@' + defaultDomain;
+
+ cmd = new Command("Set-MailContact");
+ cmd.Parameters.Add("Identity", accountName);
+
+ cmd.Parameters.Add("DisplayName", displayName);
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", hideFromAddressBook);
+ cmd.Parameters.Add("ExternalEmailAddress", tempEmail);
+ cmd.Parameters.Add("UseMapiRichTextFormat", (UseMapiRichTextFormat)useMapiRichTextFormat);
+ cmd.Parameters.Add("WindowsEmailAddress", tempEmail);
+ ExecuteShellCommand(runSpace, cmd);
+
+
+ cmd = new Command("Set-Contact");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("FirstName", firstName);
+ cmd.Parameters.Add("Initials", initials);
+ cmd.Parameters.Add("LastName", lastName);
+ cmd.Parameters.Add("StreetAddress", address);
+ cmd.Parameters.Add("City", city);
+ cmd.Parameters.Add("StateOrProvince", state);
+ cmd.Parameters.Add("PostalCode", zip);
+ cmd.Parameters.Add("CountryOrRegion", ParseCountryInfo(country));
+ cmd.Parameters.Add("Title", jobTitle);
+ cmd.Parameters.Add("Company", company);
+ cmd.Parameters.Add("Department", department);
+ cmd.Parameters.Add("Office", office);
+ cmd.Parameters.Add("Manager", managerAccountName);
+ cmd.Parameters.Add("Phone", businessPhone);
+ cmd.Parameters.Add("Fax", fax);
+ cmd.Parameters.Add("HomePhone", homePhone);
+ cmd.Parameters.Add("MobilePhone", mobilePhone);
+ cmd.Parameters.Add("Pager", pager);
+ cmd.Parameters.Add("WebPage", webPage);
+ cmd.Parameters.Add("Notes", notes);
+
+ ExecuteShellCommand(runSpace, cmd);
+
+ SetContactEmail(id, email);
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetContactGeneralSettingsInternal");
+ }
+
+ private ExchangeContact GetContactMailFlowSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetContactMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeContact info = new ExchangeContact();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-MailContact");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject contact = result[0];
+
+ info.AcceptAccounts = GetAcceptedAccounts(runSpace, contact);
+ info.RejectAccounts = GetRejectedAccounts(runSpace, contact);
+ info.RequireSenderAuthentication = (bool)GetPSObjectProperty(contact, "RequireSenderAuthenticationEnabled");
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetContactMailFlowSettingsInternal");
+ return info;
+ }
+
+ private void SetContactMailFlowSettingsInternal(string accountName, string[] acceptAccounts,
+ string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ ExchangeLog.LogStart("SetContactMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Set-MailContact");
+ cmd.Parameters.Add("Identity", accountName);
+
+ MultiValuedProperty ids = null;
+ MultiValuedProperty dlIds = null;
+
+ SetAccountIds(runSpace, acceptAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("AcceptMessagesOnlyFrom", ids);
+ cmd.Parameters.Add("AcceptMessagesOnlyFromDLMembers", dlIds);
+
+ SetAccountIds(runSpace, rejectAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("RejectMessagesFrom", ids);
+ cmd.Parameters.Add("RejectMessagesFromDLMembers", dlIds);
+ cmd.Parameters.Add("RequireSenderAuthenticationEnabled", requireSenderAuthentication);
+
+ ExecuteShellCommand(runSpace, cmd);
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetContactMailFlowSettingsInternal");
+ }
+
+ #endregion
+
+ #region Distribution groups
+ ///
+ /// Creates Security Distribution Group
+ ///
+ ///
+ ///
+ ///
+ /// LDAP path
+ private string CreateSecurityDistributionGroup(Runspace runSpace, string ouName, string groupName)
+ {
+ ExchangeLog.LogStart("CreateSecurityDistributionGroup");
+
+ Command cmd = new Command("New-DistributionGroup");
+ cmd.Parameters.Add("Name", groupName);
+ cmd.Parameters.Add("Type", "Security");
+ cmd.Parameters.Add("OrganizationalUnit", ouName);
+ cmd.Parameters.Add("SamAccountName", groupName);
+ cmd.Parameters.Add("Alias", groupName);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = CheckResultObjectDN(result);
+
+ ExchangeLog.LogEnd("CreateSecurityDistributionGroup");
+ return id;
+ }
+
+ internal string EnableMailSecurityDistributionGroup(Runspace runSpace, string distName, string groupName)
+ {
+ ExchangeLog.LogStart("EnableMailSecurityDistributionGroup");
+ ExchangeLog.DebugInfo("Group Distinguished Name: {0}", distName);
+ ExchangeLog.DebugInfo("Group Name: {0}", groupName);
+
+ int attempts = 0;
+ string securityGroupId = null;
+
+ while (true)
+ {
+ try
+ {
+ Command cmd = new Command("Enable-DistributionGroup");
+ cmd.Parameters.Add("Identity", distName);
+ cmd.Parameters.Add("Alias", groupName);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ securityGroupId = CheckResultObjectDN(result);
+ ExchangeLog.DebugInfo("Result: {0}", securityGroupId);
+ }
+ catch (Exception ex)
+ {
+ Log.WriteError(ex);
+ }
+
+ if (securityGroupId != null)
+ break;
+
+ if (attempts > 3)
+ throw new Exception(
+ string.Format("Could not enable mail Security Distribution Group '{0}' ", groupName));
+
+ attempts++;
+ ExchangeLog.LogWarning("Attempt #{0} to enable mail Security Distribution Group failed!", attempts);
+ // wait 5 sec
+ System.Threading.Thread.Sleep(5000);
+ }
+
+
+ ExchangeLog.LogEnd("EnableMailSecurityDistributionGroup");
+ return securityGroupId;
+ }
+
+ internal void DisableMailSecurityDistributionGroup(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DisableMailSecurityDistributionGroup");
+ ExchangeLog.DebugInfo("Group Id: {0}", id);
+ Command cmd = new Command("Disable-DistributionGroup");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DisableMailSecurityDistributionGroup");
+ }
+
+
+ internal void UpdateSecurityDistributionGroup(Runspace runSpace, string id, string groupName, bool isConsumer)
+ {
+ ExchangeLog.LogStart("UpdateSecurityDistributionGroup");
+
+ Command cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("EmailAddressPolicyEnabled", false);
+ cmd.Parameters.Add("CustomAttribute1", groupName);
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", !isConsumer);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("UpdateSecurityDistributionGroup");
+ }
+
+ private void CreateDistributionListInternal(
+ string organizationId,
+ string organizationDistinguishedName,
+ string displayName,
+ string accountName,
+ string name,
+ string domain,
+ string managedBy,
+ string[] addressLists)
+ {
+ ExchangeLog.LogStart("CreateDistributionListInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationId);
+ ExchangeLog.DebugInfo("Name: {0}", name);
+ ExchangeLog.DebugInfo("Domain: {0}", domain);
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ string email = string.Format("{0}@{1}", name, domain);
+ string ouName = ConvertADPathToCanonicalName(organizationDistinguishedName);
+
+ Command cmd = new Command("New-DistributionGroup");
+ cmd.Parameters.Add("Name", accountName);
+ cmd.Parameters.Add("DisplayName", displayName);
+ cmd.Parameters.Add("Type", "Security");
+ cmd.Parameters.Add("OrganizationalUnit", ouName);
+ cmd.Parameters.Add("SamAccountName", accountName);
+ cmd.Parameters.Add("Alias", accountName);
+ cmd.Parameters.Add("ManagedBy", managedBy);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectDN(result);
+
+ transaction.RegisterNewDistributionGroup(id);
+
+ //add manager permissions
+ if (!string.IsNullOrEmpty(managedBy))
+ {
+ AddADPermission(runSpace, accountName, managedBy, "WriteProperty", null, "Member");
+ }
+
+ string windowsEmailAddress = ObjToString(GetPSObjectProperty(result[0], "WindowsEmailAddress"));
+
+ //update
+ cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("EmailAddressPolicyEnabled", false);
+ cmd.Parameters.Add("CustomAttribute1", organizationId);
+ cmd.Parameters.Add("CustomAttribute3", windowsEmailAddress);
+ cmd.Parameters.Add("PrimarySmtpAddress", email);
+ cmd.Parameters.Add("WindowsEmailAddress", email);
+ cmd.Parameters.Add("RequireSenderAuthenticationEnabled", false);
+ ExecuteShellCommand(runSpace, cmd);
+
+ //fix showInAddressBook Attribute
+ if (addressLists.Length > 0)
+ FixShowInAddressBook(runSpace, email, addressLists, false);
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreateDistributionListInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CreateDistributionListInternal");
+ }
+
+ private void FixShowInAddressBook(Runspace runSpace, string accountName, string[] addressLists, bool HideFromAddressList)
+ {
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectDN(result);
+
+ DirectoryEntry dlDEEntry = GetADObject(AddADPrefix(id));
+ dlDEEntry.Properties["showInAddressBook"].Clear();
+ if (!HideFromAddressList)
+ {
+ foreach (string addressList in addressLists)
+ {
+ dlDEEntry.Properties["showInAddressBook"].Add(addressList);
+ }
+ }
+ dlDEEntry.CommitChanges();
+ }
+
+ private void DeleteDistributionListInternal(string accountName)
+ {
+ ExchangeLog.LogStart("DeleteDistributionListInternal");
+ ExchangeLog.DebugInfo("Account Name: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ RemoveDistributionGroup(runSpace, accountName);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DeleteDistributionListInternal");
+ }
+
+ internal virtual void RemoveDistributionGroup(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("RemoveDistributionGroup");
+ Command cmd = new Command("Remove-DistributionGroup");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("RemoveDistributionGroup");
+ }
+
+ private ExchangeDistributionList GetDistributionListGeneralSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetDistributionListGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeDistributionList info = new ExchangeDistributionList();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = result[0];
+
+ info.DisplayName = (string)GetPSObjectProperty(distributionGroup, "DisplayName");
+ info.HideFromAddressBook =
+ (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled");
+
+ info.SAMAccountName = string.Format("{0}\\{1}", GetNETBIOSDomainName(), (string)GetPSObjectProperty(distributionGroup, "SamAccountName"));
+
+ cmd = new Command("Get-Group");
+ cmd.Parameters.Add("Identity", accountName);
+ result = ExecuteShellCommand(runSpace, cmd);
+ PSObject group = result[0];
+
+ info.ManagerAccount = GetGroupManagerAccount(runSpace, group);
+ info.MembersAccounts = GetGroupMembers(runSpace, accountName);
+ info.Notes = (string)GetPSObjectProperty(group, "Notes");
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetDistributionListGeneralSettingsInternal");
+ return info;
+ }
+
+ internal virtual ExchangeAccount GetGroupManagerAccount(Runspace runSpace, PSObject group)
+ {
+ return GetExchangeAccount(runSpace, GetGroupManager(group));
+ }
+
+ internal virtual string GetGroupManager(PSObject group)
+ {
+ string ret = null;
+ MultiValuedProperty ids =
+ (MultiValuedProperty)GetPSObjectProperty(group, "ManagedBy");
+ if (ids.Count > 0)
+ ret = ObjToString(ids[0]);
+ return ret;
+ }
+
+ private void SetDistributionListGeneralSettingsInternal(string accountName, string displayName,
+ bool hideFromAddressBook, string managedBy, string[] memberAccounts, string notes, string[] addressLists)
+ {
+ ExchangeLog.LogStart("SetDistributionListGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ SetDistributionGroup(runSpace, accountName, displayName, hideFromAddressBook);
+
+ //get old values
+ Command cmd = new Command("Get-Group");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject group = result[0];
+ string manager = GetGroupManager(group);
+
+ //set members
+ ExchangeAccount[] accounts = GetGroupMembers(runSpace, accountName);
+ Dictionary existingMembers = new Dictionary();
+ Dictionary newMembers = new Dictionary();
+ List membersToDelete = new List();
+ List membersToAdd = new List();
+
+ foreach (ExchangeAccount account in accounts)
+ {
+ existingMembers.Add(account.AccountName.ToLower(), account.AccountName);
+ }
+
+ foreach (string member in memberAccounts)
+ {
+ newMembers.Add(member.ToLower(), member);
+ if (!existingMembers.ContainsKey(member.ToLower()))
+ {
+ membersToAdd.Add(member);
+ }
+ }
+
+ foreach (string delAccount in existingMembers.Keys)
+ {
+ if (!newMembers.ContainsKey(delAccount))
+ {
+ membersToDelete.Add(existingMembers[delAccount]);
+ }
+ }
+
+ foreach (string member in membersToAdd)
+ {
+ AddDistributionGroupMember(runSpace, accountName, member);
+ }
+
+ foreach (string member in membersToDelete)
+ {
+ RemoveDistributionGroupMember(runSpace, accountName, member);
+ }
+
+ //remove old manager rights
+ if (!string.IsNullOrEmpty(manager))
+ {
+ RemoveADPermission(runSpace, accountName, manager, "WriteProperty", null, "Member");
+ }
+
+ SetGroup(runSpace, accountName, managedBy, notes);
+
+ if (!string.IsNullOrEmpty(managedBy))
+ {
+ AddADPermission(runSpace, accountName, managedBy, "WriteProperty", null, "Member");
+ }
+
+ if (addressLists.Length > 0)
+ FixShowInAddressBook(runSpace, accountName, addressLists, hideFromAddressBook);
+
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetDistributionListGeneralSettingsInternal");
+ }
+
+ internal virtual void RemoveDistributionGroupMember(Runspace runSpace, string group, string member)
+ {
+ Command cmd = new Command("Remove-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", group);
+ cmd.Parameters.Add("Member", member);
+ cmd.Parameters.Add("Confirm", false);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+ internal virtual void AddDistributionGroupMember(Runspace runSpace, string group, string member)
+ {
+ Command cmd = new Command("Add-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", group);
+ cmd.Parameters.Add("Member", member);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+
+ internal virtual void SetGroup(Runspace runSpace, string id, string managedBy, string notes)
+ {
+ Command cmd = new Command("Set-Group");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("ManagedBy", managedBy);
+ cmd.Parameters.Add("Notes", notes);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+ internal virtual void SetDistributionGroup(Runspace runSpace, string id, string displayName, bool hideFromAddressBook)
+ {
+ Command cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("DisplayName", displayName);
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", hideFromAddressBook);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+
+ private void AddDistributionListMembersInternal(string accountName, string[] memberAccounts, string[] addressLists)
+ {
+ ExchangeLog.LogStart("AddDistributionListMembersInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ if (memberAccounts != null && memberAccounts.Length > 0)
+ {
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = null;
+
+ foreach (string member in memberAccounts)
+ {
+ cmd = new Command("Add-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("Member", member);
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck", true);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+ if (addressLists.Length > 0)
+ {
+ cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = result[0];
+
+ FixShowInAddressBook(runSpace, accountName, addressLists, (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled"));
+ }
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ }
+ ExchangeLog.LogEnd("AddDistributionListMembersInternal");
+ }
+
+ private void RemoveDistributionListMembersInternal(string accountName, string[] memberAccounts, string[] addressLists)
+ {
+ ExchangeLog.LogStart("RemoveDistributionListMembersInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ if (memberAccounts != null && memberAccounts.Length > 0)
+ {
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Command cmd = null;
+
+ foreach (string member in memberAccounts)
+ {
+ cmd = new Command("Remove-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("Member", member);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+
+ if (addressLists.Length > 0)
+ {
+ cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = result[0];
+
+ FixShowInAddressBook(runSpace, accountName, addressLists, (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled"));
+ }
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ }
+ ExchangeLog.LogEnd("RemoveDistributionListMembersInternal");
+ }
+
+ private ExchangeDistributionList GetDistributionListMailFlowSettingsInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetDistributionListMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ ExchangeDistributionList info = new ExchangeDistributionList();
+ info.AccountName = accountName;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject group = result[0];
+
+ info.AcceptAccounts = GetAcceptedAccounts(runSpace, group);
+ info.RejectAccounts = GetRejectedAccounts(runSpace, group);
+ info.RequireSenderAuthentication = (bool)GetPSObjectProperty(group, "RequireSenderAuthenticationEnabled");
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetDistributionListMailFlowSettingsInternal");
+ return info;
+ }
+
+ private void SetDistributionListMailFlowSettingsInternal(string accountName,
+ string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication, string[] addressLists)
+ {
+ ExchangeLog.LogStart("SetDistributionListMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+
+ MultiValuedProperty ids = null;
+ MultiValuedProperty dlIds = null;
+
+ SetAccountIds(runSpace, acceptAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("AcceptMessagesOnlyFrom", ids);
+ cmd.Parameters.Add("AcceptMessagesOnlyFromDLMembers", dlIds);
+
+ SetAccountIds(runSpace, rejectAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("RejectMessagesFrom", ids);
+ cmd.Parameters.Add("RejectMessagesFromDLMembers", dlIds);
+ cmd.Parameters.Add("RequireSenderAuthenticationEnabled", requireSenderAuthentication);
+
+ ExecuteShellCommand(runSpace, cmd);
+
+ if (addressLists.Length > 0)
+ {
+ cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = result[0];
+
+ FixShowInAddressBook(runSpace, accountName, addressLists, (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled"));
+ }
+
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetDistributionListMailFlowSettingsInternal");
+ }
+
+ private ExchangeAccount[] GetGroupMembers(Runspace runSpace, string groupId)
+ {
+ ExchangeLog.LogStart("GetGroupMembers");
+ List list = new List();
+ Command cmd = new Command("Get-DistributionGroupMember");
+ cmd.Parameters.Add("Identity", groupId);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeAccount account = null;
+ string id = null;
+
+ foreach (PSObject obj in result)
+ {
+ id = GetPSObjectIdentity(obj);
+ account = GetExchangeAccount(runSpace, id);
+ if (account != null)
+ list.Add(account);
+ }
+ ExchangeLog.LogEnd("GetGroupMembers");
+ return list.ToArray();
+ }
+
+ private ExchangeEmailAddress[] GetDistributionListEmailAddressesInternal(string accountName)
+ {
+ ExchangeLog.LogStart("GetDistributionListEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ List list = new List();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject group = result[0];
+
+ string primaryEmail = null;
+ string windowsEmail = null;
+
+ SmtpAddress smtpAddress = (SmtpAddress)GetPSObjectProperty(group, "PrimarySmtpAddress");
+ if (smtpAddress != null)
+ primaryEmail = smtpAddress.ToString();
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(group, "WindowsEmailAddress");
+ //if (winAddress != null)
+ // windowsEmail = winAddress.ToString();
+ windowsEmail = ObjToString(GetPSObjectProperty(group, "CustomAttribute3"));
+
+
+ ProxyAddressCollection emails = (ProxyAddressCollection)GetPSObjectProperty(group, "EmailAddresses");
+ foreach (ProxyAddress email in emails)
+ {
+ //skip windows email
+ if (string.Equals(email.AddressString, windowsEmail, StringComparison.OrdinalIgnoreCase))
+ continue;
+
+ ExchangeEmailAddress item = new ExchangeEmailAddress();
+ item.Email = email.AddressString;
+ item.Primary = string.Equals(item.Email, primaryEmail, StringComparison.OrdinalIgnoreCase);
+ list.Add(item);
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetDistributionListEmailAddressesInternal");
+ return list.ToArray();
+ }
+
+ private void SetDistributionListEmailAddressesInternal(string accountName, string[] emailAddresses, string[] addressLists)
+ {
+ ExchangeLog.LogStart("SetDistributionListEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject group = result[0];
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(group, "WindowsEmailAddress");
+ //string windowsEmail = ObjToString(winAddress);
+ string windowsEmail = ObjToString(GetPSObjectProperty(group, "CustomAttribute3"));
+
+ ProxyAddressCollection emails = new ProxyAddressCollection();
+ ProxyAddress proxy = null;
+ string primaryEmail = null;
+
+ if (emailAddresses != null)
+ {
+ foreach (string email in emailAddresses)
+ {
+ proxy = ProxyAddress.Parse(email);
+ emails.Add(proxy);
+ if (proxy.IsPrimaryAddress)
+ {
+ primaryEmail = proxy.AddressString;
+ }
+ }
+ }
+ //add system windows email
+ if (!string.IsNullOrEmpty(windowsEmail))
+ {
+ emails.Add(ProxyAddress.Parse(windowsEmail));
+ }
+
+ cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("EmailAddresses", emails);
+ if (!string.IsNullOrEmpty(primaryEmail))
+ {
+ cmd.Parameters.Add("WindowsEmailAddress", primaryEmail);
+ }
+ ExecuteShellCommand(runSpace, cmd);
+
+ if (addressLists.Length > 0)
+ {
+ cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection r = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = r[0];
+
+ FixShowInAddressBook(runSpace, accountName, addressLists, (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled"));
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetDistributionListEmailAddressesInternal");
+ }
+
+ private void SetDistributionListPrimaryEmailAddressInternal(string accountName, string emailAddress, string[] addressLists)
+ {
+ ExchangeLog.LogStart("SetDistributionListPrimaryEmailAddressInternal");
+ ExchangeLog.DebugInfo("Account: {0}", accountName);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ SmtpAddress primaryEmail = new SmtpAddress(emailAddress);
+ Command cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("PrimarySmtpAddress", primaryEmail);
+ cmd.Parameters.Add("WindowsEmailAddress", primaryEmail);
+
+ ExecuteShellCommand(runSpace, cmd);
+
+
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetDistributionListPrimaryEmailAddressInternal");
+ }
+
+ private ExchangeDistributionList GetDistributionListPermissionsInternal(string organizationId, string accountName, Runspace runspace)
+ {
+ ExchangeLog.LogStart("GetDistributionListPermissionsInternal");
+
+ if (string.IsNullOrEmpty(accountName))
+ throw new ArgumentNullException("accountName");
+
+ ExchangeDistributionList exchangeDistributionList = null;
+ bool closeRunspace = false;
+
+ try
+ {
+ if (runspace == null)
+ {
+ runspace = OpenRunspace();
+ closeRunspace = true;
+ }
+
+ Command cmd = new Command("Get-DistributionGroup");
+
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runspace, cmd);
+ PSObject distributionGroup = result[0];
+ string cn = GetPSObjectProperty(distributionGroup, "Name") as string;
+
+
+ exchangeDistributionList = new ExchangeDistributionList();
+ exchangeDistributionList.AccountName = accountName;
+ exchangeDistributionList.SendOnBehalfAccounts = GetSendOnBehalfAccounts(runspace, distributionGroup);
+ exchangeDistributionList.SendAsAccounts = GetSendAsAccounts(runspace, organizationId, cn);
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ throw ex;
+ }
+ finally
+ {
+ if (closeRunspace)
+ CloseRunspace(runspace);
+ }
+
+ ExchangeLog.LogEnd("GetDistributionListPermissionsInternal");
+ return exchangeDistributionList;
+ }
+
+ private void SetDistributionListPermissionsInternal(string organizationId, string accountName, string[] sendAsAccounts, string[] sendOnBehalfAccounts, string[] addressLists)
+ {
+ ExchangeLog.LogStart("SetDistributionListPermissionsInternal");
+
+ if (string.IsNullOrEmpty(accountName))
+ throw new ArgumentNullException("accountName");
+
+ if (sendAsAccounts == null)
+ throw new ArgumentNullException("sendAsAccounts");
+
+
+ if (sendOnBehalfAccounts == null)
+ throw new ArgumentNullException("sendOnBehalfAccounts");
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+ string cn = GetDistributionListCommonName(runSpace, accountName);
+ ExchangeDistributionList distributionList = GetDistributionListPermissionsInternal(organizationId, accountName, runSpace);
+ SetSendAsPermissions(runSpace, distributionList.SendAsAccounts, cn, sendAsAccounts);
+ SetDistributionListSendOnBehalfAccounts(runSpace, accountName, sendOnBehalfAccounts);
+
+ if (addressLists.Length > 0)
+ {
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject distributionGroup = result[0];
+
+ FixShowInAddressBook(runSpace, accountName, addressLists, (bool)GetPSObjectProperty(distributionGroup, "HiddenFromAddressListsEnabled"));
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ throw;
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+
+ ExchangeLog.LogEnd("SetDistributionListPermissionsInternal");
+ }
+
+ internal virtual void SetDistributionListSendOnBehalfAccounts(Runspace runspace, string accountName, string[] sendOnBehalfAccounts)
+ {
+ ExchangeLog.LogStart("SetDistributionListSendOnBehalfAccounts");
+ Command cmd = new Command("Set-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ cmd.Parameters.Add("GrantSendOnBehalfTo", SetSendOnBehalfAccounts(runspace, sendOnBehalfAccounts));
+ cmd.Parameters.Add("BypassSecurityGroupManagerCheck");
+ ExecuteShellCommand(runspace, cmd);
+ ExchangeLog.LogEnd("SetDistributionListSendOnBehalfAccounts");
+ }
+
+ private string GetDistributionListCommonName(Runspace runSpace, string accountName)
+ {
+ ExchangeLog.LogStart("GetDistributionListCommonName");
+ Command cmd = new Command("Get-DistributionGroup");
+ cmd.Parameters.Add("Identity", accountName);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject obj = result[0];
+ string cn = GetPSObjectProperty(obj, "Name") as string;
+ ExchangeLog.LogEnd("GeDistributionListCommonName");
+ return cn;
+ }
+
+ #endregion
+
+ #region Public folders
+
+ private void CreatePublicFolderInternal(string organizationId, string securityGroup, string parentFolder,
+ string folderName, bool mailEnabled, string accountName, string name, string domain)
+ {
+ ExchangeLog.LogStart("CreatePublicFolderInternal");
+ ExchangeLog.DebugInfo("Organization Id: {0}", organizationId);
+ ExchangeLog.DebugInfo("Parent: {0}", parentFolder);
+ ExchangeLog.DebugInfo("Name: {0}", folderName);
+
+ ExchangeTransaction transaction = StartTransaction();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ //create organization root folder if required
+ CheckOrganizationRootFolder(runSpace, organizationId, securityGroup);
+
+ string id = AddPublicFolder(runSpace, folderName, parentFolder);
+ transaction.RegisterNewPublicFolder(id);
+
+ SetPublicFolderPermissions(runSpace, id, securityGroup);
+
+ if (mailEnabled)
+ {
+ EnableMailPublicFolderInternal(organizationId, id, accountName, name, domain);
+ }
+
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError("CreatePublicFolderInternal", ex);
+ RollbackTransaction(transaction);
+ throw;
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("CreatePublicFolderInternal");
+ }
+
+ private void CheckOrganizationRootFolder(Runspace runSpace, string folder, string user)
+ {
+ ExchangeLog.LogStart("CheckOrganizationRootFolder");
+
+ Collection result = GetPublicFolderObject(runSpace, "\\" + folder);
+ if (result == null || result.Count == 0)
+ {
+ ExchangeTransaction transaction = StartTransaction();
+ try
+ {
+ string rootId = AddPublicFolder(runSpace, folder, "\\");
+ transaction.RegisterNewPublicFolder(rootId);
+ SetPublicFolderPermissions(runSpace, rootId, user);
+ }
+ catch
+ {
+ RollbackTransaction(transaction);
+ throw;
+ }
+ }
+ ExchangeLog.LogEnd("CheckOrganizationRootFolder");
+ }
+
+ private string AddPublicFolder(Runspace runSpace, string name, string path)
+ {
+ ExchangeLog.LogStart("CreatePublicFolder");
+ Command cmd = new Command("New-PublicFolder");
+ cmd.Parameters.Add("Name", name);
+ cmd.Parameters.Add("Path", path);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectIdentity(result);
+ ExchangeLog.LogEnd("CreatePublicFolder");
+ return id;
+ }
+
+ private void DeletePublicFolderInternal(string folder)
+ {
+ ExchangeLog.LogStart("DeletePublicFolderInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ RemovePublicFolder(runSpace, folder);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DeletePublicFolderInternal");
+ }
+
+ private Collection GetPublicFolderObject(Runspace runSpace, string id)
+ {
+ Command cmd = new Command("Get-PublicFolder");
+ cmd.Parameters.Add("Identity", id);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ return result;
+ }
+
+ private bool PublicFolderExists(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("PublicFolderExists");
+
+ Collection result = GetPublicFolderObject(runSpace, id);
+ bool ret = (result != null && result.Count == 1);
+ ExchangeLog.LogEnd("PublicFolderExists");
+ return ret;
+ }
+
+ private void RemovePublicFolder(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("RemovePublicFolder");
+
+ Command cmd = new Command("Remove-PublicFolder");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Recurse", new SwitchParameter(true));
+ cmd.Parameters.Add("Confirm", false);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ ExecuteShellCommand(runSpace, cmd);
+
+ ExchangeLog.LogEnd("RemovePublicFolder");
+ }
+
+ private void SetPublicFolderPermissions(Runspace runSpace, string folder, string securityGroup)
+ {
+ //set the default Permission to 'Reviewer'
+ RemovePublicFolderClientPermission(runSpace, folder, "Default", "Author");
+ AddPublicFolderClientPermission(runSpace, folder, securityGroup, "Reviewer");
+ }
+
+ private void RemovePublicFolderClientPermission(Runspace runSpace, string id, string user,
+ string permission)
+ {
+ ExchangeLog.LogStart("RemovePublicFolderClientPermission");
+
+ Command cmd = new Command("Remove-PublicFolderClientPermission");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("User", user);
+ cmd.Parameters.Add("AccessRights", permission);
+ cmd.Parameters.Add("Confirm", false);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("RemovePublicFolderClientPermission");
+ }
+
+ private void AddPublicFolderClientPermission(Runspace runSpace, string id, string user, string permission)
+ {
+ ExchangeLog.LogStart("AddPublicFolderClientPermission");
+
+ Command cmd = new Command("Add-PublicFolderClientPermission");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("User", user);
+ cmd.Parameters.Add("AccessRights", permission);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("AddPublicFolderClientPermission");
+ }
+
+ private void GetPublicFolderClientPermission(Runspace runSpace, string id)
+ {
+ Command cmd = new Command("Get-PublicFolderClientPermission");
+ cmd.Parameters.Add("Identity", id);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject obj = result[0];
+ }
+
+
+ private void EnableMailPublicFolderInternal(string organizationId, string folder, string accountName,
+ string name, string domain)
+ {
+ ExchangeLog.LogStart("EnableMailPublicFolderInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Enable-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ ExecuteShellCommand(runSpace, cmd);
+ string id = null;
+
+ //try to avoid message: "The Active Directory proxy object for the public folder 'XXX'
+ // is being generated. Please try again later."
+ int attempts = 0;
+ string windowsEmailAddress = null;
+ while (true)
+ {
+ cmd = new Command("Get-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ id = GetResultObjectIdentity(result);
+ windowsEmailAddress = ObjToString(GetPSObjectProperty(result[0], "WindowsEmailAddress"));
+ break;
+ }
+
+ if (attempts > 9)
+ {
+ string error = string.Format("Active Directory proxy object for the public folder '{0}' was not found or not generated yet.", folder);
+ throw new Exception(error);
+ }
+
+ attempts++;
+ ExchangeLog.LogWarning("Attemp {0} to create mail public folder {1}", attempts, folder);
+ System.Threading.Thread.Sleep(5000);
+ }
+
+ string email = string.Format("{0}@{1}", name, domain);
+ // fix issue with 2 DC
+ attempts = 0;
+ bool success = false;
+ object[] errors;
+ while (true)
+ {
+ try
+ {
+ cmd = new Command("Set-MailPublicFolder");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Alias", accountName);
+ cmd.Parameters.Add("EmailAddressPolicyEnabled", false);
+ cmd.Parameters.Add("CustomAttribute1", organizationId);
+ cmd.Parameters.Add("CustomAttribute3", windowsEmailAddress);
+ cmd.Parameters.Add("PrimarySmtpAddress", email);
+ ExecuteShellCommand(runSpace, cmd, out errors);
+
+ if (errors.Length == 0)
+ success = true;
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ }
+
+ if (success)
+ break;
+
+ if (attempts > 9)
+ {
+ string error = string.Format("Mail public folder '{0}' was not found or not generated yet.", id);
+ throw new Exception(error);
+ }
+
+ attempts++;
+ ExchangeLog.LogWarning("Attemp {0} to update mail public folder {1}", attempts, folder);
+ System.Threading.Thread.Sleep(5000);
+ }
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("EnableMailPublicFolderInternal");
+ }
+
+ private void DisableMailPublicFolderInternal(string folder)
+ {
+ ExchangeLog.LogStart("DisableMailPublicFolderInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Disable-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ cmd.Parameters.Add("Confirm", false);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("DisableMailPublicFolderInternal");
+ }
+
+ private ExchangePublicFolder GetPublicFolderGeneralSettingsInternal(string folder)
+ {
+ ExchangeLog.LogStart("GetPublicFolderGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ ExchangePublicFolder info = new ExchangePublicFolder();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetPublicFolderObject(runSpace, folder);
+ PSObject publicFolder = result[0];
+
+ info.Name = (string)GetPSObjectProperty(publicFolder, "Name");
+ info.MailEnabled = (bool)GetPSObjectProperty(publicFolder, "MailEnabled");
+ info.HideFromAddressBook = (bool)GetPSObjectProperty(publicFolder, "HiddenFromAddressListsEnabled");
+ info.NETBIOS = GetNETBIOSDomainName();
+ info.Accounts = GetPublicFolderAccounts(runSpace, folder);
+
+ if (info.MailEnabled)
+ {
+ Command cmd = new Command("Get-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ result = ExecuteShellCommand(runSpace, cmd);
+ if (result.Count > 0)
+ {
+ publicFolder = result[0];
+ info.SAMAccountName = string.Format("{0}\\{1}", GetNETBIOSDomainName(), (string)GetPSObjectProperty(publicFolder, "Alias"));
+ }
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFolderGeneralSettingsInternal");
+ return info;
+ }
+
+ private ExchangeAccount[] GetPublicFolderAccounts(Runspace runSpace, string folder)
+ {
+ ExchangeLog.LogStart("GetPublicFolderAccounts");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ List list = new List();
+ ExchangeAccount account = null;
+
+ Command cmd = new Command("Get-PublicFolderClientPermission");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+
+ foreach (PSObject obj in result)
+ {
+ string userId = ObjToString(GetPSObjectProperty(obj, "User"));
+ if (userId == "Default" || userId == "Anonymous" || userId.StartsWith("NT User:") == true)
+ continue;
+
+ object rights = GetPSObjectProperty(obj, "AccessRights");
+ int count = (int)GetObjectPropertyValue(rights, "Count");
+ for (int i = 0; i < count; i++)
+ {
+ account = GetExchangeAccount(runSpace, userId);
+ string permission = ObjToString(GetObjectIndexerValue(rights, i));
+ if (account != null)
+ account.PublicFolderPermission = permission;
+ list.Add(account);
+ break;
+ }
+ }
+ ExchangeLog.LogEnd("GetPublicFolderAccounts");
+ return list.ToArray();
+ }
+
+ private void SetPublicFolderGeneralSettingsInternal(string folder, string newFolderName,
+ bool hideFromAddressBook, ExchangeAccount[] accounts)
+ {
+ ExchangeLog.LogStart("SetPublicFolderGeneralSettingsInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ ExchangePublicFolder info = new ExchangePublicFolder();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+ Collection result = GetPublicFolderObject(runSpace, folder);
+ PSObject publicFolder = result[0];
+ string folderName = (string)GetPSObjectProperty(publicFolder, "Name");
+ ExchangeAccount[] allAccounts = GetPublicFolderAccounts(runSpace, folder);
+
+ //Remove all accounts and re-apply
+ List accountsToDelete = new List();
+ List accountsToAdd = new List();
+
+ foreach (ExchangeAccount existingAccount in allAccounts)
+ {
+ try
+ {
+ RemovePublicFolderClientPermission(runSpace,
+ folder,
+ existingAccount.AccountName.Contains("@") ? existingAccount.AccountName : @"\" + existingAccount.AccountName,
+ existingAccount.PublicFolderPermission);
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+
+ }
+
+ foreach (ExchangeAccount newAccount in accounts)
+ {
+ try
+ {
+ AddPublicFolderClientPermission(runSpace,
+ folder,
+ newAccount.AccountName.Contains("@") ? newAccount.AccountName : @"\" + newAccount.AccountName,
+ newAccount.PublicFolderPermission);
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+
+ }
+
+ //general settings
+ Command cmd = new Command("Set-PublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ if (!folderName.Equals(newFolderName, StringComparison.OrdinalIgnoreCase))
+ {
+ cmd.Parameters.Add("Name", newFolderName);
+ }
+ cmd.Parameters.Add("HiddenFromAddressListsEnabled", hideFromAddressBook);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetPublicFolderGeneralSettingsInternal");
+ }
+
+ private ExchangePublicFolder GetPublicFolderMailFlowSettingsInternal(string folder)
+ {
+ ExchangeLog.LogStart("GetPublicFolderMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ ExchangePublicFolder info = new ExchangePublicFolder();
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject publicFolder = result[0];
+
+ info.AcceptAccounts = GetAcceptedAccounts(runSpace, publicFolder);
+ info.RejectAccounts = GetRejectedAccounts(runSpace, publicFolder);
+ info.RequireSenderAuthentication = (bool)GetPSObjectProperty(publicFolder, "RequireSenderAuthenticationEnabled");
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFolderMailFlowSettingsInternal");
+ return info;
+ }
+
+ private void SetPublicFolderMailFlowSettingsInternal(string folder,
+ string[] acceptAccounts, string[] rejectAccounts, bool requireSenderAuthentication)
+ {
+ ExchangeLog.LogStart("SetPublicFolderMailFlowSettingsInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Set-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+
+ MultiValuedProperty ids = null;
+ MultiValuedProperty dlIds = null;
+
+ SetAccountIds(runSpace, acceptAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("AcceptMessagesOnlyFrom", ids);
+ cmd.Parameters.Add("AcceptMessagesOnlyFromDLMembers", dlIds);
+
+ SetAccountIds(runSpace, rejectAccounts, out ids, out dlIds);
+ cmd.Parameters.Add("RejectMessagesFrom", ids);
+ cmd.Parameters.Add("RejectMessagesFromDLMembers", dlIds);
+ cmd.Parameters.Add("RequireSenderAuthenticationEnabled", requireSenderAuthentication);
+
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetPublicFolderMailFlowSettingsInternal");
+
+ }
+
+
+ private ExchangeEmailAddress[] GetPublicFolderEmailAddressesInternal(string folder)
+ {
+ ExchangeLog.LogStart("GetPublicFolderEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ List list = new List();
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject publicFolder = result[0];
+
+ string primaryEmail = null;
+ string windowsEmail = null;
+
+ SmtpAddress smtpAddress = (SmtpAddress)GetPSObjectProperty(publicFolder, "PrimarySmtpAddress");
+ if (smtpAddress != null)
+ primaryEmail = smtpAddress.ToString();
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(publicFolder, "WindowsEmailAddress");
+ //if (winAddress != null)
+ // windowsEmail = winAddress.ToString();
+ windowsEmail = ObjToString(GetPSObjectProperty(publicFolder, "CustomAttribute3"));
+
+
+ ProxyAddressCollection emails = (ProxyAddressCollection)GetPSObjectProperty(publicFolder, "EmailAddresses");
+ foreach (ProxyAddress email in emails)
+ {
+ //skip windows email
+ if (string.Equals(email.AddressString, windowsEmail, StringComparison.OrdinalIgnoreCase))
+ continue;
+
+ ExchangeEmailAddress item = new ExchangeEmailAddress();
+ item.Email = email.AddressString;
+ item.Primary = string.Equals(item.Email, primaryEmail, StringComparison.OrdinalIgnoreCase);
+ list.Add(item);
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFolderEmailAddressesInternal");
+ return list.ToArray();
+ }
+
+ private void SetPublicFolderEmailAddressesInternal(string folder, string[] emailAddresses)
+ {
+ ExchangeLog.LogStart("SetDistributionListEmailAddressesInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ Command cmd = new Command("Get-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ PSObject publicFolder = result[0];
+
+ //SmtpAddress winAddress = (SmtpAddress)GetPSObjectProperty(publicFolder, "WindowsEmailAddress");
+ string windowsEmail = ObjToString(GetPSObjectProperty(publicFolder, "CustomAttribute3"));
+ //string windowsEmail = ObjToString(winAddress);
+
+ ProxyAddressCollection emails = new ProxyAddressCollection();
+ ProxyAddress proxy = null;
+ if (emailAddresses != null)
+ {
+ foreach (string email in emailAddresses)
+ {
+ proxy = ProxyAddress.Parse(email);
+ emails.Add(proxy);
+ }
+ }
+ //add system windows email
+ if (!string.IsNullOrEmpty(windowsEmail))
+ {
+ emails.Add(ProxyAddress.Parse(windowsEmail));
+ }
+
+ cmd = new Command("Set-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ cmd.Parameters.Add("EmailAddresses", emails);
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetPublicFolderEmailAddressesInternal");
+ }
+
+ private void SetPublicFolderPrimaryEmailAddressInternal(string folder, string emailAddress)
+ {
+ ExchangeLog.LogStart("SetPublicFolderPrimaryEmailAddressInternal");
+ ExchangeLog.DebugInfo("Folder: {0}", folder);
+ ExchangeLog.DebugInfo("Email: {0}", emailAddress);
+
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+
+
+ SmtpAddress primaryEmail = new SmtpAddress(emailAddress);
+ Command cmd = new Command("Set-MailPublicFolder");
+ cmd.Parameters.Add("Identity", folder);
+ cmd.Parameters.Add("PrimarySmtpAddress", primaryEmail);
+
+ ExecuteShellCommand(runSpace, cmd);
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("SetPublicFolderPrimaryEmailAddressInternal");
+ }
+
+ private ExchangeItemStatistics[] GetPublicFoldersStatisticsInternal(string[] folders)
+ {
+ ExchangeLog.LogStart("GetPublicFoldersStatisticsInternal");
+
+ Runspace runSpace = null;
+ List ret = new List();
+ try
+ {
+ runSpace = OpenRunspace();
+
+ PSObject obj = null;
+ foreach (string folder in folders)
+ {
+ Command cmd = new Command("Get-PublicFolderStatistics");
+ cmd.Parameters.Add("Identity", folder);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null && result.Count > 0)
+ {
+ obj = result[0];
+ ExchangeItemStatistics info = new ExchangeItemStatistics();
+ info.ItemName = (string)GetPSObjectProperty(obj, "FolderPath");
+ Unlimited totalItemSize =
+ (Unlimited)GetPSObjectProperty(obj, "TotalItemSize");
+ info.TotalSizeMB = ConvertUnlimitedToMB(totalItemSize);
+ uint? itemCount = (uint?)GetPSObjectProperty(obj, "ItemCount");
+ info.TotalItems = ConvertNullableToInt32(itemCount);
+
+ DateTime? lastAccessTime = (DateTime?)GetPSObjectProperty(obj, "LastAccessTime"); ;
+ DateTime? lastModificationTime = (DateTime?)GetPSObjectProperty(obj, "LastModificationTime"); ;
+ info.LastAccessTime = ConvertNullableToDateTime(lastAccessTime);
+ info.LastModificationTime = ConvertNullableToDateTime(lastModificationTime);
+ ret.Add(info);
+ }
+ }
+ }
+ finally
+ {
+
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFoldersStatisticsInternal");
+ return ret.ToArray();
+ }
+
+ private string[] GetPublicFoldersRecursiveInternal(string parent)
+ {
+ ExchangeLog.LogStart("GetPublicFoldersRecursiveInternal");
+
+ Runspace runSpace = null;
+ List ret = new List();
+ try
+ {
+ runSpace = OpenRunspace();
+ Command cmd = new Command("Get-PublicFolder");
+ cmd.Parameters.Add("Identity", parent);
+ cmd.Parameters.Add("Recurse", true);
+ if (!string.IsNullOrEmpty(PublicFolderServer))
+ cmd.Parameters.Add("Server", PublicFolderServer);
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ if (result != null)
+ {
+ foreach (PSObject obj in result)
+ {
+ ret.Add(GetPSObjectIdentity(obj));
+ }
+ }
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFoldersRecursiveInternal");
+ return ret.ToArray();
+ }
+
+ private long GetPublicFolderSizeInternal(string folder)
+ {
+ ExchangeLog.LogStart("GetPublicFolderSizeInternal");
+ long size = 0;
+ Runspace runSpace = null;
+ try
+ {
+ runSpace = OpenRunspace();
+ size += CalculatePublicFolderDiskSpace(runSpace, folder);
+ }
+ finally
+ {
+ CloseRunspace(runSpace);
+ }
+ ExchangeLog.LogEnd("GetPublicFolderSizeInternal");
+ return size;
+ }
+
+ #endregion
+
+ #region Address Lists (GAL, AL, RAL, OAB, ABP)
+
+ private string GetAddressListDN(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("GetAddressListDN");
+ string resultObjectDN = null;
+ Command cmd = new Command("Get-AddressList");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = this.ExecuteShellCommand(runSpace, cmd);
+ if ((result != null) && (result.Count > 0))
+ {
+ resultObjectDN = this.GetResultObjectDN(result);
+ ExchangeLog.DebugInfo("AL DN: {0}", new object[] { resultObjectDN });
+ }
+ ExchangeLog.LogEnd("GetAddressListDN");
+ return resultObjectDN;
+ }
+
+ internal string CreateAddressList(Runspace runSpace, string organizationId)
+ {
+ ExchangeLog.LogStart("CreateAddressList");
+ string addressListName = this.GetAddressListName(organizationId);
+ string addressListDN = this.GetAddressListDN(runSpace, addressListName);
+ if (!string.IsNullOrEmpty(addressListDN))
+ {
+ //address list already exists - we will use it
+ ExchangeLog.LogWarning("Address List '{0}' already exists", new object[] { addressListName });
+ }
+ else
+ {
+ //try to create a new address list (10 attempts)
+ int attempts = 0;
+ Command cmd = null;
+ Collection result = null;
+
+ while (true)
+ {
+ try
+ {
+ //try to create address list
+ cmd = new Command("New-AddressList");
+ cmd.Parameters.Add("Name", addressListName);
+ cmd.Parameters.Add("IncludedRecipients", "AllRecipients");
+ cmd.Parameters.Add("ConditionalCustomAttribute1", organizationId);
+
+ result = ExecuteShellCommand(runSpace, cmd);
+ addressListDN = CheckResultObjectDN(result);
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ }
+ if (addressListDN != null)
+ break;
+
+ if (attempts > 9)
+ throw new Exception(
+ string.Format("Could not create Address List '{0}' ", addressListName));
+
+ attempts++;
+ ExchangeLog.LogWarning("Attempt #{0} to create address list failed!", attempts);
+ // wait 1 sec
+ System.Threading.Thread.Sleep(1000);
+ }
+ }
+
+ ExchangeLog.LogEnd("CreateAddressList");
+ return addressListDN;
+ }
+
+ internal string CreateRoomsAddressList(Runspace runSpace, string organizationId)
+ {
+ ExchangeLog.LogStart("CreateRoomList");
+ string addressListName = this.GetRoomsAddressListName(organizationId);
+ string addressListDN = this.GetAddressListDN(runSpace, addressListName);
+ if (!string.IsNullOrEmpty(addressListDN))
+ {
+ //address list already exists - we will use it
+ ExchangeLog.LogWarning("Room List '{0}' already exists", new object[] { addressListName });
+ }
+ else
+ {
+ //try to create a new address list (10 attempts)
+ int attempts = 0;
+ Command cmd = null;
+ Collection result = null;
+
+ while (true)
+ {
+ try
+ {
+ //try to create address list
+ cmd = new Command("New-AddressList");
+ cmd.Parameters.Add("Name", addressListName);
+ cmd.Parameters.Add("IncludedRecipients", "Resources");
+ cmd.Parameters.Add("ConditionalCustomAttribute1", organizationId);
+
+ result = ExecuteShellCommand(runSpace, cmd);
+ addressListDN = CheckResultObjectDN(result);
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogError(ex);
+ }
+ if (addressListDN != null)
+ break;
+
+ if (attempts > 9)
+ throw new Exception(
+ string.Format("Could not create Room List '{0}' ", addressListName));
+
+ attempts++;
+ ExchangeLog.LogWarning("Attempt #{0} to create room list failed!", attempts);
+ // wait 1 sec
+ System.Threading.Thread.Sleep(1000);
+ }
+ }
+
+ ExchangeLog.LogEnd("CreateRoomList");
+ return addressListDN;
+ }
+
+
+ internal void UpdateAddressList(Runspace runSpace, string id, string securityGroup)
+ {
+ ExchangeLog.LogStart("UpdateAddressList");
+
+ string path = AddADPrefix(id);
+ Command cmd = new Command("Update-AddressList");
+ cmd.Parameters.Add("Identity", id);
+ ExecuteShellCommand(runSpace, cmd);
+
+ AdjustADSecurity(path, securityGroup, false);
+
+ ExchangeLog.LogEnd("UpdateAddressList");
+ }
+
+ internal void DeleteAddressList(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DeleteAddressList");
+ Command cmd = new Command("Remove-AddressList");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DeleteAddressList");
+ }
+
+
+ internal virtual void DeleteAddressBookPolicy(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DeleteAddressBookPolicy");
+ //if (id != "IsConsumer")
+ //{
+ Command cmd = new Command("Remove-AddressBookPolicy");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ //}
+ ExchangeLog.LogEnd("DeleteAddressBookPolicy");
+ }
+
+
+
+ internal string GetGlobalAddressListDN(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("GetGlobalAddressListDN");
+ string resultObjectDN = null;
+ Command cmd = new Command("Get-GlobalAddressList");
+ cmd.Parameters.Add("Identity", id);
+ Collection result = this.ExecuteShellCommand(runSpace, cmd);
+ if ((result != null) && (result.Count > 0))
+ {
+ resultObjectDN = this.GetResultObjectDN(result);
+ ExchangeLog.DebugInfo("GAL DN: {0}", new object[] { resultObjectDN });
+ }
+ ExchangeLog.LogEnd("GetGlobalAddressListDN");
+ return resultObjectDN;
+ }
+
+
+ internal string CreateGlobalAddressList(Runspace runSpace, string organizationId)
+ {
+ ExchangeLog.LogStart("CreateGlobalAddressList");
+
+ string name = GetGlobalAddressListName(organizationId);
+
+ Command cmd = new Command("New-GlobalAddressList");
+ cmd.Parameters.Add("Name", name);
+ cmd.Parameters.Add("RecipientFilter", string.Format("(Alias -ne $null -and CustomAttribute1 -eq '{0}')", organizationId));
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectDN(result);
+
+ ExchangeLog.LogEnd("CreateGlobalAddressList");
+ return id;
+ }
+
+ internal void UpdateGlobalAddressList(Runspace runSpace, string id, string securityGroup)
+ {
+ ExchangeLog.LogStart("UpdateGlobalAddressList");
+
+
+ Command cmd = new Command("Update-GlobalAddressList");
+ cmd.Parameters.Add("Identity", id);
+ ExecuteShellCommand(runSpace, cmd);
+
+ string path = AddADPrefix(id);
+ AdjustADSecurity(path, securityGroup, false);
+
+ ExchangeLog.LogEnd("UpdateGlobalAddressList");
+ }
+
+ internal void DeleteGlobalAddressList(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DeleteGlobalAddressList");
+ Command cmd = new Command("Remove-GlobalAddressList");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DeleteGlobalAddressList");
+ }
+
+ private string CreateOfflineAddressBook(Runspace runSpace, string organizationId, string server, string oabVirtualDirs)
+ {
+ ExchangeLog.LogStart("CreateOfflineAddressBook");
+
+ string oabName = GetOfflineAddressBookName(organizationId);
+ string addressListName = GetAddressListName(organizationId);
+
+ Command cmd = new Command("New-OfflineAddressBook");
+ cmd.Parameters.Add("Name", oabName);
+ cmd.Parameters.Add("AddressLists", addressListName);
+ cmd.Parameters.Add("PublicFolderDistributionEnabled", PublicFolderDistributionEnabled);
+ cmd.Parameters.Add("IsDefault", false);
+ cmd.Parameters.Add("GlobalWebDistributionEnabled", false);
+
+
+ //TODO: fix web distribution
+ if (!string.IsNullOrEmpty(oabVirtualDirs))
+ {
+ ArrayList virtualDirs = new ArrayList();
+ string[] strTmp = oabVirtualDirs.Split(',');
+ foreach (string s in strTmp)
+ {
+ virtualDirs.Add(s);
+ }
+
+ cmd.Parameters.Add("VirtualDirectories", (String[])virtualDirs.ToArray(typeof(string)));
+ }
+
+ Collection result = ExecuteShellCommand(runSpace, cmd);
+ string id = GetResultObjectDN(result);
+
+ ExchangeLog.LogEnd("CreateOfflineAddressBook");
+
+ return id;
+ }
+
+ private void UpdateOfflineAddressBook(Runspace runSpace, string id, string securityGroup)
+ {
+ ExchangeLog.LogStart("UpdateOfflineAddressBook");
+
+ string path = AddADPrefix(id);
+
+ Command cmd = new Command("Update-OfflineAddressBook");
+ cmd.Parameters.Add("Identity", id);
+ ExecuteShellCommand(runSpace, cmd);
+
+ AdjustADSecurity(path, securityGroup, true);
+
+ ExchangeLog.LogEnd("UpdateOfflineAddressBook");
+ }
+
+
+ internal void DeleteOfflineAddressBook(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DeleteOfflineAddressBook");
+ Command cmd = new Command("Remove-OfflineAddressBook");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DeleteOfflineAddressBook");
+ }
+
+ private void DeleteAddressPolicy(Runspace runSpace, string id)
+ {
+ ExchangeLog.LogStart("DeleteAddressPolicy");
+ Command cmd = new Command("Remove-AddressBookPolicy");
+ cmd.Parameters.Add("Identity", id);
+ cmd.Parameters.Add("Confirm", false);
+ ExecuteShellCommand(runSpace, cmd);
+ ExchangeLog.LogEnd("DeleteAddressPolicy");
+ }
+
+ private string GetAddressListName(string orgName)
+ {
+ return orgName + " Address List";
+ }
+
+ internal string GetGlobalAddressListName(string orgName)
+ {
+ return orgName + " Global Address List";
+ }
+
+ private string GetOfflineAddressBookName(string orgName)
+ {
+ return orgName + " Offline Address Book";
+ }
+
+ internal string GetAddressBookPolicyName(string orgName)
+ {
+ return orgName + " Address Policy";
+ }
+
+ private string GetRoomsAddressListName(string orgName)
+ {
+ return orgName + " Rooms";
+ }
+
+ #endregion
+
+ #region Active Directory
+ private string CreateOrganizationalUnit(string name)
+ {
+ ExchangeLog.LogStart("CreateOrganizationalUnit");
+
+ string ret = null;
+ DirectoryEntry ou = null;
+ DirectoryEntry rootOU = null;
+ try
+ {
+ rootOU = GetRootOU();
+ ou = rootOU.Children.Add(
+ string.Format("OU={0}", name),
+ rootOU.SchemaClassName);
+
+ ret = ou.Path;
+ ou.CommitChanges();
+ }
+ finally
+ {
+ if (ou != null)
+ ou.Close();
+ if (rootOU != null)
+ rootOU.Close();
+ }
+
+ ExchangeLog.LogEnd("CreateOrganizationalUnit");
+ return ret;
+ }
+
+ private void DeleteADObject(string id)
+ {
+ ExchangeLog.LogStart("DeleteADObject");
+
+ string path = AddADPrefix(id);
+
+ DirectoryEntry ou = GetADObject(path);
+ DirectoryEntry parent = ou.Parent;
+ if (parent != null)
+ {
+ parent.Children.Remove(ou);
+ parent.CommitChanges();
+ }
+
+ ExchangeLog.LogEnd("DeleteADObject");
+ }
+
+ private DirectoryEntry GetRootOU()
+ {
+ ExchangeLog.LogStart("GetRootOU");
+ StringBuilder sb = new StringBuilder();
+ // append provider
+ AppendProtocol(sb);
+ AppendDomainController(sb);
+ AppendOUPath(sb, RootOU);
+ AppendDomainPath(sb, RootDomain);
+
+ DirectoryEntry de = GetADObject(sb.ToString());
+ ExchangeLog.LogEnd("GetRootOU");
+ return de;
+ }
+
+ private void SetADObjectProperty(DirectoryEntry oDE, string name, string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ if (oDE.Properties.Contains(name))
+ {
+ oDE.Properties[name][0] = value;
+ }
+ else
+ {
+ oDE.Properties[name].Add(value);
+ }
+ }
+ }
+
+ internal void SetADObjectPropertyValue(DirectoryEntry oDE, string name, string value)
+ {
+ PropertyValueCollection collection = oDE.Properties[name];
+ collection.Value = value;
+ }
+
+
+ internal void AddADObjectProperty(DirectoryEntry oDE, string name, string value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ oDE.Properties[name].Add(value);
+
+ }
+ }
+
+ internal DirectoryEntry GetADObject(string path)
+ {
+ DirectoryEntry de = null;
+ if (path.StartsWith("LDAP://" + PrimaryDomainController + "/", true, CultureInfo.InvariantCulture))
+ {
+ ExchangeLog.LogInfo("Get Active Directory Object {0} from {1}", path, PrimaryDomainController);
+ de = new DirectoryEntry(path, null, null, AuthenticationTypes.ServerBind);
+ }
+ else
+ {
+ ExchangeLog.LogInfo("Get Active Directory Object {0}", path);
+ de = new DirectoryEntry(path);
+ }
+ if (de != null)
+ de.RefreshCache();
+ return de;
+ }
+
+ internal object GetADObjectProperty(DirectoryEntry entry, string name)
+ {
+ if (entry.Properties.Contains(name))
+ return entry.Properties[name][0];
+ else
+ return String.Empty;
+ }
+
+
+ private string GetOrganizationPath(string organizationId)
+ {
+ StringBuilder sb = new StringBuilder();
+ // append provider
+ AppendOUPath(sb, organizationId);
+ AppendOUPath(sb, RootOU);
+ AppendDomainPath(sb, RootDomain);
+
+ return sb.ToString();
+ }
+
+ private void AppendProtocol(StringBuilder sb)
+ {
+ sb.Append("LDAP://");
+ }
+
+ private void AppendDomainController(StringBuilder sb)
+ {
+ sb.Append(PrimaryDomainController + "/");
+ }
+
+ private void AppendOUPath(StringBuilder sb, string ou)
+ {
+ if (string.IsNullOrEmpty(ou))
+ return;
+
+ string path = ou.Replace("/", "\\");
+ string[] parts = path.Split('\\');
+ for (int i = parts.Length - 1; i != -1; i--)
+ sb.Append("OU=").Append(parts[i]).Append(",");
+ }
+
+ private void AppendDomainPath(StringBuilder sb, string domain)
+ {
+ if (string.IsNullOrEmpty(domain))
+ return;
+
+ string[] parts = domain.Split('.');
+ for (int i = 0; i < parts.Length; i++)
+ {
+ sb.Append("DC=").Append(parts[i]);
+
+ if (i < (parts.Length - 1))
+ sb.Append(",");
+ }
+ }
+
+ internal string AddADPrefix(string path)
+ {
+ string dn = path;
+ if (!dn.ToUpper().StartsWith("LDAP://"))
+ {
+ dn = string.Format("LDAP://{0}/{1}", PrimaryDomainController, dn);
+ }
+ return dn;
+ }
+
+ private string RemoveADPrefix(string path)
+ {
+ string dn = path;
+ if (dn.ToUpper().StartsWith("LDAP://"))
+ {
+ dn = dn.Substring(7);
+ }
+ int index = dn.IndexOf("/");
+
+ if (index != -1)
+ {
+ dn = dn.Substring(index + 1);
+ }
+ return dn;
+ }
+
+ internal string ConvertADPathToCanonicalName(string name)
+ {
+
+ if (string.IsNullOrEmpty(name))
+ return null;
+
+ StringBuilder ret = new StringBuilder();
+ List cn = new List();
+ List dc = new List();
+
+ name = RemoveADPrefix(name);
+
+ string[] parts = name.Split(',');
+ for (int i = 0; i < parts.Length; i++)
+ {
+ if (parts[i].StartsWith("DC="))
+ {
+ dc.Add(parts[i].Substring(3));
+ }
+ else if (parts[i].StartsWith("OU=") || parts[i].StartsWith("CN="))
+ {
+ cn.Add(parts[i].Substring(3));
+ }
+ }
+
+ for (int i = 0; i < dc.Count; i++)
+ {
+ ret.Append(dc[i]);
+ if (i < dc.Count - 1)
+ ret.Append(".");
+ }
+ for (int i = cn.Count - 1; i != -1; i--)
+ {
+ ret.Append("/");
+ ret.Append(cn[i]);
+ }
+ return ret.ToString();
+ }
+
+ private string ConvertDomainName(string name)
+ {
+
+ if (string.IsNullOrEmpty(name))
+ return null;
+
+ StringBuilder ret = new StringBuilder("LDAP://");
+
+ string[] parts = name.Split('.');
+ for (int i = 0; i < parts.Length; i++)
+ {
+ ret.Append("DC=");
+ ret.Append(parts[i]);
+ if (i < parts.Length - 1)
+ ret.Append(",");
+ }
+ return ret.ToString();
+ }
+
+
+ internal virtual void AdjustADSecurity(string objPath, string securityGroupPath, bool isAddressBook)
+ {
+ ExchangeLog.LogStart("AdjustADSecurity");
+ ExchangeLog.DebugInfo(" Active Direcory object: {0}", objPath);
+ ExchangeLog.DebugInfo(" Security Group: {0}", securityGroupPath);
+
+ if (isAddressBook)
+ {
+ ExchangeLog.DebugInfo(" Updating Security");
+ //"Download Address Book" security permission for offline address book
+ Guid openAddressBookGuid = new Guid("{bd919c7c-2d79-4950-bc9c-e16fd99285e8}");
+
+ DirectoryEntry groupEntry = GetADObject(securityGroupPath);
+ byte[] byteSid = (byte[])GetADObjectProperty(groupEntry, "objectSid");
+
+ DirectoryEntry objEntry = GetADObject(objPath);
+ ActiveDirectorySecurity security = objEntry.ObjectSecurity;
+
+ // Create a SecurityIdentifier object for security group.
+ SecurityIdentifier groupSid = new SecurityIdentifier(byteSid, 0);
+
+ // Create an access rule to allow users in Security Group to open address book.
+ ActiveDirectoryAccessRule allowOpenAddressBook =
+ new ActiveDirectoryAccessRule(
+ groupSid,
+ ActiveDirectoryRights.ExtendedRight,
+ AccessControlType.Allow,
+ openAddressBookGuid);
+
+ // Create an access rule to allow users in Security Group to read object.
+ ActiveDirectoryAccessRule allowRead =
+ new ActiveDirectoryAccessRule(
+ groupSid,
+ ActiveDirectoryRights.GenericRead,
+ AccessControlType.Allow);
+
+ // Remove existing rules if exist
+ security.RemoveAccessRuleSpecific(allowOpenAddressBook);
+ security.RemoveAccessRuleSpecific(allowRead);
+
+ // Add a new access rule to allow users in Security Group to open address book.
+ security.AddAccessRule(allowOpenAddressBook);
+ // Add a new access rule to allow users in Security Group to read object.
+ security.AddAccessRule(allowRead);
+
+ // Commit the changes.
+ objEntry.CommitChanges();
+ }
+
+ ExchangeLog.LogEnd("AdjustADSecurity");
+ }
+
+ private void AddUPNSuffix(string ouPath, string suffix)
+ {
+ ExchangeLog.LogStart("AddUPNSuffix");
+ //Add UPN Suffix to the OU
+ DirectoryEntry ou = GetADObject(ouPath);
+ AddADObjectProperty(ou, "uPNSuffixes", suffix);
+ ou.CommitChanges();
+ ou.Close();
+ ExchangeLog.LogEnd("AddUPNSuffix");
+ }
+
+ private void RemoveUPNSuffix(string ouPath, string suffix)
+ {
+ ExchangeLog.LogStart("RemoveUPNSuffix");
+
+ if (DirectoryEntry.Exists(ouPath))
+ {
+ DirectoryEntry ou = GetADObject(ouPath);
+ PropertyValueCollection prop = null;
+ try
+ {
+ prop = ou.Properties["uPNSuffixes"];
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.LogWarning("AD object or property not found: {0}", ex);
+ }
+
+ if (prop != null)
+ {
+ if (ou.Properties["uPNSuffixes"].Contains(suffix))
+ {
+ ou.Properties["uPNSuffixes"].Remove(suffix);
+ ou.CommitChanges();
+ }
+ ou.Close();
+ }
+ }
+ ExchangeLog.LogEnd("RemoveUPNSuffix");
+ }
+
+ /*private void AddGlobalUPNSuffix(string name)
+ {
+ ExchangeLog.LogStart("AddGlobalUPNSuffix");
+ string path = string.Format("LDAP://{0}/RootDSE", RootDomain);
+ DirectoryEntry rootDSE = GetADObject(path);
+ string contextPath = GetADObjectProperty(rootDSE, "ConfigurationNamingContext").ToString();
+ DirectoryEntry partitions = GetADObject("LDAP://cn=Partitions," + contextPath);
+ partitions.Properties["uPNSuffixes"].Add(name);
+ partitions.CommitChanges();
+ partitions.Close();
+ rootDSE.Close();
+ ExchangeLog.LogEnd("AddGlobalUPNSuffix");
+ }*/
+
+ internal string GetNETBIOSDomainName()
+ {
+ ExchangeLog.LogStart("GetNETBIOSDomainName");
+ string ret = string.Empty;
+
+ string path = string.Format("LDAP://{0}/RootDSE", RootDomain);
+ DirectoryEntry rootDSE = GetADObject(path);
+ string contextPath = GetADObjectProperty(rootDSE, "ConfigurationNamingContext").ToString();
+ string defaultContext = GetADObjectProperty(rootDSE, "defaultNamingContext").ToString();
+ DirectoryEntry partitions = GetADObject("LDAP://cn=Partitions," + contextPath);
+
+ DirectorySearcher searcher = new DirectorySearcher();
+ searcher.SearchRoot = partitions;
+ searcher.Filter = string.Format("(&(objectCategory=crossRef)(nCName={0}))", defaultContext);
+ searcher.SearchScope = SearchScope.OneLevel;
+
+ //find the first instance
+ SearchResult result = searcher.FindOne();
+ if (result != null)
+ {
+ DirectoryEntry partition = GetADObject(result.Path);
+ ret = GetADObjectProperty(partition, "nETBIOSName").ToString();
+ partition.Close();
+ }
+ partitions.Close();
+ rootDSE.Close();
+ ExchangeLog.LogEnd("GetNETBIOSDomainName");
+ return ret;
+ }
+
+ /*private void RemoveGlobalUPNSuffix(string name)
+ {
+ ExchangeLog.LogStart("RemoveGlobalUPNSuffix");
+ string path = string.Format("LDAP://{0}/RootDSE", RootDomain);
+ DirectoryEntry rootDSE = GetADObject(path);
+ string contextPath = GetADObjectProperty(rootDSE, "ConfigurationNamingContext").ToString();
+ DirectoryEntry partitions = GetADObject("LDAP://cn=Partitions," + contextPath);
+ if (partitions.Properties["uPNSuffixes"].Contains(name))
+ {
+ partitions.Properties["uPNSuffixes"].Remove(name);
+ partitions.CommitChanges();
+ }
+ partitions.Close();
+ rootDSE.Close();
+ ExchangeLog.LogEnd("RemoveGlobalUPNSuffix");
+ }*/
+
+
+ #endregion
+
+ #region PowerShell integration
+ /*private Collection ExecuteShellCommand2(Runspace runSpace, string cmd)
+ {
+ ExchangeLog.LogStart("ExecuteShellCommand");
+ RunspaceInvoke invoker = new RunspaceInvoke(runSpace);
+ System.Collections.IList errors = null;
+ Collection results = invoker.Invoke(cmd, null, out errors);
+ if (errors != null && errors.Count > 0)
+ {
+ foreach (PSObject err in errors)
+ {
+ string errorMessage = string.Format("Invoke error: {0}", err.ToString());
+ ExchangeLog.LogError(errorMessage, null);
+ }
+ }
+ invoker = null;
+ ExchangeLog.LogEnd("ExecuteShellCommand");
+ return results;
+ }*/
+
+ private static RunspaceConfiguration runspaceConfiguration = null;
+ private static string ExchangePath = null;
+
+ internal static string GetExchangePath()
+ {
+ if (string.IsNullOrEmpty(ExchangePath))
+ {
+ RegistryKey root = Registry.LocalMachine;
+ RegistryKey rk = root.OpenSubKey(ExchangeRegistryPath);
+ if (rk != null)
+ {
+ string value = (string)rk.GetValue("MsiInstallPath", null);
+ rk.Close();
+ if (!string.IsNullOrEmpty(value))
+ ExchangePath = Path.Combine(value, "bin");
+ }
+ }
+ return ExchangePath;
+ }
+
+ internal static Assembly ResolveExchangeAssembly(object p, ResolveEventArgs args)
+ {
+ //Add path for the Exchange 2007 DLLs
+ if (args.Name.Contains("Microsoft.Exchange"))
+ {
+ string exchangePath = GetExchangePath();
+ if (string.IsNullOrEmpty(exchangePath))
+ return null;
+
+ string path = Path.Combine(exchangePath, args.Name.Split(',')[0] + ".dll");
+ if (!File.Exists(path))
+ return null;
+
+ ExchangeLog.DebugInfo("Resolved assembly: {0}", path);
+
+ return Assembly.LoadFrom(path);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ internal virtual Runspace OpenRunspace()
+ {
+ ExchangeLog.LogStart("OpenRunspace");
+
+ if (runspaceConfiguration == null)
+ {
+ runspaceConfiguration = RunspaceConfiguration.Create();
+ PSSnapInException exception = null;
+
+ PSSnapInInfo info = runspaceConfiguration.AddPSSnapIn(ExchangeSnapInName, out exception);
+
+ if (exception != null)
+ {
+ ExchangeLog.LogWarning("SnapIn error", exception);
+ }
+ }
+ Runspace runSpace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
+ //
+ runSpace.Open();
+ //
+ runSpace.SessionStateProxy.SetVariable("ConfirmPreference", "none");
+ ExchangeLog.LogEnd("OpenRunspace");
+
+ Command cmd = new Command("Set-ADServerSettings");
+ cmd.Parameters.Add("PreferredServer", PrimaryDomainController);
+ ExecuteShellCommand(runSpace, cmd, false);
+ return runSpace;
+ }
+
+ internal void CloseRunspace(Runspace runspace)
+ {
+ try
+ {
+ if (runspace != null && runspace.RunspaceStateInfo.State == RunspaceState.Opened)
+ {
+ runspace.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ ExchangeLog.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)
+ {
+ ExchangeLog.LogStart("ExecuteShellCommand");
+ List