Files
LIAM/LiamExchange/C4IT.LIAM.ExchangeManager.cs
Drechsler, Meik f563d78417 initial
2025-10-15 14:56:07 +02:00

1027 lines
40 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Linq;
using System.Reflection;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using System.Threading.Tasks;
using System.Collections;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices.ActiveDirectory;
using System.DirectoryServices;
using System.ComponentModel;
using System.Security.AccessControl;
namespace C4IT.LIAM
{
/// <summary>
/// Manages Exchange operations using PowerShell remoting
/// </summary>
public partial class ExchangeManager
{
private readonly cLiamProviderBase _provider;
private readonly string _exchangeUri;
private readonly PSCredential _credential;
private readonly string _organizationalUnit;
private readonly string _domain;
/// <summary>
/// Constructor with explicit credentials, Exchange URI and OU path
/// </summary>
/// <param name="exchangeUri">URL of the Exchange PowerShell endpoint (e.g. "http://exchangeserver/PowerShell")</param>
/// <param name="credential">Explicit credentials</param>
/// <param name="organizationalUnit">OU path where objects should be created</param>
public ExchangeManager(cLiamProviderBase provider, string exchangeUri, PSCredential credential, string domain, string organizationalUnit)
{
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
_exchangeUri = exchangeUri;
_credential = credential;
_domain = domain;
_organizationalUnit = organizationalUnit;
}
/// <summary>
/// Creates a runspace connected to the Exchange PowerShell endpoint
/// </summary>
private Runspace CreateRunspace()
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
var connectionInfo = new WSManConnectionInfo(
new Uri(_exchangeUri),
"http://schemas.microsoft.com/powershell/Microsoft.Exchange",
_credential);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
var runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
return runspace;
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
// Internal helper for creation details
private class CreationResult
{
public Guid ObjectGuid { get; set; }
public List<Tuple<string, string, string, string>> Groups { get; private set; }
public CreationResult()
{
Groups = new List<Tuple<string, string, string, string>>();
}
}
private DirectoryEntry FindAdObject(string ldapFilter)
{
using (DirectoryEntry root = new DirectoryEntry("LDAP://" + _organizationalUnit,
_credential.UserName,
SecureStringToString(_credential.Password),
AuthenticationTypes.Secure))
{
using (DirectorySearcher ds = new DirectorySearcher(root))
{
ds.Filter = ldapFilter;
ds.PropertiesToLoad.Add("objectGUID");
ds.PropertiesToLoad.Add("objectSid");
ds.PropertiesToLoad.Add("cn");
ds.PropertiesToLoad.Add("sAMAccountName");
SearchResult searchResult = ds.FindOne();
if (searchResult != null)
return searchResult.GetDirectoryEntry();
return null;
}
}
}
/// <summary>
/// Creates a distribution group (mailing list). Optionally members can be added initially.
/// </summary>
public void CreateDistributionGroup(string name, string alias, List<string> initialMembers = null)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("New-DistributionGroup")
.AddParameter("Name", name)
.AddParameter("Alias", alias)
.AddParameter("OrganizationalUnit", _organizationalUnit);
ps.Invoke();
if (initialMembers != null)
{
foreach (var member in initialMembers)
{
ps.Commands.Clear();
ps.AddCommand("Add-DistributionGroupMember")
.AddParameter("Identity", name)
.AddParameter("Member", member);
ps.Invoke();
}
}
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Creates a security group in Active Directory that can be used for Exchange permissions
/// direkt per LDAP und mit den im Konstruktor übergebenen Credentials & Domain.
/// </summary>
public bool CreateSecurityGroup(eLiamAccessRoles accessRole, string baseName, string baseDescription="")
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Find the naming convention for this role
var namingConvention = _provider.NamingConventions
.FirstOrDefault(nc => nc.AccessRole == accessRole);
if (namingConvention == null)
throw new InvalidOperationException($"No naming convention found for role '{accessRole}'");
// Generate group name and description from templates
string groupName = namingConvention.NamingTemplate
.Replace("{Name}", baseName);
string groupDescription = namingConvention.DescriptionTemplate
.Replace("{Name}", baseDescription);
// Determine scope bit for groupType
int scopeBit;
switch (namingConvention.Scope)
{
case eLiamAccessRoleScopes.Global:
scopeBit = 0x2;
break;
case eLiamAccessRoleScopes.DomainLocal:
scopeBit = 0x4;
break;
case eLiamAccessRoleScopes.Universal:
scopeBit = 0x8;
break;
default:
scopeBit = 0x8;
break;
}
int groupType = unchecked((int)(0x80000000 | scopeBit));
// Create the group in AD
string ldapPath = $"LDAP://{_organizationalUnit}";
string password = new System.Net.NetworkCredential(string.Empty, _credential.Password).Password;
using (var root = new DirectoryEntry(
ldapPath,
_credential.UserName,
password,
AuthenticationTypes.Secure))
{
var newGroup = root.Children.Add($"CN={groupName}", "group");
newGroup.Properties["sAMAccountName"].Value = groupName;
newGroup.Properties["displayName"].Value = groupName;
newGroup.Properties["groupType"].Value = groupType;
newGroup.Properties["description"].Value = groupDescription;
newGroup.CommitChanges();
}
return true;
}
catch (Exception ex)
{
LogException(ex);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
/// <summary>
/// Gets all shared mailboxes matching an optional filter
/// </summary>
public IEnumerable<PSObject> GetSharedMailboxes(string filter = null)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-Mailbox")
.AddParameter("RecipientTypeDetails", "SharedMailbox");
if (!string.IsNullOrEmpty(filter))
{
ps.AddParameter("Filter", filter);
}
return ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets a shared mailbox by primary SMTP address
/// </summary>
public PSObject GetSharedMailboxByAddress(string primarySmtpAddress)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-Mailbox")
.AddParameter("RecipientTypeDetails", "SharedMailbox")
.AddParameter("PrimarySmtpAddress", primarySmtpAddress);
var results = ps.Invoke();
return results.Count > 0 ? results[0] : null;
}
}
catch (Exception ex)
{
LogException(ex);
return null;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets all distribution groups matching an optional filter
/// </summary>
public IEnumerable<PSObject> GetDistributionGroups(string filter = null)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-DistributionGroup");
if (!string.IsNullOrEmpty(filter))
{
ps.AddParameter("Filter", filter);
}
return ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets a distribution group by primary SMTP address.
/// Die Methode bleibt unverändert.
/// </summary>
public PSObject GetDistributionGroupByAddress(string primarySmtpAddress)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-DistributionGroup")
.AddParameter("PrimarySmtpAddress", primarySmtpAddress);
var results = ps.Invoke();
return results.Count > 0 ? results[0] : null;
}
}
catch (Exception ex)
{
LogException(ex);
return null;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets members of a distribution group
/// </summary>
public IEnumerable<PSObject> GetDistributionGroupMembers(string distributionListIdentity)
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
// alle Members des DL holen
ps.AddCommand("Get-DistributionGroupMember")
.AddParameter("Identity", distributionListIdentity)
.AddParameter("ResultSize", "Unlimited");
var members = ps.Invoke();
if (ps.HadErrors || members.Count == 0)
return Enumerable.Empty<PSObject>();
var result = new List<PSObject>();
foreach (var member in members)
{
// nur Gruppen (Security- oder Distributions-Gruppen)
var rt = member.Properties["RecipientTypeDetails"]?.Value?.ToString() ?? "";
if (rt.IndexOf("Group", StringComparison.OrdinalIgnoreCase) <= 0)
continue;
// SamAccountName auslesen
var name = member.Properties["Name"]?.Value?.ToString();
if (string.IsNullOrEmpty(name))
continue;
// AD-Gruppe per .NET auflösen
using (var ctx = new PrincipalContext(ContextType.Domain))
using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, name))
{
if (grp == null)
continue;
// PSObject bauen
var obj = new PSObject();
obj.Properties.Add(new PSNoteProperty("SamAccountName", grp.SamAccountName));
obj.Properties.Add(new PSNoteProperty("Name", grp.Name));
obj.Properties.Add(new PSNoteProperty("Sid", grp.Sid.Value));
obj.Properties.Add(new PSNoteProperty("DistinguishedName", grp.DistinguishedName));
obj.Properties.Add(new PSNoteProperty("GroupPrincipal", grp));
result.Add(obj);
}
}
return result;
}
}
public IEnumerable<PSObject> GetSendAsPermissionMembers(string mailboxIdentity)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
// 1) Alle AD-Permissions holen
ps.AddCommand("Get-ADPermission")
.AddParameter("Identity", mailboxIdentity);
var perms = ps.Invoke();
if (ps.HadErrors) return Enumerable.Empty<PSObject>();
var result = new List<PSObject>();
using (var ps2 = PowerShell.Create())
{
ps2.Runspace = runspace;
foreach (var perm in perms)
{
// 2) Nur explizite (nicht geerbte) Rechte
var inherited = perm.Properties["IsInherited"]?.Value as bool? ?? true;
if (inherited) continue;
// 3) ExtendedRights robust auslesen
var rawVal = perm.Properties["ExtendedRights"]?.Value;
IEnumerable<object> rights = null;
if (rawVal is IEnumerable seq && !(rawVal is string))
rights = seq.Cast<object>();
else if (rawVal is PSObject pso && pso.BaseObject is IEnumerable baseSeq)
rights = baseSeq.Cast<object>();
else if (rawVal != null)
rights = new[] { rawVal };
// wenn gar keine Rechte da sind, weiter
if (rights == null)
continue;
// die Liste der RechtStrings extrahieren
var rightStrings = rights
.Select(r => (r as PSObject)?.Properties["RawIdentity"]?.Value?.ToString()
?? r.ToString())
.ToList();
// UND jetzt prüfen, ob *genau* "Send-As" (normaler Bindestrich) enthalten ist
if (!rightStrings
.Any(rs => string.Equals(rs.Trim(),
"Send-As",
StringComparison.OrdinalIgnoreCase)))
{
continue; // kein SendAs, nächste Permission
}
// 4) SystemAccounts rausfiltern
var userName = perm.Properties["User"]?.Value?.ToString() ?? "";
if (userName.StartsWith("NT AUTHORITY", StringComparison.OrdinalIgnoreCase)
|| userName.IndexOf("SELF", StringComparison.OrdinalIgnoreCase) >= 0
|| userName.IndexOf("Administrator", StringComparison.OrdinalIgnoreCase) >= 0)
continue;
// 5) Get-User auflösen
ps2.Commands.Clear();
ps2.AddCommand("Get-User")
.AddParameter("Identity", userName);
var users = ps2.Invoke();
if (users.Count > 0)
result.Add(users[0]);
}
}
return result;
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Liefert pro SendAsGruppe ein PSObject mit Name, SID und dem GroupPrincipal selbst.
/// </summary>
public IEnumerable<PSObject> GetSendAsPermissionGroups(string mailboxIdentity)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-ADPermission")
.AddParameter("Identity", mailboxIdentity);
var perms = ps.Invoke();
if (ps.HadErrors || perms.Count == 0)
return Enumerable.Empty<PSObject>();
var result = new List<PSObject>();
foreach (var perm in perms)
{
// 1) Nur explizite Rechte
var inherited = perm.Properties["IsInherited"]?.Value as bool? ?? true;
if (inherited) continue;
// 2) ExtendedRights auf "SendAs" prüfen (nur via ToString)
var rawVal = perm.Properties["ExtendedRights"]?.Value;
IEnumerable<object> rights;
if (rawVal is System.Collections.IEnumerable seq && !(rawVal is string))
rights = seq.Cast<object>();
else if (rawVal is PSObject pso && pso.BaseObject is System.Collections.IEnumerable baseSeq)
rights = baseSeq.Cast<object>();
else if (rawVal != null)
rights = new[] { rawVal };
else
continue;
// ganz einfach: jede Rechte-Instanz zu String machen
var rightStrings = rights.Select(r => r.ToString().Trim());
if (!rightStrings.Any(s =>
string.Equals(s, "Send-As", StringComparison.OrdinalIgnoreCase)))
{
continue;
}
// 3) Nur GruppenPrincipals (DOMAIN\Name) und keine SystemAccounts
var userName = perm.Properties["User"]?.Value?.ToString() ?? "";
var low = userName.ToLowerInvariant();
if (!userName.Contains("\\") ||
low.StartsWith("nt authority") ||
low.Contains("self") ||
low.Contains("administrator"))
continue;
// 4) Gruppe im AD auflösen
var sam = userName.Split('\\').Last();
using (var ctx = new PrincipalContext(ContextType.Domain))
using (var grp = GroupPrincipal.FindByIdentity(ctx, sam))
{
if (grp == null)
continue;
// 5) PSObject mit allen gewünschten Properties anlegen
var obj = new PSObject();
obj.Properties.Add(new PSNoteProperty("SamAccountName", grp.SamAccountName));
obj.Properties.Add(new PSNoteProperty("Name", grp.Name));
obj.Properties.Add(new PSNoteProperty("Sid", grp.Sid.Value));
obj.Properties.Add(new PSNoteProperty("DistinguishedName", grp.DistinguishedName));
obj.Properties.Add(new PSNoteProperty("GroupPrincipal", grp));
result.Add(obj);
}
}
return result;
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Liefert pro Gruppe, die FullAccess auf das angegebene Postfach hat,
/// ein PSObject mit Name, SID, DistinguishedName und dem GroupPrincipal.
/// </summary>
public IEnumerable<PSObject> GetFullAccessPermissionGroups(string mailboxIdentity)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
// 1) Alle FullAccess-Berechtigungen für das Postfach holen
ps.AddCommand("Get-MailboxPermission")
.AddParameter("Identity", mailboxIdentity);
var perms = ps.Invoke();
if (ps.HadErrors || perms.Count == 0)
return Enumerable.Empty<PSObject>();
var result = new List<PSObject>();
foreach (var perm in perms)
{
// 2) Eingebettete Properties ziehen
// - IsInherited
// - AccessRights (MultiValuedProperty)
var inherited = perm.Properties["IsInherited"]?.Value as bool? ?? true;
if (inherited)
continue;
var rawVal = perm.Properties["AccessRights"]?.Value;
IEnumerable<object> rights = null;
if (rawVal is System.Collections.IEnumerable seq && !(rawVal is string))
rights = seq.Cast<object>();
else if (rawVal is PSObject pso && pso.BaseObject is System.Collections.IEnumerable baseSeq)
rights = baseSeq.Cast<object>();
else if (rawVal != null)
rights = new[] { rawVal };
// 3) Nur FullAccess durchlassen
if (rights == null ||
!rights.Any(r =>
{
var s = (r as PSObject)?.BaseObject?.ToString() ?? r.ToString();
return string.Equals(s, "FullAccess", StringComparison.OrdinalIgnoreCase);
}))
{
continue;
}
// 4) Nur Security-Principals im DOMAIN\Name-Format und keine SystemAccounts
var userName = perm.Properties["User"]?.Value?.ToString() ?? "";
var low = userName.ToLowerInvariant();
if (!userName.Contains("\\")
|| low.StartsWith("nt authority")
|| low.Contains("self")
|| low.Contains("administrator"))
{
continue;
}
// 5) Gruppe im AD auflösen und PSObject bauen
var sam = userName.Split('\\').Last();
using (var ctx = new PrincipalContext(ContextType.Domain))
using (var grp = GroupPrincipal.FindByIdentity(ctx, sam))
{
if (grp == null)
continue;
var obj = new PSObject();
obj.Properties.Add(new PSNoteProperty("SamAccountName", grp.SamAccountName));
obj.Properties.Add(new PSNoteProperty("Name", grp.Name));
obj.Properties.Add(new PSNoteProperty("Sid", grp.Sid.Value));
obj.Properties.Add(new PSNoteProperty("DistinguishedName", grp.DistinguishedName));
obj.Properties.Add(new PSNoteProperty("GroupPrincipal", grp));
result.Add(obj);
}
}
return result;
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets users who have permissions on a mailbox
/// </summary>
public IEnumerable<PSObject> GetMailboxPermissionMembers(string id)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-MailboxPermission")
.AddParameter("Identity", id)
.AddParameter("AccessRights", "FullAccess");
var results = ps.Invoke().Where(p =>
!p.Properties["User"].Value.ToString().Contains("NT AUTHORITY") &&
!p.Properties["User"].Value.ToString().Contains("Administrator"));
var userList = new List<PSObject>();
using (var ps2 = PowerShell.Create())
{
ps2.Runspace = runspace;
foreach (var perm in results)
{
ps2.Commands.Clear();
ps2.AddCommand("Get-User")
.AddParameter("Identity", perm.Properties["User"].Value.ToString());
var users = ps2.Invoke();
if (users.Count > 0)
userList.Add(users[0]);
}
}
return userList;
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Sucht im angegebenen ADDomain/OU nach SecurityGruppen, deren Name zum Wildcard passt.
/// Nutzt hierfür die übergebenen Anmeldeinformationen.
/// </summary>
public IEnumerable<PSObject> GetSecurityGroups(string nameWildcard)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
// Credentials in NetworkCredential konvertieren
var netCred = _credential.GetNetworkCredential();
// PrincipalContext auf Domain oder OU
using (var ctx = new PrincipalContext(
ContextType.Domain,
_domain, // ← real domain or DC hostname
_organizationalUnit, // ← the OUDN to scope your search
netCred.UserName,
netCred.Password))
{
{
// QBEGruppe für WildcardSuche
using (var qbe = new GroupPrincipal(ctx) { Name = nameWildcard })
using (var searcher = new PrincipalSearcher(qbe))
{
var result = new List<PSObject>();
foreach (var principal in searcher.FindAll().OfType<GroupPrincipal>())
{
// DirectoryEntry benötigt man, um DistinguishedName auszulesen
var de = principal.GetUnderlyingObject() as DirectoryEntry;
var obj = new PSObject();
obj.Properties.Add(new PSNoteProperty("SamAccountName",
principal.SamAccountName));
obj.Properties.Add(new PSNoteProperty("DisplayName",
principal.Name));
obj.Properties.Add(new PSNoteProperty("Sid",
principal.Sid?.Value ?? string.Empty));
obj.Properties.Add(new PSNoteProperty("DistinguishedName",
de?.Properties["distinguishedName"]?.Value?.ToString()
?? string.Empty));
result.Add(obj);
}
return result;
}
}
}
}
catch (Exception ex)
{
LogException(ex);
return new List<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Adds a member to a distribution group
/// </summary>
public void AddMemberToDistributionGroup(string groupName, string member)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Add-DistributionGroupMember")
.AddParameter("Identity", groupName)
.AddParameter("Member", member);
ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Removes a member from a distribution group
/// </summary>
public void RemoveMemberFromDistributionGroup(string groupName, string member)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Remove-DistributionGroupMember")
.AddParameter("Identity", groupName)
.AddParameter("Member", member)
.AddParameter("Confirm", false);
ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Adds mailbox permission for a user
/// </summary>
public void AddMailboxPermission(string mailboxName, string user, string accessRight = "FullAccess")
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Add-MailboxPermission")
.AddParameter("Identity", mailboxName)
.AddParameter("User", user)
.AddParameter("AccessRights", accessRight)
.AddParameter("InheritanceType", "All");
ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Removes mailbox permission for a user
/// </summary>
public void RemoveMailboxPermission(string mailboxName, string user, string accessRight = "FullAccess")
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Remove-MailboxPermission")
.AddParameter("Identity", mailboxName)
.AddParameter("User", user)
.AddParameter("AccessRights", accessRight)
.AddParameter("InheritanceType", "All")
.AddParameter("Confirm", false);
ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Adds Send As permission for a mailbox
/// </summary>
public async Task<bool> AddSendAsPermission(string mailboxName, string user)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Add-ADPermission")
.AddParameter("Identity", mailboxName)
.AddParameter("User", user)
.AddParameter("ExtendedRights", "Send-As")
.AddParameter("AccessRights", "ExtendedRight");
var results = ps.Invoke();
return results.Count > 0;
}
}
catch (Exception ex)
{
LogException(ex);
return false;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Removes Send As permission for a mailbox
/// </summary>
public async Task<bool> RemoveSendAsPermission(string mailboxName, string user)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Remove-ADPermission")
.AddParameter("Identity", mailboxName)
.AddParameter("User", user)
.AddParameter("ExtendedRights", "Send-As")
.AddParameter("AccessRights", "ExtendedRight")
.AddParameter("Confirm", false);
var results = ps.Invoke();
return results.Count > 0;
}
}
catch (Exception ex)
{
LogException(ex);
return false;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Creates a shared mailbox. Optionally initial permissions (e.g. FullAccess) can be set for members.
/// </summary>
public void CreateSharedMailbox(string name, string alias, List<string> initialMembers = null)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("New-Mailbox")
.AddParameter("Name", name)
.AddParameter("Alias", alias)
.AddParameter("Shared", true)
.AddParameter("OrganizationalUnit", _organizationalUnit);
ps.Invoke();
if (initialMembers != null)
{
foreach (var member in initialMembers)
{
ps.Commands.Clear();
ps.AddCommand("Add-MailboxPermission")
.AddParameter("Identity", name)
.AddParameter("User", member)
.AddParameter("AccessRights", "FullAccess")
.AddParameter("InheritanceType", "All");
ps.Invoke();
}
}
}
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
}
}