6905 lines
275 KiB
C#
6905 lines
275 KiB
C#
// 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
|
|
|
|
/// <summary>
|
|
/// Extend existing organization with exchange functionality
|
|
/// </summary>
|
|
/// <param name="organizationId"></param>
|
|
/// <param name="securityGroup"></param>
|
|
/// <returns></returns>
|
|
public Organization ExtendToExchangeOrganization(string organizationId, string securityGroup, bool IsConsumer)
|
|
{
|
|
return ExtendToExchangeOrganizationInternal(organizationId, securityGroup, IsConsumer);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates organization OAB on the Client Access Server
|
|
/// </summary>
|
|
/// <param name="organizationId"></param>
|
|
/// <param name="securityGroup"></param>
|
|
/// <returns></returns>
|
|
public Organization CreateOrganizationOfflineAddressBook(string organizationId, string securityGroup, string oabVirtualDir)
|
|
{
|
|
return CreateOrganizationOfflineAddressBookInternal(organizationId, securityGroup, oabVirtualDir);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates organization OAB
|
|
/// </summary>
|
|
/// <param name="oabId"></param>
|
|
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 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, bool enabledLitigationHold, long recoverabelItemsSpace, long recoverabelItemsWarning)
|
|
{
|
|
SetMailboxAdvancedSettingsInternal(organizationId, accountName, enablePOP, enableIMAP, enableOWA,
|
|
enableMAPI, enableActiveSync, issueWarningKB,
|
|
prohibitSendKB, prohibitSendReceiveKB, keepDeletedItemsDays, maxRecipients, maxSendMessageSizeKB, maxReceiveMessageSizeKB,
|
|
enabledLitigationHold, recoverabelItemsSpace, recoverabelItemsWarning);
|
|
}
|
|
|
|
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<PSObject> 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<ServiceProviderItemDiskSpace> itemsDiskspace = new List<ServiceProviderItemDiskSpace>();
|
|
|
|
// 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
|
|
|
|
/// <summary>
|
|
/// Creates organization on Mail Server
|
|
/// </summary>
|
|
/// <param name="organizationId"></param>
|
|
/// <returns></returns>
|
|
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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<ByteQuantifiedSize> issueWarningQuota = ConvertKBToUnlimited(issueWarningKB);
|
|
Unlimited<ByteQuantifiedSize> prohibitSendQuota = ConvertKBToUnlimited(prohibitSendKB);
|
|
Unlimited<ByteQuantifiedSize> prohibitSendReceiveQuota = ConvertKBToUnlimited(prohibitSendReceiveKB);
|
|
EnhancedTimeSpan retainDeletedItemsFor = ConvertDaysToEnhancedTimeSpan(keepDeletedItemsDays);
|
|
|
|
Command cmd = new Command("Get-Mailbox");
|
|
cmd.Parameters.Add("OrganizationalUnit", org);
|
|
Collection<PSObject> 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<ExchangeItemStatistics> ret = new List<ExchangeItemStatistics>();
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
|
|
string org = ConvertADPathToCanonicalName(organizationDistinguishedName);
|
|
|
|
Command cmd = new Command("Get-Mailbox");
|
|
cmd.Parameters.Add("OrganizationalUnit", org);
|
|
Collection<PSObject> 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<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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<PSObject> 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<PSObject> 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<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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<PSObject> 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<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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<PSObject> results = ExecuteShellCommand(runSpace, cmd);
|
|
List<ExchangeAccount> accounts = new List<ExchangeAccount>();
|
|
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<PSObject> results = ExecuteShellCommand(runSpace, cmd);
|
|
|
|
|
|
List<ExchangeAccount> accounts = new List<ExchangeAccount>();
|
|
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<string> temp = new List<string>(newAccounts);
|
|
|
|
Array.Sort(newAccounts);
|
|
foreach (ExchangeAccount exist in existingAccounts)
|
|
{
|
|
if (Array.BinarySearch<string>(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<string> temp = new List<string>(newAccounts);
|
|
|
|
Array.Sort<string>(newAccounts);
|
|
foreach (ExchangeAccount current in existingAccounts)
|
|
{
|
|
if (Array.BinarySearch<string>(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, bool enabledLitigationHold, long recoverabelItemsSpace, long recoverabelItemsWarning)
|
|
{
|
|
return CreateMailEnableUserInternal(upn, organizationId, organizationDistinguishedName, accountType,
|
|
mailboxDatabase, offlineAddressBook, addressBookPolicy,
|
|
accountName, enablePOP, enableIMAP,
|
|
enableOWA, enableMAPI, enableActiveSync,
|
|
issueWarningKB, prohibitSendKB, prohibitSendReceiveKB,
|
|
keepDeletedItemsDays, maxRecipients, maxSendMessageSizeKB, maxReceiveMessageSizeKB, hideFromAddressBook, IsConsumer, enabledLitigationHold, recoverabelItemsSpace, recoverabelItemsWarning);
|
|
}
|
|
|
|
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, bool enabledLitigationHold, long recoverabelItemsSpace, long recoverabelItemsWarning)
|
|
{
|
|
|
|
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<PSObject> 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);
|
|
|
|
if (enabledLitigationHold)
|
|
{
|
|
cmd.Parameters.Add("LitigationHoldEnabled", true);
|
|
cmd.Parameters.Add("RecoverableItemsQuota", ConvertKBToUnlimited(recoverabelItemsSpace));
|
|
cmd.Parameters.Add("RecoverableItemsWarningQuota", ConvertKBToUnlimited(recoverabelItemsWarning));
|
|
}
|
|
|
|
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<PSObject> 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<PSObject> 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<ADObjectId> servers = (ADMultiValuedProperty<ADObjectId>)GetPSObjectProperty(dags[0], "Servers");
|
|
|
|
if (servers != null)
|
|
{
|
|
System.Collections.Generic.List<string> lstDatabase = new System.Collections.Generic.List<string>();
|
|
|
|
foreach (object objServer in servers)
|
|
{
|
|
Collection<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<int>)GetPSObjectProperty(mailbox, "RecipientLimits"));
|
|
info.MaxSendMessageSizeKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "MaxSendSize"));
|
|
info.MaxReceiveMessageSizeKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)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<ADObjectId> ids = null;
|
|
MultiValuedProperty<ADObjectId> 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<PSObject> result = GetMailboxObject(runSpace, accountName);
|
|
PSObject mailbox = result[0];
|
|
|
|
info.IssueWarningKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "IssueWarningQuota"));
|
|
info.ProhibitSendKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "ProhibitSendQuota"));
|
|
info.ProhibitSendReceiveKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "ProhibitSendReceiveQuota"));
|
|
info.KeepDeletedItemsDays =
|
|
ConvertEnhancedTimeSpanToDays((EnhancedTimeSpan)GetPSObjectProperty(mailbox, "RetainDeletedItemsFor"));
|
|
|
|
info.EnableLitigationHold = (bool)GetPSObjectProperty(mailbox, "LitigationHoldEnabled");
|
|
|
|
info.RecoverabelItemsSpace =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "RecoverableItemsQuota"));
|
|
info.RecoverabelItemsWarning =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(mailbox, "RecoverableItemsWarningQuota"));
|
|
|
|
//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<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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, bool enabledLitigationHold, long recoverabelItemsSpace, long recoverabelItemsWarning)
|
|
{
|
|
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));
|
|
|
|
if (enabledLitigationHold)
|
|
{
|
|
cmd.Parameters.Add("LitigationHoldEnabled", true);
|
|
cmd.Parameters.Add("RecoverableItemsQuota", ConvertKBToUnlimited(recoverabelItemsSpace));
|
|
cmd.Parameters.Add("RecoverableItemsWarningQuota", ConvertKBToUnlimited(recoverabelItemsWarning));
|
|
}
|
|
|
|
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<ExchangeEmailAddress> list = new List<ExchangeEmailAddress>();
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
Collection<PSObject> 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<PSObject> 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<ExchangeAccount> list = new List<ExchangeAccount>();
|
|
|
|
IList<ADObjectId> ids =
|
|
(IList<ADObjectId>)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<ADObjectId> SetSendOnBehalfAccounts(Runspace runspace, string[] accounts)
|
|
{
|
|
if (accounts == null || accounts.Length == 0)
|
|
return MultiValuedProperty<ADObjectId>.Empty;
|
|
else
|
|
{
|
|
MultiValuedProperty<ADObjectId> ids = new MultiValuedProperty<ADObjectId>();
|
|
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<ExchangeAccount> list = new List<ExchangeAccount>();
|
|
ExchangeAccount account = null;
|
|
IList<ADObjectId> ids =
|
|
(IList<ADObjectId>)GetPSObjectProperty(mailbox, "AcceptMessagesOnlyFrom");
|
|
foreach (ADObjectId id in ids)
|
|
{
|
|
account = GetExchangeAccount(runSpace, id.ToString());
|
|
if (account != null)
|
|
list.Add(account);
|
|
}
|
|
ids = (IList<ADObjectId>)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<ADObjectId> ids, out MultiValuedProperty<ADObjectId> dlIds)
|
|
{
|
|
ids = MultiValuedProperty<ADObjectId>.Empty;
|
|
dlIds = MultiValuedProperty<ADObjectId>.Empty;
|
|
|
|
if (accounts == null || accounts.Length == 0)
|
|
return;
|
|
|
|
ids = new MultiValuedProperty<ADObjectId>();
|
|
dlIds = new MultiValuedProperty<ADObjectId>();
|
|
|
|
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<ADObjectId>.Empty;
|
|
if (dlIds.Count == 0)
|
|
dlIds = MultiValuedProperty<ADObjectId>.Empty;
|
|
}
|
|
|
|
|
|
private ExchangeAccount[] GetRejectedAccounts(Runspace runSpace, PSObject mailbox)
|
|
{
|
|
List<ExchangeAccount> list = new List<ExchangeAccount>();
|
|
ExchangeAccount account = null;
|
|
IList<ADObjectId> ids =
|
|
(IList<ADObjectId>)GetPSObjectProperty(mailbox, "RejectMessagesFrom");
|
|
foreach (ADObjectId id in ids)
|
|
{
|
|
account = GetExchangeAccount(runSpace, id.ToString());
|
|
if (account != null)
|
|
list.Add(account);
|
|
}
|
|
ids = (IList<ADObjectId>)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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<ByteQuantifiedSize>)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<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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<PSObject> GetMailboxObject(Runspace runSpace, string id)
|
|
{
|
|
Command cmd = new Command("Get-Mailbox");
|
|
cmd.Parameters.Add("Identity", id);
|
|
Collection<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<ADObjectId> ids = null;
|
|
MultiValuedProperty<ADObjectId> 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
|
|
/// <summary>
|
|
/// Creates Security Distribution Group
|
|
/// </summary>
|
|
/// <param name="runSpace"></param>
|
|
/// <param name="ouName"></param>
|
|
/// <param name="groupName"></param>
|
|
/// <returns>LDAP path</returns>
|
|
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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<ADObjectId> ids =
|
|
(MultiValuedProperty<ADObjectId>)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<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
PSObject group = result[0];
|
|
string manager = GetGroupManager(group);
|
|
|
|
//set members
|
|
ExchangeAccount[] accounts = GetGroupMembers(runSpace, accountName);
|
|
Dictionary<string, string> existingMembers = new Dictionary<string, string>();
|
|
Dictionary<string, string> newMembers = new Dictionary<string, string>();
|
|
List<string> membersToDelete = new List<string>();
|
|
List<string> membersToAdd = new List<string>();
|
|
|
|
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<PSObject> 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<PSObject> 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<PSObject> 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<ADObjectId> ids = null;
|
|
MultiValuedProperty<ADObjectId> 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<PSObject> 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<ExchangeAccount> list = new List<ExchangeAccount>();
|
|
Command cmd = new Command("Get-DistributionGroupMember");
|
|
cmd.Parameters.Add("Identity", groupId);
|
|
Collection<PSObject> 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<ExchangeEmailAddress> list = new List<ExchangeEmailAddress>();
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
|
|
Command cmd = new Command("Get-DistributionGroup");
|
|
cmd.Parameters.Add("Identity", accountName);
|
|
Collection<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
return result;
|
|
}
|
|
|
|
private bool PublicFolderExists(Runspace runSpace, string id)
|
|
{
|
|
ExchangeLog.LogStart("PublicFolderExists");
|
|
|
|
Collection<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<ExchangeAccount> list = new List<ExchangeAccount>();
|
|
ExchangeAccount account = null;
|
|
|
|
Command cmd = new Command("Get-PublicFolderClientPermission");
|
|
cmd.Parameters.Add("Identity", folder);
|
|
if (!string.IsNullOrEmpty(PublicFolderServer))
|
|
cmd.Parameters.Add("Server", PublicFolderServer);
|
|
Collection<PSObject> 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<PSObject> 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<ExchangeAccount> accountsToDelete = new List<ExchangeAccount>();
|
|
List<ExchangeAccount> accountsToAdd = new List<ExchangeAccount>();
|
|
|
|
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<PSObject> 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<ADObjectId> ids = null;
|
|
MultiValuedProperty<ADObjectId> 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<ExchangeEmailAddress> list = new List<ExchangeEmailAddress>();
|
|
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<PSObject> 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<PSObject> 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<ExchangeItemStatistics> ret = new List<ExchangeItemStatistics>();
|
|
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<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
if (result != null && result.Count > 0)
|
|
{
|
|
obj = result[0];
|
|
ExchangeItemStatistics info = new ExchangeItemStatistics();
|
|
info.ItemName = (string)GetPSObjectProperty(obj, "FolderPath");
|
|
Unlimited<ByteQuantifiedSize> totalItemSize =
|
|
(Unlimited<ByteQuantifiedSize>)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<string> ret = new List<string>();
|
|
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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<PSObject> 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<string> cn = new List<string>();
|
|
List<string> dc = new List<string>();
|
|
|
|
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<PSObject> ExecuteShellCommand2(Runspace runSpace, string cmd)
|
|
{
|
|
ExchangeLog.LogStart("ExecuteShellCommand");
|
|
RunspaceInvoke invoker = new RunspaceInvoke(runSpace);
|
|
System.Collections.IList errors = null;
|
|
Collection<PSObject> 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<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd)
|
|
{
|
|
return ExecuteShellCommand(runSpace, cmd, true);
|
|
}
|
|
|
|
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController)
|
|
{
|
|
object[] errors;
|
|
return ExecuteShellCommand(runSpace, cmd, useDomainController, out errors);
|
|
}
|
|
|
|
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, out object[] errors)
|
|
{
|
|
return ExecuteShellCommand(runSpace, cmd, true, out errors);
|
|
}
|
|
|
|
internal Collection<PSObject> ExecuteShellCommand(Runspace runSpace, Command cmd, bool useDomainController, out object[] errors)
|
|
{
|
|
ExchangeLog.LogStart("ExecuteShellCommand");
|
|
List<object> errorList = new List<object>();
|
|
|
|
if (useDomainController)
|
|
{
|
|
CommandParameter dc = new CommandParameter("DomainController", PrimaryDomainController);
|
|
if (!cmd.Parameters.Contains(dc))
|
|
{
|
|
cmd.Parameters.Add(dc);
|
|
}
|
|
}
|
|
|
|
ExchangeLog.DebugCommand(cmd);
|
|
Collection<PSObject> results = null;
|
|
// Create a pipeline
|
|
Pipeline pipeLine = runSpace.CreatePipeline();
|
|
using (pipeLine)
|
|
{
|
|
// Add the command
|
|
pipeLine.Commands.Add(cmd);
|
|
// Execute the pipeline and save the objects returned.
|
|
results = pipeLine.Invoke();
|
|
|
|
// Log out any errors in the pipeline execution
|
|
// NOTE: These errors are NOT thrown as exceptions!
|
|
// Be sure to check this to ensure that no errors
|
|
// happened while executing the command.
|
|
if (pipeLine.Error != null && pipeLine.Error.Count > 0)
|
|
{
|
|
foreach (object item in pipeLine.Error.ReadToEnd())
|
|
{
|
|
errorList.Add(item);
|
|
string errorMessage = string.Format("Invoke error: {0}", item);
|
|
ExchangeLog.LogWarning(errorMessage);
|
|
}
|
|
}
|
|
}
|
|
pipeLine = null;
|
|
errors = errorList.ToArray();
|
|
ExchangeLog.LogEnd("ExecuteShellCommand");
|
|
return results;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the distinguished name of the object from the shell execution result
|
|
/// </summary>
|
|
/// <param name="result"></param>
|
|
/// <returns></returns>
|
|
internal string GetResultObjectDN(Collection<PSObject> result)
|
|
{
|
|
ExchangeLog.LogStart("GetResultObjectDN");
|
|
if (result == null)
|
|
throw new ArgumentNullException("result", "Execution result is not specified");
|
|
|
|
if (result.Count < 1)
|
|
throw new ArgumentException("Execution result does not contain any object");
|
|
|
|
if (result.Count > 1)
|
|
throw new ArgumentException("Execution result contains more than one object");
|
|
|
|
PSMemberInfo info = result[0].Members["DistinguishedName"];
|
|
if (info == null)
|
|
throw new ArgumentException("Execution result does not contain DistinguishedName property", "result");
|
|
|
|
string ret = info.Value.ToString();
|
|
ExchangeLog.LogEnd("GetResultObjectDN");
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the object from the shell execution result.
|
|
/// </summary>
|
|
/// <param name="result"></param>
|
|
/// <returns>Distinguished name of the object if object exists or null otherwise.</returns>
|
|
internal string CheckResultObjectDN(Collection<PSObject> result)
|
|
{
|
|
ExchangeLog.LogStart("CheckResultObjectDN");
|
|
|
|
if (result == null)
|
|
return null;
|
|
|
|
if (result.Count < 1)
|
|
return null;
|
|
|
|
PSMemberInfo info = result[0].Members["DistinguishedName"];
|
|
if (info == null)
|
|
throw new ArgumentException("Execution result does not contain DistinguishedName property", "result");
|
|
|
|
string ret = info.Value.ToString();
|
|
ExchangeLog.LogEnd("CheckResultObjectDN");
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the identity of the object from the shell execution result
|
|
/// </summary>
|
|
/// <param name="result"></param>
|
|
/// <returns></returns>
|
|
internal string GetResultObjectIdentity(Collection<PSObject> result)
|
|
{
|
|
ExchangeLog.LogStart("GetResultObjectIdentity");
|
|
if (result == null)
|
|
throw new ArgumentNullException("result", "Execution result is not specified");
|
|
|
|
if (result.Count < 1)
|
|
throw new ArgumentException("Execution result is empty", "result");
|
|
|
|
if (result.Count > 1)
|
|
throw new ArgumentException("Execution result contains more than one object", "result");
|
|
|
|
PSMemberInfo info = result[0].Members["Identity"];
|
|
if (info == null)
|
|
throw new ArgumentException("Execution result does not contain Identity property", "result");
|
|
|
|
string ret = info.Value.ToString();
|
|
ExchangeLog.LogEnd("GetResultObjectIdentity");
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the identity of the PS object
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <returns></returns>
|
|
internal string GetPSObjectIdentity(PSObject obj)
|
|
{
|
|
ExchangeLog.LogStart("GetPSObjectIdentity");
|
|
if (obj == null)
|
|
throw new ArgumentNullException("obj", "PSObject is not specified");
|
|
|
|
|
|
PSMemberInfo info = obj.Members["Identity"];
|
|
if (info == null)
|
|
throw new ArgumentException("PSObject does not contain Identity property", "obj");
|
|
|
|
string ret = info.Value.ToString();
|
|
ExchangeLog.LogEnd("GetPSObjectIdentity");
|
|
return ret;
|
|
}
|
|
|
|
internal object GetPSObjectProperty(PSObject obj, string name)
|
|
{
|
|
return obj.Members[name].Value;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Storage
|
|
internal virtual string CreateStorageGroup(Runspace runSpace, string name, string server)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
internal virtual string CreateMailboxDatabase(Runspace runSpace, string name, string storageGroup)
|
|
{
|
|
ExchangeLog.LogStart("CreateMailboxDatabase");
|
|
string id;
|
|
if (name != "*")
|
|
{
|
|
Command cmd = new Command("Get-MailboxDatabase");
|
|
cmd.Parameters.Add("Identity", name);
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
if (result != null && result.Count > 0)
|
|
{
|
|
id = GetResultObjectIdentity(result);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception(string.Format("Mailbox database {0} not found", name));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
id = "*";
|
|
}
|
|
ExchangeLog.LogEnd("CreateMailboxDatabase");
|
|
return id;
|
|
}
|
|
#endregion
|
|
|
|
#region Domains
|
|
|
|
|
|
private string[] GetAuthoritativeDomainsInternal()
|
|
{
|
|
ExchangeLog.LogStart("GetAuthoritativeDomainsInternal");
|
|
|
|
Runspace runSpace = null;
|
|
List<string> domains = new List<string>();
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Get-AcceptedDomain");
|
|
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
foreach (PSObject current in result)
|
|
{
|
|
domains.Add(GetPSObjectProperty(current, "DomainName").ToString());
|
|
}
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("GetAuthoritativeDomainsInternal", ex);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
|
|
ExchangeLog.LogEnd("GetAuthoritativeDomainsInternal");
|
|
return domains.ToArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Creates Authoritative Domain on Hub Transport Server
|
|
/// </summary>
|
|
/// <param name="domain"></param>
|
|
/// <returns></returns>
|
|
private void CreateAuthoritativeDomainInternal(string domain)
|
|
{
|
|
ExchangeLog.LogStart("CreateAuthoritativeDomainInternal");
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
CreateAcceptedDomain(runSpace, domain);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("CreateAuthoritativeDomainInternal", ex);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("CreateAuthoritativeDomainInternal");
|
|
}
|
|
|
|
private void ChangeAcceptedDomainTypeInternal(string domainName, ExchangeAcceptedDomainType domainType)
|
|
{
|
|
ExchangeLog.LogStart("ChangeAcceptedDomainType");
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
SetAcceptedDomainType(runSpace, domainName, domainType);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("ChangeAcceptedDomainType", ex);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
|
|
CloseRunspace(runSpace);
|
|
}
|
|
|
|
ExchangeLog.LogEnd("ChangeAcceptedDomainType");
|
|
}
|
|
|
|
private void DeleteAcceptedDomain(string domainName)
|
|
{
|
|
ExchangeLog.LogStart("DeleteAcceptedDomain");
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
RemoveAcceptedDomain(runSpace, domainName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("DeleteAcceptedDomain", ex);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
|
|
CloseRunspace(runSpace);
|
|
}
|
|
|
|
ExchangeLog.LogEnd("DeleteAcceptedDomain");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes Authoritative Domain on Hub Transport Server
|
|
/// </summary>
|
|
/// <param name="domain"></param>
|
|
private void DeleteAuthoritativeDomainInternal(string domain)
|
|
{
|
|
ExchangeLog.LogStart("DeleteDomainInternal");
|
|
//Delete accepted domain
|
|
DeleteAcceptedDomain(domain);
|
|
ExchangeLog.LogEnd("DeleteDomainInternal");
|
|
}
|
|
|
|
private string CreateAcceptedDomain(Runspace runSpace, string name)
|
|
{
|
|
ExchangeLog.LogStart("CreateAcceptedDomain");
|
|
|
|
Command cmd = new Command("New-AcceptedDomain");
|
|
cmd.Parameters.Add("Name", name);
|
|
cmd.Parameters.Add("DomainName", name);
|
|
cmd.Parameters.Add("DomainType", "Authoritative");
|
|
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
string id = GetResultObjectDN(result);
|
|
|
|
ExchangeLog.LogEnd("CreateAcceptedDomain");
|
|
|
|
return id;
|
|
}
|
|
|
|
private void RemoveAcceptedDomain(Runspace runSpace, string id)
|
|
{
|
|
ExchangeLog.LogStart("RemoveAcceptedDomain");
|
|
Command cmd = new Command("Remove-AcceptedDomain");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
ExchangeLog.LogEnd("RemoveAcceptedDomain");
|
|
}
|
|
|
|
private void SetAcceptedDomainType(Runspace runSpace, string id, ExchangeAcceptedDomainType domainType)
|
|
{
|
|
ExchangeLog.LogStart("SetAcceptedDomainType");
|
|
Command cmd = new Command("Set-AcceptedDomain");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("DomainType", domainType.ToString());
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
ExchangeLog.LogEnd("SetAcceptedDomainType");
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ActiveSync
|
|
private void CreateOrganizationActiveSyncPolicyInternal(string organizationId)
|
|
{
|
|
ExchangeLog.LogStart("CreateOrganizationActiveSyncPolicyInternal");
|
|
ExchangeLog.DebugInfo(" Organization Id: {0}", organizationId);
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
//create ActiveSync policy
|
|
CreateActiveSyncPolicy(runSpace, organizationId);
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("CreateOrganizationActiveSyncPolicyInternal");
|
|
}
|
|
|
|
internal string CreateActiveSyncPolicy(Runspace runSpace, string organizationId)
|
|
{
|
|
ExchangeLog.LogStart("CreateActiveSyncPolicy");
|
|
Command cmd = new Command("New-ActiveSyncMailboxPolicy");
|
|
cmd.Parameters.Add("Name", organizationId);
|
|
cmd.Parameters.Add("AllowNonProvisionableDevices", true);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
string id = GetResultObjectIdentity(result);
|
|
ExchangeLog.LogEnd("CreateActiveSyncPolicy");
|
|
return id;
|
|
}
|
|
|
|
internal void DeleteActiveSyncPolicy(Runspace runSpace, string id)
|
|
{
|
|
ExchangeLog.LogStart("DeleteActiveSyncPolicy");
|
|
Command cmd = new Command("Remove-ActiveSyncMailboxPolicy");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
ExchangeLog.LogEnd("DeleteActiveSyncPolicy");
|
|
}
|
|
|
|
private ExchangeActiveSyncPolicy GetActiveSyncPolicyInternal(string id)
|
|
{
|
|
ExchangeLog.LogStart("GetActiveSyncPolicyInternal");
|
|
ExchangeLog.DebugInfo("Id: {0}", id);
|
|
ExchangeActiveSyncPolicy info = null;
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
Command cmd = new Command("Get-ActiveSyncMailboxPolicy");
|
|
cmd.Parameters.Add("Identity", id);
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
|
|
if (result != null && result.Count > 0)
|
|
{
|
|
PSObject policy = result[0];
|
|
info = new ExchangeActiveSyncPolicy();
|
|
info.AllowNonProvisionableDevices = (bool)GetPSObjectProperty(policy, "AllowNonProvisionableDevices");
|
|
info.AttachmentsEnabled = (bool)GetPSObjectProperty(policy, "AttachmentsEnabled");
|
|
info.MaxAttachmentSizeKB =
|
|
ConvertUnlimitedToKB((Unlimited<ByteQuantifiedSize>)GetPSObjectProperty(policy, "MaxAttachmentSize"));
|
|
info.UNCAccessEnabled = (bool)GetPSObjectProperty(policy, "UNCAccessEnabled");
|
|
info.WSSAccessEnabled = (bool)GetPSObjectProperty(policy, "WSSAccessEnabled");
|
|
|
|
info.DevicePasswordEnabled = (bool)GetPSObjectProperty(policy, "DevicePasswordEnabled");
|
|
info.AlphanumericPasswordRequired = (bool)GetPSObjectProperty(policy, "AlphanumericDevicePasswordRequired");
|
|
info.PasswordRecoveryEnabled = (bool)GetPSObjectProperty(policy, "PasswordRecoveryEnabled");
|
|
info.DeviceEncryptionEnabled = (bool)GetPSObjectProperty(policy, "DeviceEncryptionEnabled");
|
|
info.AllowSimplePassword = (bool)GetPSObjectProperty(policy, "AllowSimpleDevicePassword");
|
|
|
|
info.MaxPasswordFailedAttempts =
|
|
ConvertUnlimitedToInt32((Unlimited<int>)GetPSObjectProperty(policy, "MaxDevicePasswordFailedAttempts"));
|
|
int? passwordLength = (int?)GetPSObjectProperty(policy, "MinDevicePasswordLength");
|
|
info.MinPasswordLength = ConvertNullableToInt32(passwordLength);
|
|
|
|
info.InactivityLockMin = ConvertUnlimitedToMinutes((Unlimited<EnhancedTimeSpan>)GetPSObjectProperty(policy, "MaxInactivityTimeDeviceLock"));
|
|
info.PasswordExpirationDays = ConvertUnlimitedTimeSpanToDays((Unlimited<EnhancedTimeSpan>)GetPSObjectProperty(policy, "DevicePasswordExpiration"));
|
|
info.PasswordHistory = (int)GetPSObjectProperty(policy, "DevicePasswordHistory");
|
|
|
|
|
|
info.RefreshInterval = ConvertUnlimitedToHours((Unlimited<EnhancedTimeSpan>)GetPSObjectProperty(policy, "DevicePolicyRefreshInterval"));
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("GetActiveSyncPolicyInternal");
|
|
return info;
|
|
}
|
|
|
|
private void SetActiveSyncPolicyInternal(
|
|
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)
|
|
{
|
|
ExchangeLog.LogStart("SetActiveSyncPolicyInternal");
|
|
ExchangeLog.DebugInfo("Id: {0}", id);
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
Command cmd = new Command("Set-ActiveSyncMailboxPolicy");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("AllowNonProvisionableDevices", allowNonProvisionableDevices);
|
|
cmd.Parameters.Add("AttachmentsEnabled", attachmentsEnabled);
|
|
cmd.Parameters.Add("MaxAttachmentSize", ConvertKBToUnlimited(maxAttachmentSizeKB));
|
|
cmd.Parameters.Add("UNCAccessEnabled", uncAccessEnabled);
|
|
cmd.Parameters.Add("WSSAccessEnabled", wssAccessEnabled);
|
|
|
|
cmd.Parameters.Add("DevicePasswordEnabled", devicePasswordEnabled);
|
|
cmd.Parameters.Add("AlphanumericDevicePasswordRequired", alphanumericPasswordRequired);
|
|
cmd.Parameters.Add("PasswordRecoveryEnabled", passwordRecoveryEnabled);
|
|
cmd.Parameters.Add("DeviceEncryptionEnabled", deviceEncryptionEnabled);
|
|
cmd.Parameters.Add("AllowSimpleDevicePassword", allowSimplePassword);
|
|
|
|
Unlimited<int> attempts = ConvertInt32ToUnlimited(maxPasswordFailedAttempts);
|
|
cmd.Parameters.Add("MaxDevicePasswordFailedAttempts", attempts);
|
|
|
|
int? passwordLength = ConvertInt32ToNullable(minPasswordLength);
|
|
cmd.Parameters.Add("MinDevicePasswordLength", passwordLength);
|
|
|
|
|
|
Unlimited<EnhancedTimeSpan> inactivityLock = ConvertMinutesToUnlimitedTimeSpan(inactivityLockMin);
|
|
cmd.Parameters.Add("MaxInactivityTimeDeviceLock", inactivityLock);
|
|
|
|
Unlimited<EnhancedTimeSpan> passwordExpiration = ConvertDaysToUnlimitedTimeSpan(passwordExpirationDays);
|
|
cmd.Parameters.Add("DevicePasswordExpiration", passwordExpiration);
|
|
|
|
cmd.Parameters.Add("DevicePasswordHistory", passwordHistory);
|
|
|
|
Unlimited<EnhancedTimeSpan> refInter = ConvertHoursToUnlimitedTimeSpan(refreshInterval);
|
|
cmd.Parameters.Add("DevicePolicyRefreshInterval", refInter);
|
|
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("SetActiveSyncPolicyInternal");
|
|
}
|
|
#endregion
|
|
|
|
#region Mobile devices
|
|
|
|
private ExchangeMobileDevice[] GetMobileDevicesInternal(string accountName)
|
|
{
|
|
ExchangeLog.LogStart("GetMobileDevicesInternal");
|
|
ExchangeLog.DebugInfo("Account name: {0}", accountName);
|
|
|
|
List<ExchangeMobileDevice> devices = new List<ExchangeMobileDevice>();
|
|
ExchangeMobileDevice device = null;
|
|
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Get-ActiveSyncDeviceStatistics");
|
|
cmd.Parameters.Add("Mailbox", accountName);
|
|
|
|
Collection<PSObject> result = null;
|
|
try
|
|
{
|
|
result = ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
|
|
if (result != null)
|
|
{
|
|
foreach (PSObject obj in result)
|
|
{
|
|
device = GetMobileDeviceObject(obj);
|
|
devices.Add(device);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("GetMobileDevicesInternal");
|
|
return devices.ToArray();
|
|
}
|
|
|
|
private ExchangeMobileDevice GetMobileDeviceObject(PSObject obj)
|
|
{
|
|
ExchangeMobileDevice device = new ExchangeMobileDevice();
|
|
device.Id = GetPSObjectIdentity(obj);
|
|
device.FirstSyncTime = ConvertNullableToDateTime((DateTime?)GetPSObjectProperty(obj, "FirstSyncTime"));
|
|
device.LastPolicyUpdateTime = ConvertNullableToDateTime((DateTime?)GetPSObjectProperty(obj, "LastPolicyUpdateTime"));
|
|
device.LastSyncAttemptTime = ConvertNullableToDateTime((DateTime?)GetPSObjectProperty(obj, "LastSyncAttemptTime"));
|
|
device.LastSuccessSync = ConvertNullableToDateTime((DateTime?)GetPSObjectProperty(obj, "LastSuccessSync"));
|
|
device.DeviceType = (string)GetPSObjectProperty(obj, "DeviceType");
|
|
device.DeviceID = (string)GetPSObjectProperty(obj, "DeviceID");
|
|
device.DeviceUserAgent = (string)GetPSObjectProperty(obj, "DeviceUserAgent");
|
|
DateTime? wipeSentTime = (DateTime?)GetPSObjectProperty(obj, "DeviceWipeSentTime");
|
|
device.DeviceWipeSentTime = ConvertNullableToDateTime(wipeSentTime);
|
|
DateTime? wipeRequestTime = (DateTime?)GetPSObjectProperty(obj, "DeviceWipeRequestTime");
|
|
device.DeviceWipeRequestTime = ConvertNullableToDateTime(wipeRequestTime);
|
|
DateTime? wipeAckTime = (DateTime?)GetPSObjectProperty(obj, "DeviceWipeAckTime");
|
|
device.DeviceWipeAckTime = ConvertNullableToDateTime(wipeAckTime);
|
|
device.LastPingHeartbeat = ConvertNullableToInt32((UInt32?)GetPSObjectProperty(obj, "LastPingHeartbeat"));
|
|
device.RecoveryPassword = (string)GetPSObjectProperty(obj, "RecoveryPassword");
|
|
device.DeviceModel = (string)GetPSObjectProperty(obj, "DeviceModel");
|
|
device.DeviceIMEI = (string)GetPSObjectProperty(obj, "DeviceIMEI");
|
|
device.DeviceFriendlyName = (string)GetPSObjectProperty(obj, "DeviceFriendlyName");
|
|
device.DeviceOS = (string)GetPSObjectProperty(obj, "DeviceOS");
|
|
device.DeviceOSLanguage = (string)GetPSObjectProperty(obj, "DeviceOSLanguage");
|
|
device.DevicePhoneNumber = (string)GetPSObjectProperty(obj, "DevicePhoneNumber");
|
|
//status
|
|
if (wipeAckTime.HasValue)
|
|
{
|
|
//green
|
|
device.Status = MobileDeviceStatus.WipeSuccessful;
|
|
}
|
|
else
|
|
{
|
|
if (wipeRequestTime.HasValue || wipeSentTime.HasValue)
|
|
{
|
|
//red
|
|
device.Status = MobileDeviceStatus.PendingWipe;
|
|
}
|
|
else
|
|
{
|
|
//black
|
|
device.Status = MobileDeviceStatus.OK;
|
|
}
|
|
}
|
|
|
|
return device;
|
|
}
|
|
|
|
private ExchangeMobileDevice GetMobileDeviceInternal(string id)
|
|
{
|
|
ExchangeLog.LogStart("GetMobileDeviceInternal");
|
|
ExchangeMobileDevice device = null;
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Get-ActiveSyncDeviceStatistics");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("ShowRecoveryPassword", true);
|
|
Collection<PSObject> result = ExecuteShellCommand(runSpace, cmd);
|
|
if (result != null && result.Count > 0)
|
|
{
|
|
device = GetMobileDeviceObject(result[0]);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("GetMobileDeviceInternal");
|
|
return device;
|
|
}
|
|
|
|
private void WipeDataFromDeviceInternal(string id)
|
|
{
|
|
ExchangeLog.LogStart("WipeDataFromDeviceInternal");
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Clear-ActiveSyncDevice");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("WipeDataFromDeviceInternal");
|
|
}
|
|
|
|
private void CancelRemoteWipeRequestInternal(string id)
|
|
{
|
|
ExchangeLog.LogStart("CancelRemoteWipeRequestInternal");
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Clear-ActiveSyncDevice");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("Cancel", true);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
|
|
ExchangeLog.LogEnd("CancelRemoteWipeRequestInternal");
|
|
}
|
|
|
|
|
|
internal void RemoveDevicesInternal(Runspace runSpace, string accountName)
|
|
{
|
|
ExchangeLog.LogStart("RemoveDevicesInternal");
|
|
ExchangeLog.DebugInfo("Account name: {0}", accountName);
|
|
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Get-ActiveSyncDeviceStatistics");
|
|
cmd.Parameters.Add("Mailbox", accountName);
|
|
|
|
Collection<PSObject> result = null;
|
|
try
|
|
{
|
|
result = ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
|
|
if (result != null)
|
|
{
|
|
foreach (PSObject obj in result)
|
|
{
|
|
ExchangeMobileDevice device = GetMobileDeviceObject(obj);
|
|
|
|
cmd = new Command("Remove-ActiveSyncDevice");
|
|
cmd.Parameters.Add("Identity", device.DeviceID);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
|
|
}
|
|
ExchangeLog.LogEnd("RemoveDevicesInternal");
|
|
}
|
|
|
|
|
|
private void RemoveDeviceInternal(string id)
|
|
{
|
|
ExchangeLog.LogStart("RemoveDeviceInternal");
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
Command cmd = new Command("Remove-ActiveSyncDevice");
|
|
cmd.Parameters.Add("Identity", id);
|
|
cmd.Parameters.Add("Confirm", false);
|
|
ExecuteShellCommand(runSpace, cmd);
|
|
}
|
|
finally
|
|
{
|
|
CloseRunspace(runSpace);
|
|
}
|
|
|
|
ExchangeLog.LogEnd("RemoveDeviceInternal");
|
|
}
|
|
#endregion
|
|
|
|
#region Convert Utils
|
|
internal int ConvertUnlimitedToInt32(Unlimited<int> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = value.Value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal Unlimited<int> ConvertInt32ToUnlimited(int value)
|
|
{
|
|
if (value == -1)
|
|
return Unlimited<int>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<int> ret = new Unlimited<int>();
|
|
ret.Value = value;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
internal long ConvertUnlimitedToBytes(Unlimited<ByteQuantifiedSize> value)
|
|
{
|
|
long ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = Convert.ToInt64(value.Value.ToBytes());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal int ConvertUnlimitedToKB(Unlimited<ByteQuantifiedSize> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = Convert.ToInt32(value.Value.ToKB());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal int ConvertUnlimitedToMB(Unlimited<ByteQuantifiedSize> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = Convert.ToInt32(value.Value.ToMB());
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
internal int ConvertUnlimitedToHours(Unlimited<EnhancedTimeSpan> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = Convert.ToInt32(value.Value.TotalHours);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal int ConvertUnlimitedToMinutes(Unlimited<EnhancedTimeSpan> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = Convert.ToInt32(value.Value.TotalMinutes);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal Unlimited<EnhancedTimeSpan> ConvertHoursToUnlimitedTimeSpan(int value)
|
|
{
|
|
if (value == -1)
|
|
return Unlimited<EnhancedTimeSpan>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<EnhancedTimeSpan> ret = new Unlimited<EnhancedTimeSpan>();
|
|
ret.Value = EnhancedTimeSpan.FromHours(Convert.ToDouble(value));
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|
|
internal Unlimited<EnhancedTimeSpan> ConvertMinutesToUnlimitedTimeSpan(int value)
|
|
{
|
|
if (value == -1)
|
|
return Unlimited<EnhancedTimeSpan>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<EnhancedTimeSpan> ret = new Unlimited<EnhancedTimeSpan>();
|
|
ret.Value = EnhancedTimeSpan.FromMinutes(Convert.ToDouble(value));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
internal Unlimited<EnhancedTimeSpan> ConvertDaysToUnlimitedTimeSpan(int value)
|
|
{
|
|
if (value == -1)
|
|
return Unlimited<EnhancedTimeSpan>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<EnhancedTimeSpan> ret = new Unlimited<EnhancedTimeSpan>();
|
|
ret.Value = EnhancedTimeSpan.FromDays(Convert.ToDouble(value));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
internal int ConvertUnlimitedTimeSpanToDays(Unlimited<EnhancedTimeSpan> value)
|
|
{
|
|
int ret = 0;
|
|
if (value.IsUnlimited)
|
|
{
|
|
ret = -1;
|
|
}
|
|
else
|
|
{
|
|
ret = value.Value.Days;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
internal int ConvertNullableToInt32<T>(Nullable<T> value) where T : struct
|
|
{
|
|
int ret = 0;
|
|
if (value.HasValue)
|
|
{
|
|
ret = Convert.ToInt32(value.Value);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
internal int? ConvertInt32ToNullable(int value)
|
|
{
|
|
int? ret = null;
|
|
if (value != 0)
|
|
{
|
|
ret = new int?(value);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
internal DateTime ConvertNullableToDateTime(DateTime? value)
|
|
{
|
|
DateTime ret = DateTime.MinValue;
|
|
if (value.HasValue)
|
|
{
|
|
ret = value.Value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal bool ConvertNullableToBoolean(bool? value)
|
|
{
|
|
bool ret = false;
|
|
if (value.HasValue)
|
|
{
|
|
ret = value.Value;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
internal int ConvertEnhancedTimeSpanToDays(EnhancedTimeSpan value)
|
|
{
|
|
return value.Days;
|
|
}
|
|
|
|
internal EnhancedTimeSpan ConvertDaysToEnhancedTimeSpan(int days)
|
|
{
|
|
return EnhancedTimeSpan.FromDays(Convert.ToDouble(days));
|
|
}
|
|
|
|
internal Unlimited<ByteQuantifiedSize> ConvertKBToUnlimited(int kb)
|
|
{
|
|
if (kb == -1)
|
|
return Unlimited<ByteQuantifiedSize>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<ByteQuantifiedSize> ret = new Unlimited<ByteQuantifiedSize>();
|
|
ret.Value = ByteQuantifiedSize.FromKB(Convert.ToUInt64(kb));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
internal Unlimited<ByteQuantifiedSize> ConvertKBToUnlimited(long kb)
|
|
{
|
|
if (kb == -1)
|
|
return Unlimited<ByteQuantifiedSize>.UnlimitedValue;
|
|
else
|
|
{
|
|
Unlimited<ByteQuantifiedSize> ret = new Unlimited<ByteQuantifiedSize>();
|
|
ret.Value = ByteQuantifiedSize.FromKB(Convert.ToUInt64(kb));
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
internal string ProxyAddressToString(ProxyAddress proxyAddress)
|
|
{
|
|
string ret = null;
|
|
if (proxyAddress != null)
|
|
ret = proxyAddress.AddressString;
|
|
return ret;
|
|
}
|
|
|
|
internal string SmtpAddressToString(SmtpAddress smtpAddress)
|
|
{
|
|
string ret = null;
|
|
if (smtpAddress != null)
|
|
ret = smtpAddress.ToString();
|
|
return ret;
|
|
}
|
|
|
|
internal string CountryInfoToString(CountryInfo countryInfo)
|
|
{
|
|
string ret = null;
|
|
if (countryInfo != null)
|
|
ret = countryInfo.Name;
|
|
return ret;
|
|
}
|
|
|
|
internal CountryInfo ParseCountryInfo(string country)
|
|
{
|
|
CountryInfo ret = null;
|
|
if (!string.IsNullOrEmpty(country))
|
|
{
|
|
ret = CountryInfo.Parse(country);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
internal string ObjToString(object obj)
|
|
{
|
|
string ret = null;
|
|
if (obj != null)
|
|
ret = obj.ToString();
|
|
return ret;
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
#region Utils
|
|
private object GetObjectPropertyValue(object obj, string property)
|
|
{
|
|
PropertyInfo pinfo = obj.GetType().GetProperty(property);
|
|
return pinfo.GetValue(obj, null);
|
|
}
|
|
|
|
private object GetObjectIndexerValue(object obj, object index)
|
|
{
|
|
Type t = obj.GetType();
|
|
object ret = t.InvokeMember("Item", BindingFlags.GetProperty, null, obj, new object[] { index });
|
|
return ret;
|
|
}
|
|
|
|
internal string GetServerName()
|
|
{
|
|
return System.Environment.MachineName;
|
|
}
|
|
#endregion
|
|
|
|
#region Transactions
|
|
|
|
internal ExchangeTransaction StartTransaction()
|
|
{
|
|
return new ExchangeTransaction();
|
|
}
|
|
|
|
internal void RollbackTransaction(ExchangeTransaction transaction)
|
|
{
|
|
ExchangeLog.LogStart("RollbackTransaction");
|
|
Runspace runSpace = null;
|
|
try
|
|
{
|
|
runSpace = OpenRunspace();
|
|
|
|
|
|
for (int i = transaction.Actions.Count - 1; i > -1; i--)
|
|
{
|
|
//reverse order
|
|
try
|
|
{
|
|
RollbackAction(transaction.Actions[i], runSpace);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("Rollback error", ex);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ExchangeLog.LogError("Rollback error", ex);
|
|
}
|
|
finally
|
|
{
|
|
|
|
CloseRunspace(runSpace);
|
|
}
|
|
ExchangeLog.LogEnd("RollbackTransaction");
|
|
}
|
|
|
|
private void RollbackAction(TransactionAction action, Runspace runspace)
|
|
{
|
|
ExchangeLog.LogInfo("Rollback action: {0}", action.ActionType);
|
|
switch (action.ActionType)
|
|
{
|
|
case TransactionAction.TransactionActionTypes.CreateOrganizationUnit:
|
|
DeleteADObject(action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateDistributionGroup:
|
|
RemoveDistributionGroup(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.EnableDistributionGroup:
|
|
DisableMailSecurityDistributionGroup(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateGlobalAddressList:
|
|
DeleteGlobalAddressList(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateAddressList:
|
|
DeleteAddressList(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateAddressBookPolicy:
|
|
DeleteAddressBookPolicy(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateOfflineAddressBook:
|
|
DeleteOfflineAddressBook(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateActiveSyncPolicy:
|
|
DeleteActiveSyncPolicy(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateAcceptedDomain:
|
|
RemoveAcceptedDomain(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.AddUPNSuffix:
|
|
RemoveUPNSuffix(action.Id, action.Suffix);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateMailbox:
|
|
RemoveMailbox(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.EnableMailbox:
|
|
DisableMailbox(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreateContact:
|
|
RemoveContact(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.CreatePublicFolder:
|
|
RemovePublicFolder(runspace, action.Id);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.AddMailboxFullAccessPermission:
|
|
RemoveMailboxAccessPermission(runspace, action.Account, action.Id, "FullAccess");
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.AddSendAsPermission:
|
|
RemoveADPermission(runspace, action.Account, action.Id, null, "Send-as", null);
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.RemoveMailboxFullAccessPermission:
|
|
SetMailboxPermission(runspace, action.Account, action.Id, "FullAccess");
|
|
break;
|
|
case TransactionAction.TransactionActionTypes.RemoveSendAsPermission:
|
|
SetExtendedRights(runspace, action.Account, action.Id, "Send-as");
|
|
break;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public override bool IsInstalled()
|
|
{
|
|
|
|
int value = 0;
|
|
bool bResult = false;
|
|
RegistryKey root = Registry.LocalMachine;
|
|
RegistryKey rk = root.OpenSubKey(ExchangeRegistryPath);
|
|
if (rk != null)
|
|
{
|
|
value = (int)rk.GetValue("MsiProductMajor", null);
|
|
if (value == 15)
|
|
{
|
|
value = (int)rk.GetValue("MsiProductMinor", null);
|
|
if (value == 0) bResult = true;
|
|
}
|
|
rk.Close();
|
|
}
|
|
return bResult;
|
|
}
|
|
}
|
|
}
|
|
|