using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using C4IT.Matrix42.ServerInfo;
using System.Text.RegularExpressions;
using LiamNtfs;
using System.DirectoryServices;
using System.Security.Principal;
namespace C4IT.LIAM
{
public class cLiamProviderExchange : cLiamProviderBase
{
public static Guid exchangeModuleId = new Guid("A1E213C3-6517-EA11-4881-000C2980FD95");
public readonly ExchangeManager exchangeManager;
internal readonly cActiveDirectoryBase activeDirectoryBase = new cActiveDirectoryBase();
private string exchangeUri;
private PSCredential credential;
private string organizationalUnit;
private string lastErrorCode = string.Empty;
private string lastErrorMessage;
private bool isLoggedOn = false;
public cLiamProviderExchange(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
base(LiamConfiguration, ProviderData)
{
exchangeUri = ProviderData.RootPath;
if (!string.IsNullOrEmpty(ProviderData.GroupPath))
organizationalUnit = ProviderData.GroupPath;
else
organizationalUnit = ProviderData.Domain;
// Credential erstellen
var securePassword = new SecureString();
foreach (char c in ProviderData.Credential.Secret)
{
securePassword.AppendChar(c);
}
credential = new PSCredential(ProviderData.Credential.Identification, securePassword);
// ExchangeManager initialisieren
exchangeManager = new ExchangeManager(this, exchangeUri, credential, ProviderData.Domain, organizationalUnit);
// AD-Zugriff initialisieren
var LI = new cNtfsLogonInfo()
{
Domain = Domain,
User = Credential?.Identification,
UserSecret = Credential?.Secret,
TargetGroupPath = this.GroupPath
};
// Asynchrone Initialisierung starten
_ = activeDirectoryBase.LogonAsync(LI).ConfigureAwait(false);
}
///
/// Extrahiert den GUID-Wert aus den Properties.
/// Zunächst wird versucht, "objectGUID" zu lesen – ist dieser leer, wird "GUID" verwendet.
///
internal static string ExtractObjectGuid(dynamic properties)
{
// Erstversuch: objectGUID (wie in AD)
var value = properties["objectGUID"]?.Value;
if (value == null || string.IsNullOrEmpty(value.ToString()))
{
// Alternative: GUID (wie von den Exchange-Cmdlets zurückgegeben)
value = properties["GUID"]?.Value;
}
if (value is byte[] guidBytes)
return new Guid(guidBytes).ToString();
if (value is Guid guid)
return guid.ToString();
return value?.ToString() ?? string.Empty;
}
public string GetLastErrorCode()
{
return lastErrorCode;
}
private void ClearLastError()
{
lastErrorCode = string.Empty;
lastErrorMessage = string.Empty;
}
private void SetLastError(string code, string message)
{
lastErrorCode = string.IsNullOrWhiteSpace(code) ? "EXCH_UNKNOWN_ERROR" : code;
lastErrorMessage = message ?? string.Empty;
LogEntry($"[{lastErrorCode}] {lastErrorMessage}", LogLevels.Error);
}
public override async Task LogonAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
ClearLastError();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
SetLastError("EXCH_LOGON_LICENSE_INVALID", "License not valid or Exchange module not licensed");
return false;
}
try
{
var testMailboxes = exchangeManager.GetSharedMailboxes(
"Name -like '*'",
out string errorCode,
out string errorMessage);
if (testMailboxes == null)
{
SetLastError(errorCode, $"Failed to connect to Exchange: {errorMessage}");
isLoggedOn = false;
return false;
}
if (testMailboxes != null)
{
LogEntry("Successfully connected to Exchange", LogLevels.Info);
isLoggedOn = true;
ClearLastError();
return true;
}
}
catch (Exception ex)
{
LogException(ex);
SetLastError("EXCH_LOGON_EXCEPTION", $"Failed to connect to Exchange: {ex.Message}");
isLoggedOn = false;
return false;
}
SetLastError("EXCH_LOGON_FAILED", "Unknown error connecting to Exchange");
return false;
}
catch (Exception E)
{
LogException(E);
SetLastError("EXCH_LOGON_EXCEPTION", $"Exception during Exchange logon: {E.Message}");
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public override string GetLastErrorMessage()
{
return lastErrorMessage;
}
public override async Task> getDataAreasAsync(int MaxDepth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
ClearLastError();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
SetLastError("EXCH_GET_DATAAREAS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
return new List();
}
if (!isLoggedOn && !await LogonAsync())
return null;
var DataAreas = new List();
// Shared Mailboxes
var sharedMailboxes = exchangeManager.GetSharedMailboxes(
null,
out string sharedErrorCode,
out string sharedErrorMessage);
if (sharedMailboxes == null)
{
SetLastError(sharedErrorCode, $"Failed to read shared mailboxes: {sharedErrorMessage}");
return null;
}
foreach (var mailbox in sharedMailboxes)
{
var displayName = mailbox.Properties["DisplayName"]?.Value?.ToString();
var alias = mailbox.Properties["Alias"]?.Value?.ToString();
var primarySmtpAddress = mailbox.Properties["PrimarySmtpAddress"]?.Value?.ToString();
var objectGuid = ExtractObjectGuid(mailbox.Properties);
// Filterung via Regex
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
!Regex.Match(displayName, this.DataAreaRegEx).Success)
continue;
var exchangeMailbox = new cLiamExchangeSharedMailbox(this, displayName, primarySmtpAddress, alias, objectGuid);
await exchangeMailbox.ResolvePermissionGroupsAsync();
DataAreas.Add(exchangeMailbox);
}
// Distribution Groups
var distributionGroups = exchangeManager.GetDistributionGroups(
null,
out string distErrorCode,
out string distErrorMessage);
if (distributionGroups == null)
{
SetLastError(distErrorCode, $"Failed to read distribution groups: {distErrorMessage}");
return null;
}
foreach (var group in distributionGroups)
{
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
var alias = group.Properties["Alias"]?.Value?.ToString();
var primarySmtpAddress = group.Properties["PrimarySmtpAddress"]?.Value?.ToString();
var objectGuid = ExtractObjectGuid(group.Properties);
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
!Regex.Match(displayName, this.DataAreaRegEx).Success)
continue;
var exchangeGroup = new cLiamExchangeDistributionGroup(this, displayName, primarySmtpAddress, alias, objectGuid);
await exchangeGroup.ResolvePermissionGroupsAsync();
DataAreas.Add(exchangeGroup);
}
ClearLastError();
return DataAreas;
}
catch (Exception E)
{
LogException(E);
SetLastError("EXCH_GET_DATAAREAS_EXCEPTION", E.Message);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task LoadDataArea(string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var dataType = cLIAMHelper.getUidItem(ref UID);
if (string.IsNullOrEmpty(dataType))
return null;
if (!int.TryParse(dataType, out int dataTypeInt))
return null;
var primarySmtpAddress = cLIAMHelper.getUidItem(ref UID);
if (string.IsNullOrEmpty(primarySmtpAddress))
return null;
if (!isLoggedOn && !await LogonAsync())
return null;
switch ((eLiamDataAreaTypes)dataTypeInt)
{
case eLiamDataAreaTypes.ExchangeSharedMailbox:
return await cLiamExchangeSharedMailbox.Load(this, primarySmtpAddress);
case eLiamDataAreaTypes.ExchangeDistributionGroup:
return await cLiamExchangeDistributionGroup.Load(this, primarySmtpAddress);
default:
return null;
}
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task> getSecurityGroupsAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
ClearLastError();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
SetLastError("EXCH_GET_SECURITYGROUPS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
return new List();
}
if (!isLoggedOn && !await LogonAsync())
return null;
var securityGroups = new List();
var groups = exchangeManager.GetSecurityGroups(
groupFilter,
out string errorCode,
out string errorMessage);
if (groups == null)
{
SetLastError(errorCode, $"Failed to read security groups: {errorMessage}");
return null;
}
foreach (var group in groups)
{
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
var sid = group.Properties["Sid"]?.Value?.ToString();
var dn = group.Properties["DistinguishedName"]?.Value?.ToString();
var objectGuid = ExtractObjectGuid(group.Properties);
if (!string.IsNullOrEmpty(this.GroupRegEx) &&
!Regex.Match(displayName, this.GroupRegEx).Success)
continue;
var securityGroup = new cLiamExchangeSecurityGroup(this, displayName, sid, dn, objectGuid);
securityGroups.Add(securityGroup);
}
ClearLastError();
return securityGroups;
}
catch (Exception E)
{
LogException(E);
SetLastError("EXCH_GET_SECURITYGROUPS_EXCEPTION", E.Message);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
// Hilfsmethoden zur Interaktion mit Exchange
internal async Task AddMemberToGroup(string groupName, string member, bool isSharedMailbox)
{
try
{
if (isSharedMailbox)
exchangeManager.AddMailboxPermission(groupName, member);
else
exchangeManager.AddMemberToDistributionGroup(groupName, member);
return true;
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Error adding member to group: {ex.Message}";
return false;
}
}
internal async Task RemoveMemberFromGroup(string groupName, string member, bool isSharedMailbox)
{
try
{
if (isSharedMailbox)
exchangeManager.RemoveMailboxPermission(groupName, member);
else
exchangeManager.RemoveMemberFromDistributionGroup(groupName, member);
return true;
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Error removing member from group: {ex.Message}";
return false;
}
}
public async Task GetManagedByGroup(string groupDn)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (activeDirectoryBase.adContext == null)
{
LogEntry("Active Directory context not initialized", LogLevels.Error);
return null;
}
string ldapPath = $"LDAP://{groupDn}";
DirectoryEntry groupEntry = null;
try
{
groupEntry = new DirectoryEntry(
ldapPath,
this.Credential?.Identification,
this.Credential?.Secret,
AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
if (groupEntry.Properties.Contains("managedBy") && groupEntry.Properties["managedBy"].Value != null)
{
string managedByDn = groupEntry.Properties["managedBy"].Value.ToString();
string managedByLdapPath = $"LDAP://{managedByDn}";
using (DirectoryEntry managedByEntry = new DirectoryEntry(
managedByLdapPath,
this.Credential?.Identification,
this.Credential?.Secret,
AuthenticationTypes.Secure | AuthenticationTypes.Sealing))
{
if (managedByEntry.SchemaClassName == "group")
{
byte[] sidBytes = (byte[])managedByEntry.Properties["objectSid"].Value;
SecurityIdentifier sid = new SecurityIdentifier(sidBytes, 0);
string displayName = managedByEntry.Properties["displayName"]?.Value?.ToString()
?? managedByEntry.Properties["name"]?.Value?.ToString();
return new cLiamExchangeSecurityGroup(this, displayName, sid.Value, managedByDn, sid.Value);
}
}
}
}
catch (Exception ex)
{
LogException(ex);
}
finally
{
groupEntry?.Dispose();
}
return null;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cLiamExchangeSecurityGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string sid = null;
public readonly string dn = null;
// objectGuid wird nun als TechnicalName genutzt
public cLiamExchangeSecurityGroup(cLiamProviderExchange Provider, string displayName, string sid, string dn, string objectGuid) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = displayName;
this.DisplayName = displayName;
this.UID = sid;
this.sid = sid;
this.dn = dn;
}
public override Task> getChildrenAsync(int Depth = -1)
{
return Task.FromResult(new List());
}
}
public class cLiamExchangeSharedMailbox : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string PrimarySmtpAddress = null;
public readonly string Alias = null;
public string OwnerGroupIdentifier = "S-1-0-0";
public string FullAccessGroupSid = "S-1-0-0";
public string SendAsGroupSid = "S-1-0-0";
// objectGuid wird für TechnicalName genutzt
public cLiamExchangeSharedMailbox(cLiamProviderExchange Provider, string displayName, string primarySmtpAddress, string alias, string objectGuid) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = objectGuid;
this.DisplayName = displayName;
this.PrimarySmtpAddress = primarySmtpAddress;
this.Alias = alias;
this.UID = getUID(primarySmtpAddress);
this.Level = 0;
this.DataType = eLiamDataAreaTypes.ExchangeSharedMailbox;
this.SupportsOwners = true;
this.SupportsPermissions = true;
}
internal static string getUID(string primarySmtpAddress)
{
return $"{(int)eLiamDataAreaTypes.ExchangeSharedMailbox}|{primarySmtpAddress}";
}
public static async Task Load(cLiamProviderExchange Provider, string primarySmtpAddress)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var mailbox = Provider.exchangeManager.GetSharedMailboxByAddress(primarySmtpAddress);
if (mailbox == null)
return null;
var displayName = mailbox.Properties["DisplayName"]?.Value?.ToString();
var alias = mailbox.Properties["Alias"]?.Value?.ToString();
var objectGuid = cLiamProviderExchange.ExtractObjectGuid(mailbox.Properties);
var mailboxDataArea = new cLiamExchangeSharedMailbox(Provider, displayName, primarySmtpAddress, alias, objectGuid);
await mailboxDataArea.ResolvePermissionGroupsAsync();
return mailboxDataArea;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var members = Provider.exchangeManager.GetMailboxPermissionMembers(this.TechnicalName);
if (members == null)
return new List();
var ownersList = new List();
foreach (var member in members)
{
var userInfo = new cLiamUserInfo
{
DisplayName = member.Properties["DisplayName"]?.Value?.ToString(),
UserPrincipalName = member.Properties["UserPrincipalName"]?.Value?.ToString(),
EMail = member.Properties["PrimarySmtpAddress"]?.Value?.ToString(),
SID = member.Properties["Sid"]?.Value?.ToString()
};
ownersList.Add(userInfo);
}
return ownersList;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
bool success = false;
switch (Role)
{
case eLiamAccessRoles.Owner:
success = await Provider.AddMemberToGroup(this.DisplayName, User.UserPrincipalName, true);
break;
case eLiamAccessRoles.Write:
success = await Provider.exchangeManager.AddSendAsPermission(this.DisplayName, User.UserPrincipalName);
break;
default:
LogEntry($"Unsupported permission role for Exchange mailbox: {Role}", LogLevels.Warning);
return new cLiamPermissionResult { Valid = false };
}
return new cLiamPermissionResult
{
Valid = success,
UserReference = User.UserPrincipalName
};
}
catch (Exception E)
{
LogException(E);
return new cLiamPermissionResult { Valid = false };
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
bool success = false;
switch (Role)
{
case eLiamAccessRoles.Owner:
success = await Provider.RemoveMemberFromGroup(this.DisplayName, User.UserPrincipalName, true);
break;
case eLiamAccessRoles.Write:
success = await Provider.exchangeManager.RemoveSendAsPermission(this.DisplayName, User.UserPrincipalName);
break;
default:
LogEntry($"Unsupported permission role for Exchange mailbox: {Role}", LogLevels.Warning);
return false;
}
return success;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task> getChildrenAsync(int Depth = -1)
{
return new List();
}
public async Task ResolvePermissionGroupsAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var fullAccessNamingConvention = Provider.NamingConventions.FirstOrDefault(i =>
i.AccessRole == eLiamAccessRoles.ExchangeSMBFullAccess);
var sendAsNamingConvention = Provider.NamingConventions.FirstOrDefault(i =>
i.AccessRole == eLiamAccessRoles.ExchangeSMBSendAs);
if (fullAccessNamingConvention == null || sendAsNamingConvention == null)
{
LogEntry("Naming conventions for Exchange mailbox permissions not found", LogLevels.Warning);
return;
}
try
{
var fullAccessPermissions = Provider.exchangeManager.GetFullAccessPermissionGroups(this.TechnicalName);
if (fullAccessPermissions != null)
{
foreach (var permission in fullAccessPermissions)
{
string samAccountName = permission.Properties["SamAccountName"]?.Value?.ToString();
string sid = permission.Properties["Sid"]?.Value?.ToString();
if (!string.IsNullOrEmpty(samAccountName) && !string.IsNullOrEmpty(sid))
{
//if (Regex.IsMatch(samAccountName, fullAccessNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
this.FullAccessGroupSid = sid;
LogEntry($"Found FullAccess group {samAccountName} (SID: {sid}) for mailbox {this.DisplayName}", LogLevels.Debug);
string dn = permission.Properties["DistinguishedName"]?.Value?.ToString();
if (!string.IsNullOrEmpty(dn))
{
var managedByGroup = await Provider.GetManagedByGroup(dn);
if (managedByGroup != null)
{
this.OwnerGroupIdentifier = managedByGroup.sid;
LogEntry($"Found owner group {managedByGroup.TechnicalName} (SID: {managedByGroup.sid}) for mailbox {this.DisplayName}", LogLevels.Debug);
}
}
}
}
}
}
var sendAsPermissions = Provider.exchangeManager.GetSendAsPermissionGroups(this.TechnicalName);
if (sendAsPermissions != null)
{
foreach (var permission in sendAsPermissions)
{
string recipientType = permission.Properties["RecipientType"]?.Value?.ToString();
string samAccountName = permission.Properties["SamAccountName"]?.Value?.ToString();
string sid = permission.Properties["Sid"]?.Value?.ToString();
if (!string.IsNullOrEmpty(samAccountName) && !string.IsNullOrEmpty(sid))
{
//if (Regex.IsMatch(samAccountName, sendAsNamingConvention.Wildcard, RegexOptions.IgnoreCase))
{
this.SendAsGroupSid = sid;
LogEntry($"Found SendAs group {samAccountName} (SID: {sid}) for mailbox {this.DisplayName}", LogLevels.Debug);
}
}
}
}
}
catch (Exception ex)
{
LogException(ex);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
}
public class cLiamExchangeDistributionGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string PrimarySmtpAddress = null;
public readonly string Alias = null;
public string OwnerGroupIdentifier = "S-1-0-0";
public string MemberGroupSid = "S-1-0-0";
// objectGuid wird als TechnicalName gesetzt
public cLiamExchangeDistributionGroup(cLiamProviderExchange Provider, string displayName, string primarySmtpAddress, string alias, string objectGuid) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = objectGuid;
this.DisplayName = displayName;
this.PrimarySmtpAddress = primarySmtpAddress;
this.Alias = alias;
this.UID = getUID(primarySmtpAddress);
this.Level = 0;
this.DataType = eLiamDataAreaTypes.ExchangeDistributionGroup;
this.SupportsOwners = true;
this.SupportsPermissions = true;
}
internal static string getUID(string primarySmtpAddress)
{
return $"{(int)eLiamDataAreaTypes.ExchangeDistributionGroup}|{primarySmtpAddress}";
}
public static async Task Load(cLiamProviderExchange Provider, string primarySmtpAddress)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var group = Provider.exchangeManager.GetDistributionGroupByAddress(primarySmtpAddress);
if (group == null)
return null;
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
var alias = group.Properties["Alias"]?.Value?.ToString();
var objectGuid = cLiamProviderExchange.ExtractObjectGuid(group.Properties);
var groupDataArea = new cLiamExchangeDistributionGroup(Provider, displayName, primarySmtpAddress, alias, objectGuid);
await groupDataArea.ResolvePermissionGroupsAsync();
return groupDataArea;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var members = Provider.exchangeManager.GetDistributionGroupMembers(this.TechnicalName);
if (members == null)
return new List();
var membersList = new List();
foreach (var member in members)
{
var userInfo = new cLiamUserInfo
{
DisplayName = member.Properties["DisplayName"]?.Value?.ToString(),
UserPrincipalName = member.Properties["UserPrincipalName"]?.Value?.ToString(),
EMail = member.Properties["PrimarySmtpAddress"]?.Value?.ToString(),
SID = member.Properties["Sid"]?.Value?.ToString()
};
membersList.Add(userInfo);
}
return membersList;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (Role != eLiamAccessRoles.Owner)
{
LogEntry($"Only Owner role is supported for distribution groups, requested: {Role}", LogLevels.Warning);
return new cLiamPermissionResult { Valid = false };
}
bool success = await Provider.AddMemberToGroup(this.DisplayName, User.UserPrincipalName, false);
return new cLiamPermissionResult
{
Valid = success,
UserReference = User.UserPrincipalName
};
}
catch (Exception E)
{
LogException(E);
return new cLiamPermissionResult { Valid = false };
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (Role != eLiamAccessRoles.Owner)
{
LogEntry($"Only Owner role is supported for distribution groups, requested: {Role}", LogLevels.Warning);
return false;
}
return await Provider.RemoveMemberFromGroup(this.DisplayName, User.UserPrincipalName, false);
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task> getChildrenAsync(int Depth = -1)
{
return new List();
}
public async Task ResolvePermissionGroupsAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var namingConvention = Provider.NamingConventions
.FirstOrDefault(nc => nc.AccessRole == eLiamAccessRoles.ExchangeMLMember);
if (namingConvention == null)
{
LogEntry("Naming convention for DL-Member not found", LogLevels.Warning);
return;
}
try
{
// ruft alle Gruppen auf dem DL ab
var memberGroups = Provider.exchangeManager
.GetDistributionGroupMembers(this.TechnicalName);
foreach (var group in memberGroups)
{
var sam = group.Properties["SamAccountName"]?.Value?.ToString();
var sid = group.Properties["Sid"]?.Value?.ToString();
if (string.IsNullOrEmpty(sam) || string.IsNullOrEmpty(sid))
continue;
// falls gewünscht: Filter nach Namenskonvention
// if (!Regex.IsMatch(sam, namingConvention.Wildcard, RegexOptions.IgnoreCase))
// continue;
// hier beispielsweise in eine List MemberGroupSids aufnehmen
this.MemberGroupSid = sid;
LogEntry($"Found DL-member group {sam} (SID: {sid}) for distribution list {this.DisplayName}", LogLevels.Debug);
// optional: falls die Gruppe ein ManagedBy hat
var dn = group.Properties["DistinguishedName"]?.Value?.ToString();
if (!string.IsNullOrEmpty(dn))
{
var mgr = await Provider.GetManagedByGroup(dn);
if (mgr != null)
{
this.OwnerGroupIdentifier = mgr.sid;
LogEntry($"Found owner group {mgr.TechnicalName} (SID: {mgr.sid}) for distribution list {this.DisplayName}", LogLevels.Debug);
}
}
}
}
catch (Exception ex)
{
LogException(ex);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
}
}
}