This commit is contained in:
Drechsler, Meik
2025-10-15 14:56:07 +02:00
commit f563d78417
896 changed files with 654481 additions and 0 deletions

View File

@@ -0,0 +1,898 @@
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 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);
}
/// <summary>
/// Extrahiert den GUID-Wert aus den Properties.
/// Zunächst wird versucht, "objectGUID" zu lesen ist dieser leer, wird "GUID" verwendet.
/// </summary>
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 override async Task<bool> LogonAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry("Error: License not valid or Exchange module not licensed", LogLevels.Error);
lastErrorMessage = "License not valid or Exchange module not licensed";
return false;
}
try
{
var testMailboxes = exchangeManager.GetSharedMailboxes("Name -like '*'");
if (testMailboxes != null)
{
LogEntry("Successfully connected to Exchange", LogLevels.Info);
isLoggedOn = true;
return true;
}
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Failed to connect to Exchange: {ex.Message}";
isLoggedOn = false;
return false;
}
lastErrorMessage = "Unknown error connecting to Exchange";
return false;
}
catch (Exception E)
{
LogException(E);
lastErrorMessage = $"Exception during Exchange logon: {E.Message}";
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public override string GetLastErrorMessage()
{
return lastErrorMessage;
}
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int MaxDepth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry("Error: License not valid or Exchange module not licensed", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!isLoggedOn && !await LogonAsync())
return null;
var DataAreas = new List<cLiamDataAreaBase>();
// Shared Mailboxes
try
{
var sharedMailboxes = exchangeManager.GetSharedMailboxes();
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);
DataAreas.Add(exchangeMailbox);
}
}
catch (Exception ex)
{
LogException(ex);
}
// Distribution Groups
try
{
var distributionGroups = exchangeManager.GetDistributionGroups();
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);
DataAreas.Add(exchangeGroup);
}
}
catch (Exception ex)
{
LogException(ex);
}
return DataAreas;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamDataAreaBase> 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<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry("Error: License not valid or Exchange module not licensed", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!isLoggedOn && !await LogonAsync())
return null;
var securityGroups = new List<cLiamDataAreaBase>();
try
{
var groups = exchangeManager.GetSecurityGroups(groupFilter);
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);
}
}
catch (Exception ex)
{
LogException(ex);
}
return securityGroups;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
// Hilfsmethoden zur Interaktion mit Exchange
internal async Task<bool> 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<bool> 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<cLiamExchangeSecurityGroup> 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<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
return Task.FromResult(new List<cLiamDataAreaBase>());
}
}
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;
_ = assignPermissionGroups(Provider).ConfigureAwait(false);
}
internal static string getUID(string primarySmtpAddress)
{
return $"{(int)eLiamDataAreaTypes.ExchangeSharedMailbox}|{primarySmtpAddress}";
}
public static async Task<cLiamExchangeSharedMailbox> 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);
return new cLiamExchangeSharedMailbox(Provider, displayName, primarySmtpAddress, alias, objectGuid);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var members = Provider.exchangeManager.GetMailboxPermissionMembers(this.TechnicalName);
if (members == null)
return new List<cLiamUserInfo>();
var ownersList = new List<cLiamUserInfo>();
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<cLiamPermissionResult> 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<bool> 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<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
return new List<cLiamDataAreaBase>();
}
private async Task assignPermissionGroups(cLiamProviderExchange Provider)
{
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;
_ = assignPermissionGroups(Provider).ConfigureAwait(false);
}
internal static string getUID(string primarySmtpAddress)
{
return $"{(int)eLiamDataAreaTypes.ExchangeDistributionGroup}|{primarySmtpAddress}";
}
public static async Task<cLiamExchangeDistributionGroup> 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);
return new cLiamExchangeDistributionGroup(Provider, displayName, primarySmtpAddress, alias, objectGuid);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var members = Provider.exchangeManager.GetDistributionGroupMembers(this.TechnicalName);
if (members == null)
return new List<cLiamUserInfo>();
var membersList = new List<cLiamUserInfo>();
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<cLiamPermissionResult> 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<bool> 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<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
return new List<cLiamDataAreaBase>();
}
private async Task assignPermissionGroups(cLiamProviderExchange Provider)
{
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<string> 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);
}
}
}
}

View File

@@ -0,0 +1,726 @@
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;
namespace C4IT.LIAM
{
public static class LiamInitializer
{
static public cLiamProviderBase CreateInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
{
return new cLiamProviderExchange(LiamConfiguration, ProviderData);
}
}
public class cLiamProviderExchange : cLiamProviderBase
{
public static Guid exchangeModuleId = new Guid("A1E213C3-6517-EA11-4881-000C2980FD95");
internal readonly ExchangeManager exchangeManager;
private string exchangeUri;
private PSCredential credential;
private string organizationalUnit;
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;
// Use the credential from the provider data
var securePassword = new SecureString();
foreach (char c in ProviderData.Credential.Secret)
{
securePassword.AppendChar(c);
}
credential = new PSCredential(ProviderData.Credential.Identification, securePassword);
// Create the Exchange manager
exchangeManager = new ExchangeManager(exchangeUri, credential, organizationalUnit);
}
public override async Task<bool> LogonAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid /*|| !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(exchangeModuleId)*/)
{
LogEntry($"Error: License not valid or Exchange module not licensed", LogLevels.Error);
lastErrorMessage = "License not valid or Exchange module not licensed";
return false;
}
// Test connection by getting a simple list
try
{
var testMailboxes = exchangeManager.GetSharedMailboxes("Name -like '*'");
if (testMailboxes != null)
{
LogEntry($"Successfully connected to Exchange", LogLevels.Info);
isLoggedOn = true;
return true;
}
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Failed to connect to Exchange: {ex.Message}";
isLoggedOn = false;
return false;
}
lastErrorMessage = "Unknown error connecting to Exchange";
return false;
}
catch (Exception E)
{
LogException(E);
lastErrorMessage = $"Exception during Exchange logon: {E.Message}";
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public override string GetLastErrorMessage()
{
return lastErrorMessage;
}
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int MaxDepth = -1)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid /*|| !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(exchangeModuleId)*/)
{
LogEntry($"Error: License not valid or Exchange module not licensed", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!isLoggedOn && !await LogonAsync())
return null;
var DataAreas = new List<cLiamDataAreaBase>();
// Get Shared Mailboxes
try
{
var sharedMailboxes = exchangeManager.GetSharedMailboxes();
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();
// Skip if it doesn't match the regex filter (if provided)
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
!System.Text.RegularExpressions.Regex.Match(displayName, this.DataAreaRegEx).Success)
continue;
var exchangeMailbox = new cLiamExchangeSharedMailbox(this, displayName, primarySmtpAddress, alias);
DataAreas.Add(exchangeMailbox);
}
}
catch (Exception ex)
{
LogException(ex);
}
// Get Distribution Groups
try
{
var distributionGroups = exchangeManager.GetDistributionGroups();
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();
// Skip if it doesn't match the regex filter (if provided)
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
!System.Text.RegularExpressions.Regex.Match(displayName, this.DataAreaRegEx).Success)
continue;
var exchangeGroup = new cLiamExchangeDistributionGroup(this, displayName, primarySmtpAddress, alias);
DataAreas.Add(exchangeGroup);
}
}
catch (Exception ex)
{
LogException(ex);
}
return DataAreas;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
public override async Task<cLiamDataAreaBase> LoadDataArea(string UID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var dataType = cLIAMHelper.getUidItem(ref UID);
if (string.IsNullOrEmpty(dataType))
return null;
int dataTypeInt;
if (!int.TryParse(dataType, out 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<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (!cC4ITLicenseM42ESM.Instance.IsValid /*|| !cC4ITLicenseM42ESM.Instance.Modules.ContainsKey(exchangeModuleId)*/)
{
LogEntry($"Error: License not valid or Exchange module not licensed", LogLevels.Error);
return new List<cLiamDataAreaBase>();
}
if (!isLoggedOn && !await LogonAsync())
return null;
// For Exchange, we need to use the same AD security groups as from the AD provider
// This is just a placeholder implementation to return some groups from the exchange environment
var securityGroups = new List<cLiamDataAreaBase>();
try
{
// Use the Exchange PowerShell to get AD groups
var groups = exchangeManager.GetSecurityGroups(groupFilter);
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();
// Skip if it doesn't match the regex filter (if provided)
if (!string.IsNullOrEmpty(this.GroupRegEx) &&
!System.Text.RegularExpressions.Regex.Match(displayName, this.GroupRegEx).Success)
continue;
var securityGroup = new cLiamExchangeSecurityGroup(this, displayName, sid, dn);
securityGroups.Add(securityGroup);
}
}
catch (Exception ex)
{
LogException(ex);
}
return securityGroups;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
// Helper methods to interact with Exchange
internal async Task<bool> CreateSharedMailbox(string displayName, string alias, string ownerGroupName, string writeGroupName)
{
try
{
exchangeManager.CreateSharedMailbox(displayName, alias, null);
// Create the owner (FullAccess) and write (SendAs) groups if they don't exist already
exchangeManager.CreateSecurityGroup(ownerGroupName, $"{displayName} Full Access");
exchangeManager.CreateSecurityGroup(writeGroupName, $"{displayName} Send As");
// Grant permissions to the groups
exchangeManager.AddMailboxPermission(displayName, ownerGroupName, "FullAccess");
exchangeManager.AddSendAsPermission(displayName, writeGroupName);
return true;
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Error creating shared mailbox: {ex.Message}";
return false;
}
}
internal async Task<bool> CreateDistributionGroup(string displayName, string alias, List<string> initialMembers = null)
{
try
{
exchangeManager.CreateDistributionGroup(displayName, alias, initialMembers);
return true;
}
catch (Exception ex)
{
LogException(ex);
lastErrorMessage = $"Error creating distribution group: {ex.Message}";
return false;
}
}
internal async Task<bool> 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<bool> 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 class cLiamExchangeSecurityGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string sid = null;
public readonly string dn = null;
public cLiamExchangeSecurityGroup(cLiamProviderExchange Provider, string displayName, string sid, string dn) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = displayName;
this.UID = sid;
this.sid = sid;
this.dn = dn;
}
public override Task<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
// Security groups don't have children in this context
return Task.FromResult(new List<cLiamDataAreaBase>());
}
}
public class cLiamExchangeSharedMailbox : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string PrimarySmtpAddress = null;
public readonly string Alias = null;
public string OwnerGroupIdentifier = null; // Full Access group
public string WriteGroupIdentifier = null; // Send As group
public cLiamExchangeSharedMailbox(cLiamProviderExchange Provider, string displayName, string primarySmtpAddress, string alias) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = displayName;
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;
// Set standard naming convention for access groups
// These will be resolved to actual groups later as needed
this.OwnerGroupIdentifier = $"EXCH_FA_{alias}"; // Full Access group
this.WriteGroupIdentifier = $"EXCH_SA_{alias}"; // Send As group
}
internal static string getUID(string primarySmtpAddress)
{
return $"{(int)eLiamDataAreaTypes.ExchangeSharedMailbox}|{primarySmtpAddress}";
}
public static async Task<cLiamExchangeSharedMailbox> Load(cLiamProviderExchange Provider, string primarySmtpAddress)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Get the mailbox details from Exchange
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();
return new cLiamExchangeSharedMailbox(Provider, displayName, primarySmtpAddress, alias);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Get members of the Full Access group
var members = Provider.exchangeManager.GetMailboxPermissionMembers(this.DisplayName);
if (members == null)
return new List<cLiamUserInfo>();
var ownersList = new List<cLiamUserInfo>();
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<cLiamPermissionResult> GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
bool success = false;
switch (Role)
{
case eLiamAccessRoles.Owner:
// Add to Full Access group
success = await Provider.AddMemberToGroup(this.DisplayName, User.UserPrincipalName, true);
break;
case eLiamAccessRoles.Write:
// Add Send As permission
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<bool> RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
bool success = false;
switch (Role)
{
case eLiamAccessRoles.Owner:
// Remove from Full Access group
success = await Provider.RemoveMemberFromGroup(this.DisplayName, User.UserPrincipalName, true);
break;
case eLiamAccessRoles.Write:
// Remove Send As permission
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<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
// Shared mailboxes don't have children in this context
return new List<cLiamDataAreaBase>();
}
}
public class cLiamExchangeDistributionGroup : cLiamDataAreaBase
{
public new readonly cLiamProviderExchange Provider = null;
public readonly string PrimarySmtpAddress = null;
public readonly string Alias = null;
public cLiamExchangeDistributionGroup(cLiamProviderExchange Provider, string displayName, string primarySmtpAddress, string alias) : base(Provider)
{
this.Provider = Provider;
this.TechnicalName = displayName;
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<cLiamExchangeDistributionGroup> Load(cLiamProviderExchange Provider, string primarySmtpAddress)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Get the group details from Exchange
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();
return new cLiamExchangeDistributionGroup(Provider, displayName, primarySmtpAddress, alias);
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public override async Task<List<cLiamUserInfo>> GetOwnersAsync()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Get members of the distribution group
var members = Provider.exchangeManager.GetDistributionGroupMembers(this.DisplayName);
if (members == null)
return new List<cLiamUserInfo>();
var membersList = new List<cLiamUserInfo>();
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<cLiamPermissionResult> GrantPermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// For distribution groups, we only support adding members (which is essentially Owner role)
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<bool> RevokePermissionAsync(cLiamUserInfo User, eLiamAccessRoles Role)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// For distribution groups, we only support removing members (which is essentially Owner role)
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<List<cLiamDataAreaBase>> getChildrenAsync(int Depth = -1)
{
// Distribution groups don't have children in this context
return new List<cLiamDataAreaBase>();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,671 @@
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;
namespace C4IT.LIAM
{
/// <summary>
/// Manages Exchange operations using PowerShell remoting
/// </summary>
public class ExchangeManager
{
private readonly string _exchangeUri;
private readonly PSCredential _credential;
private readonly string _organizationalUnit;
/// <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(string exchangeUri, PSCredential credential, string organizationalUnit)
{
_exchangeUri = exchangeUri;
_credential = credential;
_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);
// Set authentication mechanism to Kerberos by default
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
var runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
return runspace;
}
catch (Exception ex)
{
LogException(ex);
throw;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Creates a distribution group (mailing list). Optionally members can be added initially.
/// </summary>
/// <param name="name">Name of the group</param>
/// <param name="alias">Alias of the group</param>
/// <param name="initialMembers">List of members to be added to the group (optional)</param>
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;
// Create the distribution group
ps.AddCommand("New-DistributionGroup")
.AddParameter("Name", name)
.AddParameter("Alias", alias)
.AddParameter("OrganizationalUnit", _organizationalUnit);
ps.Invoke();
// Add initial members if specified
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
/// </summary>
/// <param name="name">Name of the security group</param>
/// <param name="description">Description of the security group</param>
/// <returns>True if successful</returns>
public bool CreateSecurityGroup(string name, string description)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
// Create the security group using New-ADGroup cmdlet
ps.AddCommand("New-ADGroup")
.AddParameter("Name", name)
.AddParameter("GroupScope", "Universal")
.AddParameter("GroupCategory", "Security")
.AddParameter("DisplayName", name)
.AddParameter("Path", _organizationalUnit)
.AddParameter("Description", description);
var result = ps.Invoke();
return result.Count > 0;
}
}
catch (Exception ex)
{
LogException(ex);
return false;
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets all shared mailboxes matching an optional filter
/// </summary>
/// <param name="filter">Optional filter string</param>
/// <returns>Collection of shared mailboxes as PSObjects</returns>
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>
/// <param name="primarySmtpAddress">The primary SMTP address of the mailbox</param>
/// <returns>The mailbox as a PSObject, or null if not found</returns>
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>
/// <param name="filter">Optional filter string</param>
/// <returns>Collection of distribution groups as PSObjects</returns>
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
/// </summary>
/// <param name="primarySmtpAddress">The primary SMTP address of the group</param>
/// <returns>The distribution group as a PSObject, or null if not found</returns>
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>
/// <param name="groupName">The name of the distribution group</param>
/// <returns>Collection of members as PSObjects</returns>
public IEnumerable<PSObject> GetDistributionGroupMembers(string groupName)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-DistributionGroupMember")
.AddParameter("Identity", groupName);
return ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Gets users who have permissions on a mailbox
/// </summary>
/// <param name="mailboxName">The name of the mailbox</param>
/// <returns>Collection of users as PSObjects</returns>
public IEnumerable<PSObject> GetMailboxPermissionMembers(string mailboxName)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-MailboxPermission")
.AddParameter("Identity", mailboxName)
.AddParameter("AccessRights", "FullAccess");
// Filter out default permissions like NT AUTHORITY\SELF
var results = ps.Invoke().Where(p =>
!p.Properties["User"].Value.ToString().Contains("NT AUTHORITY") &&
!p.Properties["User"].Value.ToString().Contains("Administrator"));
// Now, get the full user objects for each permission
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>
/// Gets security groups matching a filter
/// </summary>
/// <param name="filter">LDAP filter to match groups</param>
/// <returns>Collection of security groups as PSObjects</returns>
public IEnumerable<PSObject> GetSecurityGroups(string filter)
{
LogMethodBegin(MethodBase.GetCurrentMethod());
try
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Get-ADGroup")
.AddParameter("Filter", filter)
.AddParameter("Properties", new string[] { "DisplayName", "DistinguishedName", "Sid" });
return ps.Invoke();
}
}
catch (Exception ex)
{
LogException(ex);
return Enumerable.Empty<PSObject>();
}
finally
{
LogMethodEnd(MethodBase.GetCurrentMethod());
}
}
/// <summary>
/// Adds a member to a distribution group
/// </summary>
/// <param name="groupName">Name of the distribution group</param>
/// <param name="member">User to be added as a member</param>
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>
/// <param name="groupName">Name of the distribution group</param>
/// <param name="member">User to be removed</param>
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>
/// <param name="mailboxName">Name of the mailbox</param>
/// <param name="user">User or group to be granted permission</param>
/// <param name="accessRight">Access right (default: FullAccess)</param>
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>
/// <param name="mailboxName">Name of the mailbox</param>
/// <param name="user">User or group to have permission removed</param>
/// <param name="accessRight">Access right (default: FullAccess)</param>
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>
/// <param name="mailboxName">Name of the mailbox</param>
/// <param name="user">User or group to be granted permission</param>
/// <returns>True if successful</returns>
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>
/// <param name="mailboxName">Name of the mailbox</param>
/// <param name="user">User or group to have permission removed</param>
/// <returns>True if successful</returns>
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>
/// <param name="name">Name of the mailbox</param>
/// <param name="alias">Alias of the mailbox</param>
/// <param name="initialMembers">List of users to be added as access rights (optional)</param>
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;
// Create new shared mailbox
ps.AddCommand("New-Mailbox")
.AddParameter("Name", name)
.AddParameter("Alias", alias)
.AddParameter("Shared", true)
.AddParameter("OrganizationalUnit", _organizationalUnit);
ps.Invoke();
// Add initial members if specified
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());
}
}
}
}

View File

@@ -0,0 +1,380 @@
using System;
using System.Linq;
using System.Management.Automation;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.DirectoryServices;
using System.Diagnostics;
using System.Threading;
using System.Management.Automation.Runspaces;
using System.Security.Principal;
namespace C4IT.LIAM
{
public partial class ExchangeManager
{
/// <summary>
/// Stellt sicher, dass eine AD-Sicherheitsgruppe für den angegebenen AccessRole existiert (erstellt sie falls nicht)
/// und wartet optional, bis die Replikation abgeschlossen ist.
/// Liefert den tatsächlichen Gruppennamen zurück.
/// </summary>
private string EnsureSecurityGroup(eLiamAccessRoles accessRole, string baseName)
{
const int MaxLoop = 50; // Abbruchbedingung: nach 50 Versuchen abbrechen
// 1. Namenskonvention für diese Rolle finden
var namingConvention = _provider.NamingConventions
.FirstOrDefault(nc => nc.AccessRole == accessRole);
if (namingConvention == null)
throw new InvalidOperationException($"Keine Namenskonvention für Rolle '{accessRole}' gefunden.");
// 2. Benötigte CustomTags aus dem Provider ziehen
// - Prefix (z.B. "ACL")
// - GROUPTYPEPOSTFIX (z.B. "ExchangeMLMember")
_provider.CustomTags.TryGetValue("ADGroupPrefix", out var prefix);
_provider.CustomTags.TryGetValue(accessRole.ToString(), out var typePostfix);
// 3. Schleife für _LOOP hochzählen, bis ein einzigartiger Name gefunden ist
string groupName = null;
string description = null;
for (int loop = 0; loop <= MaxLoop; loop++)
{
// nur einfügen, wenn loop > 0
var loopPart = loop > 0 ? $"_{loop}" : string.Empty;
// Platzhalter im Template ersetzen
groupName = namingConvention.NamingTemplate
.Replace("{{ADGroupPrefix}}", prefix ?? string.Empty)
.Replace("{{NAME}}", baseName)
.Replace("{{_LOOP}}", loopPart)
.Replace("{{GROUPTYPEPOSTFIX}}", typePostfix ?? string.Empty);
description = namingConvention.DescriptionTemplate
.Replace("{{ADGroupPrefix}}", prefix ?? string.Empty)
.Replace("{{NAME}}", baseName)
.Replace("{{_LOOP}}", loopPart)
.Replace("{{GROUPTYPEPOSTFIX}}", typePostfix ?? string.Empty);
// Existenz prüfen
bool exists = GetSecurityGroups(groupName)
.Any(g => string.Equals(
g.Properties["sAMAccountName"]?.Value?.ToString(),
groupName,
StringComparison.OrdinalIgnoreCase));
if (!exists)
break; // Name ist frei raus aus der Schleife
if (loop == MaxLoop)
throw new InvalidOperationException(
$"Konnte nach {MaxLoop} Versuchen keinen eindeutigen Gruppennamen für '{baseName}' erzeugen.");
}
// 4. Gruppen-Scope-Bit setzen
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));
// 5. Gruppe im AD anlegen
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;
if(!string.IsNullOrEmpty(description))
{
newGroup.Properties["description"].Value = description;
}
newGroup.CommitChanges();
}
// 6. Auf Replikation warten (optional)
const int replicationTimeoutMinutes = 2;
if (!WaitForGroupReplication(groupName, TimeSpan.FromMinutes(replicationTimeoutMinutes)))
{
throw new TimeoutException(
$"Die AD-Gruppe '{groupName}' konnte innerhalb von {replicationTimeoutMinutes} Minuten nicht repliziert werden.");
}
return groupName;
}
/// <summary>
/// Wartet darauf, dass die Gruppe nach der Erstellung im AD repliziert ist.
/// </summary>
private bool WaitForGroupReplication(string groupName, TimeSpan timeout)
{
var sw = Stopwatch.StartNew();
var pollInterval = TimeSpan.FromSeconds(5);
while (sw.Elapsed < timeout)
{
var found = GetSecurityGroups(groupName)
.Any(g => string.Equals(
g.Properties["sAMAccountName"]?.Value?.ToString(),
groupName,
StringComparison.OrdinalIgnoreCase));
if (found) return true;
Thread.Sleep(pollInterval);
}
return false;
}
/// <summary>
/// Setzt das ManagedBy-Attribut einer AD-Gruppe auf eine andere Gruppe
/// mit den im Konstruktor übergebenen Credentials und Domain.
/// </summary>
private void SetManagedBy(string groupName, string managerGroup)
{
string ldapPath = $"LDAP://{_organizationalUnit}";
// SecureString -> Klartext
string password = SecureStringToString(_credential.Password);
using (var root = new DirectoryEntry(ldapPath,
_credential.UserName,
password,
AuthenticationTypes.Secure))
using (var ds = new DirectorySearcher(root))
{
// Gruppe holen
ds.Filter = $"(&(objectClass=group)(sAMAccountName={groupName}))";
var result = ds.FindOne();
if (result == null)
throw new InvalidOperationException($"Gruppe '{groupName}' nicht gefunden in {ldapPath}");
var groupEntry = result.GetDirectoryEntry();
// DistinguishedName der Manager-Gruppe ermitteln
using (var mgrSearch = new DirectorySearcher(root))
{
mgrSearch.Filter = $"(&(objectClass=group)(sAMAccountName={managerGroup}))";
var mgrResult = mgrSearch.FindOne();
if (mgrResult == null)
throw new InvalidOperationException($"Manager-Gruppe '{managerGroup}' nicht gefunden in {ldapPath}");
string managerDn = mgrResult.GetDirectoryEntry()
.Properties["distinguishedName"]
.Value
.ToString();
// Attribut setzen und speichern
groupEntry.Properties["managedBy"].Value = managerDn;
groupEntry.CommitChanges();
}
}
}
/// <summary>
/// Erstellt eine Shared Mailbox samt zugehöriger AD-Gruppen (FullAccess, SendAs, Owner) und setzt die nötigen Berechtigungen.
/// </summary>
public Tuple<Guid, List<Tuple<string, string, string, string>>> CreateSharedMailboxWithOwnershipGroups(
string name,
string alias,
string displayName = null,
string primarySmtpAddress = null)
{
CreationResult result = new CreationResult();
// Ensure AD groups
string fullAccessGroup = EnsureSecurityGroup(eLiamAccessRoles.ExchangeSMBFullAccess, name);
string sendAsGroup = EnsureSecurityGroup(eLiamAccessRoles.ExchangeSMBSendAs, name);
string ownerGroup = EnsureSecurityGroup(eLiamAccessRoles.ExchangeSMBOwner, name);
SetManagedBy(fullAccessGroup, ownerGroup);
SetManagedBy(sendAsGroup, ownerGroup);
// Create mailbox
using (Runspace rs = CreateRunspace())
{
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = rs;
ps.AddCommand("New-Mailbox");
ps.AddParameter("Name", name);
ps.AddParameter("Alias", alias);
ps.AddParameter("Shared", true);
ps.AddParameter("OrganizationalUnit", _organizationalUnit);
if (!string.IsNullOrEmpty(displayName))
ps.AddParameter("DisplayName", displayName);
if (!string.IsNullOrEmpty(primarySmtpAddress))
ps.AddParameter("PrimarySmtpAddress", primarySmtpAddress);
ps.Invoke();
AddMailboxPermission(name, fullAccessGroup, "FullAccess");
AddSendAsPermission(name, sendAsGroup).GetAwaiter().GetResult();
}
}
// Retrieve mailbox GUID
DirectoryEntry mbEntry = FindAdObject("(&(objectClass=user)(mailNickname=" + alias + "))");
if (mbEntry != null && mbEntry.Properties.Contains("objectGUID") && mbEntry.Properties["objectGUID"].Count > 0)
{
byte[] bytes = (byte[])mbEntry.Properties["objectGUID"][0];
result.ObjectGuid = new Guid(bytes);
}
// Collect group details
string[] roles = new string[] {
eLiamAccessRoles.ExchangeSMBFullAccess.ToString(),
eLiamAccessRoles.ExchangeSMBSendAs.ToString(),
eLiamAccessRoles.ExchangeSMBOwner.ToString()
};
string[] names = new string[] {
fullAccessGroup,
sendAsGroup,
ownerGroup
};
for (int i = 0; i < roles.Length; i++)
{
DirectoryEntry grpEntry = FindAdObject("(&(objectCategory=group)(sAMAccountName=" + names[i] + "))");
if (grpEntry != null && grpEntry.Properties.Contains("objectSid") && grpEntry.Properties["objectSid"].Count > 0)
{
byte[] sidBytes = (byte[])grpEntry.Properties["objectSid"][0];
string sid = new SecurityIdentifier(sidBytes, 0).Value;
string distinguishedName = grpEntry.Properties["distinguishedName"][0].ToString();
result.Groups.Add(Tuple.Create(roles[i], sid, names[i], distinguishedName));
}
}
return Tuple.Create(result.ObjectGuid, result.Groups);
}
/// <summary>
/// Erstellt eine Distribution Group samt zugehöriger AD-Gruppen (Member, Owner) und setzt die nötigen Berechtigungen.
/// </summary>
public Tuple<Guid, List<Tuple<string, string, string, string>>> CreateDistributionGroupWithOwnershipGroups(
string name,
string alias,
string displayName = null,
string primarySmtpAddress = null)
{
CreationResult result = new CreationResult();
// Ensure AD groups
string memberGroup = EnsureSecurityGroup(eLiamAccessRoles.ExchangeMLMember, name);
string ownerGroup = EnsureSecurityGroup(eLiamAccessRoles.ExchangeMLOwner, name);
SetManagedBy(memberGroup, ownerGroup);
// Create distribution group
using (Runspace rs = CreateRunspace())
{
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = rs;
ps.AddCommand("New-DistributionGroup");
ps.AddParameter("Name", name);
ps.AddParameter("Alias", alias);
ps.AddParameter("OrganizationalUnit", _organizationalUnit);
if (!string.IsNullOrEmpty(displayName))
ps.AddParameter("DisplayName", displayName);
if (!string.IsNullOrEmpty(primarySmtpAddress))
ps.AddParameter("PrimarySmtpAddress", primarySmtpAddress);
ps.Invoke();
// b) GUID holen
ps.Commands.Clear();
ps.AddCommand("Get-DistributionGroup")
.AddParameter("Identity", name);
var dg = ps.Invoke().FirstOrDefault();
if (dg != null && dg.Properties["Guid"] != null)
{
var guidVal = dg.Properties["Guid"].Value;
if (guidVal is Guid g) result.ObjectGuid = g;
else if (guidVal is string s && Guid.TryParse(s, out Guid parsed)) result.ObjectGuid = parsed;
}
AddMemberToDistributionGroup(name, memberGroup);
SetDistributionGroupManagedBy(name, ownerGroup);
}
}
// Collect group details
string[] dRoles = new string[] {
eLiamAccessRoles.ExchangeMLMember.ToString(),
eLiamAccessRoles.ExchangeMLOwner.ToString()
};
string[] dNames = new string[] {
memberGroup,
ownerGroup
};
for (int i = 0; i < dRoles.Length; i++)
{
DirectoryEntry grpEntry = FindAdObject("(&(objectCategory=group)(sAMAccountName=" + dNames[i] + "))");
if (grpEntry != null && grpEntry.Properties.Contains("objectSid") && grpEntry.Properties["objectSid"].Count > 0)
{
byte[] sidBytes = (byte[])grpEntry.Properties["objectSid"][0];
string sid = new SecurityIdentifier(sidBytes, 0).Value;
string distinguishedName = grpEntry.Properties["distinguishedName"][0].ToString();
result.Groups.Add(Tuple.Create(dRoles[i], sid, dNames[i], distinguishedName));
}
}
return Tuple.Create(result.ObjectGuid, result.Groups);
}
/// <summary>
/// Setzt das ManagedBy-Attribut einer Distribution Group.
/// </summary>
private void SetDistributionGroupManagedBy(string groupName, string managerGroup)
{
using (var runspace = CreateRunspace())
using (var ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddCommand("Set-DistributionGroup")
.AddParameter("Identity", groupName)
.AddParameter("ManagedBy", managerGroup)
.AddParameter("ErrorAction", "SilentlyContinue");
ps.Invoke();
}
}
/// <summary>
/// Hilfsmethode: SecureString in Klartext wandeln.
/// </summary>
private static string SecureStringToString(SecureString ss)
{
if (ss == null) return string.Empty;
IntPtr ptr = Marshal.SecureStringToBSTR(ss);
try
{
return Marshal.PtrToStringBSTR(ptr) ?? string.Empty;
}
finally
{
Marshal.ZeroFreeBSTR(ptr);
}
}
}
}

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{12586A29-BB1E-49B4-B971-88E520D6A77C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LiamExchange</RootNamespace>
<AssemblyName>LiamExchange</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Bcl.Cryptography, Version=9.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.Cryptography.9.0.4\lib\net462\Microsoft.Bcl.Cryptography.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Formats.Asn1, Version=9.0.0.4, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Formats.Asn1.9.0.4\lib\net462\System.Formats.Asn1.dll</HintPath>
</Reference>
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.PowerShell.5.ReferenceAssemblies.1.1.0\lib\net4\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="C4IT.LIAM.Exchange.cs" />
<Compile Include="ExchangeManager.Extensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LiamBaseClasses\LiamBaseClasses.csproj">
<Project>{3531c9e6-cf6e-458e-b604-4a5a8d1c7ab0}</Project>
<Name>LiamBaseClasses</Name>
</ProjectReference>
<ProjectReference Include="..\LiamHelper\LiamHelper.csproj">
<Project>{6b0e73a6-f918-42d5-9525-d59d4d16283d}</Project>
<Name>LiamHelper</Name>
</ProjectReference>
<ProjectReference Include="..\LiamNtfs\LiamNtfs.csproj">
<Project>{7F3085F7-1B7A-4DB2-B66F-1B69CCB0002F}</Project>
<Name>LiamNtfs</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="C4IT.LIAM.ExchangeManager.cs" />
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,10 @@
""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

View File

@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("LiamExchange")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LiamExchange")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("12586a29-bb1e-49b4-b971-88e520d6a77c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

11
LiamExchange/app.config Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?><doc>
<assembly>
<name>System.Buffers</name>
</assembly>
<members>
<member name="T:System.Buffers.ArrayPool`1">
<summary>Provides a resource pool that enables reusing instances of type <see cref="T[]"></see>.</summary>
<typeparam name="T">The type of the objects that are in the resource pool.</typeparam>
</member>
<member name="M:System.Buffers.ArrayPool`1.#ctor">
<summary>Initializes a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class.</summary>
</member>
<member name="M:System.Buffers.ArrayPool`1.Create">
<summary>Creates a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class.</summary>
<returns>A new instance of the <see cref="System.Buffers.ArrayPool`1"></see> class.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Create(System.Int32,System.Int32)">
<summary>Creates a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class using the specifed configuration.</summary>
<param name="maxArrayLength">The maximum length of an array instance that may be stored in the pool.</param>
<param name="maxArraysPerBucket">The maximum number of array instances that may be stored in each bucket in the pool. The pool groups arrays of similar lengths into buckets for faster access.</param>
<returns>A new instance of the <see cref="System.Buffers.ArrayPool`1"></see> class with the specified configuration.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Rent(System.Int32)">
<summary>Retrieves a buffer that is at least the requested length.</summary>
<param name="minimumLength">The minimum length of the array.</param>
<returns>An array of type <see cref="T[]"></see> that is at least <paramref name="minimumLength">minimumLength</paramref> in length.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Return(`0[],System.Boolean)">
<summary>Returns an array to the pool that was previously obtained using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method on the same <see cref="T:System.Buffers.ArrayPool`1"></see> instance.</summary>
<param name="array">A buffer to return to the pool that was previously obtained using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method.</param>
<param name="clearArray">Indicates whether the contents of the buffer should be cleared before reuse. If <paramref name="clearArray">clearArray</paramref> is set to true, and if the pool will store the buffer to enable subsequent reuse, the <see cref="M:System.Buffers.ArrayPool`1.Return(`0[],System.Boolean)"></see> method will clear the <paramref name="array">array</paramref> of its contents so that a subsequent caller using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method will not see the content of the previous caller. If <paramref name="clearArray">clearArray</paramref> is set to false or if the pool will release the buffer, the array&amp;#39;s contents are left unchanged.</param>
</member>
<member name="P:System.Buffers.ArrayPool`1.Shared">
<summary>Gets a shared <see cref="T:System.Buffers.ArrayPool`1"></see> instance.</summary>
<returns>A shared <see cref="System.Buffers.ArrayPool`1"></see> instance.</returns>
</member>
</members>
</doc>

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,355 @@
<?xml version="1.0" encoding="utf-8"?><doc>
<assembly>
<name>System.Memory</name>
</assembly>
<members>
<member name="T:System.Span`1">
<typeparam name="T"></typeparam>
</member>
<member name="M:System.Span`1.#ctor(`0[])">
<param name="array"></param>
</member>
<member name="M:System.Span`1.#ctor(System.Void*,System.Int32)">
<param name="pointer"></param>
<param name="length"></param>
</member>
<member name="M:System.Span`1.#ctor(`0[],System.Int32)">
<param name="array"></param>
<param name="start"></param>
</member>
<member name="M:System.Span`1.#ctor(`0[],System.Int32,System.Int32)">
<param name="array"></param>
<param name="start"></param>
<param name="length"></param>
</member>
<member name="M:System.Span`1.Clear">
</member>
<member name="M:System.Span`1.CopyTo(System.Span{`0})">
<param name="destination"></param>
</member>
<member name="M:System.Span`1.DangerousCreate(System.Object,`0@,System.Int32)">
<param name="obj"></param>
<param name="objectData"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.DangerousGetPinnableReference">
<returns></returns>
</member>
<member name="P:System.Span`1.Empty">
<returns></returns>
</member>
<member name="M:System.Span`1.Equals(System.Object)">
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Fill(`0)">
<param name="value"></param>
</member>
<member name="M:System.Span`1.GetHashCode">
<returns></returns>
</member>
<member name="P:System.Span`1.IsEmpty">
<returns></returns>
</member>
<member name="P:System.Span`1.Item(System.Int32)">
<param name="index"></param>
<returns></returns>
</member>
<member name="P:System.Span`1.Length">
<returns></returns>
</member>
<member name="M:System.Span`1.op_Equality(System.Span{`0},System.Span{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(System.ArraySegment{T})~System.Span{T}">
<param name="arraySegment"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(System.Span{T})~System.ReadOnlySpan{T}">
<param name="span"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(T[])~System.Span{T}">
<param name="array"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Inequality(System.Span{`0},System.Span{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Slice(System.Int32)">
<param name="start"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Slice(System.Int32,System.Int32)">
<param name="start"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.ToArray">
<returns></returns>
</member>
<member name="M:System.Span`1.TryCopyTo(System.Span{`0})">
<param name="destination"></param>
<returns></returns>
</member>
<member name="T:System.SpanExtensions">
</member>
<member name="M:System.SpanExtensions.AsBytes``1(System.ReadOnlySpan{``0})">
<param name="source"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsBytes``1(System.Span{``0})">
<param name="source"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan(System.String)">
<param name="text"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan``1(System.ArraySegment{``0})">
<param name="arraySegment"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan``1(``0[])">
<param name="array"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.CopyTo``1(``0[],System.Span{``0})">
<param name="array"></param>
<param name="destination"></param>
<typeparam name="T"></typeparam>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.Span{System.Byte},System.Byte)">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.ReadOnlySpan{System.Byte},System.Byte)">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.ReadOnlySpan{``0},``0)">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.Span{``0},``0)">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.Byte,System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<param name="value2"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.Byte,System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<param name="value2"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="values"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="values"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.NonPortableCast``2(System.ReadOnlySpan{``0})">
<param name="source"></param>
<typeparam name="TFrom"></typeparam>
<typeparam name="TTo"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.NonPortableCast``2(System.Span{``0})">
<param name="source"></param>
<typeparam name="TFrom"></typeparam>
<typeparam name="TTo"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="first"></param>
<param name="second"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="first"></param>
<param name="second"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="first"></param>
<param name="second"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="first"></param>
<param name="second"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="T:System.ReadOnlySpan`1">
<typeparam name="T"></typeparam>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[])">
<param name="array"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(System.Void*,System.Int32)">
<param name="pointer"></param>
<param name="length"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[],System.Int32)">
<param name="array"></param>
<param name="start"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[],System.Int32,System.Int32)">
<param name="array"></param>
<param name="start"></param>
<param name="length"></param>
</member>
<member name="M:System.ReadOnlySpan`1.CopyTo(System.Span{`0})">
<param name="destination"></param>
</member>
<member name="M:System.ReadOnlySpan`1.DangerousCreate(System.Object,`0@,System.Int32)">
<param name="obj"></param>
<param name="objectData"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.DangerousGetPinnableReference">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Empty">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Equals(System.Object)">
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.GetHashCode">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.IsEmpty">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Item(System.Int32)">
<param name="index"></param>
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Length">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Equality(System.ReadOnlySpan{`0},System.ReadOnlySpan{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Implicit(System.ArraySegment{T})~System.ReadOnlySpan{T}">
<param name="arraySegment"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Implicit(T[])~System.ReadOnlySpan{T}">
<param name="array"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Inequality(System.ReadOnlySpan{`0},System.ReadOnlySpan{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Slice(System.Int32)">
<param name="start"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Slice(System.Int32,System.Int32)">
<param name="start"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.ToArray">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.TryCopyTo(System.Span{`0})">
<param name="destination"></param>
<returns></returns>
</member>
</members>
</doc>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="utf-8"?>
<doc>
<assembly>
<name>System.Runtime.CompilerServices.Unsafe</name>
</assembly>
<members>
<member name="T:System.Runtime.CompilerServices.Unsafe">
<summary>Contains generic, low-level functionality for manipulating pointers.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.Int32)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.IntPtr)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.UIntPtr)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(System.Void*,System.Int32)">
<summary>Adds an element offset to the given void pointer.</summary>
<param name="source">The void pointer to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of void pointer.</typeparam>
<returns>A new void pointer that reflects the addition of offset to the specified pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AddByteOffset``1(``0@,System.IntPtr)">
<summary>Adds a byte offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="byteOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of byte offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AddByteOffset``1(``0@,System.UIntPtr)">
<summary>Adds a byte offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="byteOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of byte offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AreSame``1(``0@,``0@)">
<summary>Determines whether the specified references point to the same location.</summary>
<param name="left">The first reference to compare.</param>
<param name="right">The second reference to compare.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> and <paramref name="right" /> point to the same location; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.As``1(System.Object)">
<summary>Casts the given object to the specified type.</summary>
<param name="o">The object to cast.</param>
<typeparam name="T">The type which the object will be cast to.</typeparam>
<returns>The original object, casted to the given type.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.As``2(``0@)">
<summary>Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo" />.</summary>
<param name="source">The reference to reinterpret.</param>
<typeparam name="TFrom">The type of reference to reinterpret.</typeparam>
<typeparam name="TTo">The desired type of the reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="TTo" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsPointer``1(``0@)">
<summary>Returns a pointer to the given by-ref parameter.</summary>
<param name="value">The object whose pointer is obtained.</param>
<typeparam name="T">The type of object.</typeparam>
<returns>A pointer to the given value.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsRef``1(``0@)">
<summary>Reinterprets the given read-only reference as a reference.</summary>
<param name="source">The read-only reference to reinterpret.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsRef``1(System.Void*)">
<summary>Reinterprets the given location as a reference to a value of type <typeparamref name="T" />.</summary>
<param name="source">The location of the value to reference.</param>
<typeparam name="T">The type of the interpreted location.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ByteOffset``1(``0@,``0@)">
<summary>Determines the byte offset from origin to target from the given references.</summary>
<param name="origin">The reference to origin.</param>
<param name="target">The reference to target.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>Byte offset from origin to target i.e. <paramref name="target" /> - <paramref name="origin" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Copy``1(``0@,System.Void*)">
<summary>Copies a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to copy to.</param>
<param name="source">A pointer to the value to copy.</param>
<typeparam name="T">The type of value to copy.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Copy``1(System.Void*,``0@)">
<summary>Copies a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to copy to.</param>
<param name="source">A reference to the value to copy.</param>
<typeparam name="T">The type of value to copy.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Byte@,System.Byte@,System.UInt32)">
<summary>Copies bytes from the source address to the destination address.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Void*,System.Void*,System.UInt32)">
<summary>Copies bytes from the source address to the destination address.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Byte@,System.Byte@,System.UInt32)">
<summary>Copies bytes from the source address to the destination address without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Void*,System.Void*,System.UInt32)">
<summary>Copies bytes from the source address to the destination address without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Byte@,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Void*,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Byte@,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value without assuming architecture dependent alignment of the address.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Void*,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value without assuming architecture dependent alignment of the address.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressGreaterThan``1(``0@,``0@)">
<summary>Returns a value that indicates whether a specified reference is greater than another specified reference.</summary>
<param name="left">The first value to compare.</param>
<param name="right">The second value to compare.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> is greater than <paramref name="right" />; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressLessThan``1(``0@,``0@)">
<summary>Returns a value that indicates whether a specified reference is less than another specified reference.</summary>
<param name="left">The first value to compare.</param>
<param name="right">The second value to compare.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> is less than <paramref name="right" />; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsNullRef``1(``0@)">
<summary>Determines if a given reference to a value of type <typeparamref name="T" /> is a null reference.</summary>
<param name="source">The reference to check.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="source" /> is a null reference; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.NullRef``1">
<summary>Returns a reference to a value of type <typeparamref name="T" /> that is a null reference.</summary>
<typeparam name="T">The type of the reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" /> that is a null reference.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Read``1(System.Void*)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ReadUnaligned``1(System.Byte@)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ReadUnaligned``1(System.Void*)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SizeOf``1">
<summary>Returns the size of an object of the given type parameter.</summary>
<typeparam name="T">The type of object whose size is retrieved.</typeparam>
<returns>The size of an object of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SkipInit``1(``0@)">
<summary>Bypasses definite assignment rules for a given value.</summary>
<param name="value">The uninitialized object.</param>
<typeparam name="T">The type of the uninitialized object.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.Int32)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.IntPtr)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.UIntPtr)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(System.Void*,System.Int32)">
<summary>Subtracts an element offset from the given void pointer.</summary>
<param name="source">The void pointer to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of the void pointer.</typeparam>
<returns>A new void pointer that reflects the subtraction of offset from the specified pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SubtractByteOffset``1(``0@,System.IntPtr)">
<summary>Subtracts a byte offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="byteOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of byte offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SubtractByteOffset``1(``0@,System.UIntPtr)">
<summary>Subtracts a byte offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="byteOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subraction of byte offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Unbox``1(System.Object)">
<summary>Returns a <see langword="mutable ref" /> to a boxed value.</summary>
<param name="box">The value to unbox.</param>
<typeparam name="T">The type to be unboxed.</typeparam>
<exception cref="T:System.NullReferenceException">
<paramref name="box" /> is <see langword="null" />, and <typeparamref name="T" /> is a non-nullable value type.</exception>
<exception cref="T:System.InvalidCastException">
<paramref name="box" /> is not a boxed value type.
-or-
<paramref name="box" /> is not a boxed <typeparamref name="T" />.</exception>
<exception cref="T:System.TypeLoadException">
<typeparamref name="T" /> cannot be found.</exception>
<returns>A <see langword="mutable ref" /> to the boxed value <paramref name="box" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Write``1(System.Void*,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.WriteUnaligned``1(System.Byte@,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.WriteUnaligned``1(System.Void*,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
</members>
</doc>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.ValueTuple</name>
</assembly>
<members>
</members>
</doc>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?><doc>
<assembly>
<name>System.Buffers</name>
</assembly>
<members>
<member name="T:System.Buffers.ArrayPool`1">
<summary>Provides a resource pool that enables reusing instances of type <see cref="T[]"></see>.</summary>
<typeparam name="T">The type of the objects that are in the resource pool.</typeparam>
</member>
<member name="M:System.Buffers.ArrayPool`1.#ctor">
<summary>Initializes a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class.</summary>
</member>
<member name="M:System.Buffers.ArrayPool`1.Create">
<summary>Creates a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class.</summary>
<returns>A new instance of the <see cref="System.Buffers.ArrayPool`1"></see> class.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Create(System.Int32,System.Int32)">
<summary>Creates a new instance of the <see cref="T:System.Buffers.ArrayPool`1"></see> class using the specifed configuration.</summary>
<param name="maxArrayLength">The maximum length of an array instance that may be stored in the pool.</param>
<param name="maxArraysPerBucket">The maximum number of array instances that may be stored in each bucket in the pool. The pool groups arrays of similar lengths into buckets for faster access.</param>
<returns>A new instance of the <see cref="System.Buffers.ArrayPool`1"></see> class with the specified configuration.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Rent(System.Int32)">
<summary>Retrieves a buffer that is at least the requested length.</summary>
<param name="minimumLength">The minimum length of the array.</param>
<returns>An array of type <see cref="T[]"></see> that is at least <paramref name="minimumLength">minimumLength</paramref> in length.</returns>
</member>
<member name="M:System.Buffers.ArrayPool`1.Return(`0[],System.Boolean)">
<summary>Returns an array to the pool that was previously obtained using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method on the same <see cref="T:System.Buffers.ArrayPool`1"></see> instance.</summary>
<param name="array">A buffer to return to the pool that was previously obtained using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method.</param>
<param name="clearArray">Indicates whether the contents of the buffer should be cleared before reuse. If <paramref name="clearArray">clearArray</paramref> is set to true, and if the pool will store the buffer to enable subsequent reuse, the <see cref="M:System.Buffers.ArrayPool`1.Return(`0[],System.Boolean)"></see> method will clear the <paramref name="array">array</paramref> of its contents so that a subsequent caller using the <see cref="M:System.Buffers.ArrayPool`1.Rent(System.Int32)"></see> method will not see the content of the previous caller. If <paramref name="clearArray">clearArray</paramref> is set to false or if the pool will release the buffer, the array&amp;#39;s contents are left unchanged.</param>
</member>
<member name="P:System.Buffers.ArrayPool`1.Shared">
<summary>Gets a shared <see cref="T:System.Buffers.ArrayPool`1"></see> instance.</summary>
<returns>A shared <see cref="System.Buffers.ArrayPool`1"></see> instance.</returns>
</member>
</members>
</doc>

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,355 @@
<?xml version="1.0" encoding="utf-8"?><doc>
<assembly>
<name>System.Memory</name>
</assembly>
<members>
<member name="T:System.Span`1">
<typeparam name="T"></typeparam>
</member>
<member name="M:System.Span`1.#ctor(`0[])">
<param name="array"></param>
</member>
<member name="M:System.Span`1.#ctor(System.Void*,System.Int32)">
<param name="pointer"></param>
<param name="length"></param>
</member>
<member name="M:System.Span`1.#ctor(`0[],System.Int32)">
<param name="array"></param>
<param name="start"></param>
</member>
<member name="M:System.Span`1.#ctor(`0[],System.Int32,System.Int32)">
<param name="array"></param>
<param name="start"></param>
<param name="length"></param>
</member>
<member name="M:System.Span`1.Clear">
</member>
<member name="M:System.Span`1.CopyTo(System.Span{`0})">
<param name="destination"></param>
</member>
<member name="M:System.Span`1.DangerousCreate(System.Object,`0@,System.Int32)">
<param name="obj"></param>
<param name="objectData"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.DangerousGetPinnableReference">
<returns></returns>
</member>
<member name="P:System.Span`1.Empty">
<returns></returns>
</member>
<member name="M:System.Span`1.Equals(System.Object)">
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Fill(`0)">
<param name="value"></param>
</member>
<member name="M:System.Span`1.GetHashCode">
<returns></returns>
</member>
<member name="P:System.Span`1.IsEmpty">
<returns></returns>
</member>
<member name="P:System.Span`1.Item(System.Int32)">
<param name="index"></param>
<returns></returns>
</member>
<member name="P:System.Span`1.Length">
<returns></returns>
</member>
<member name="M:System.Span`1.op_Equality(System.Span{`0},System.Span{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(System.ArraySegment{T})~System.Span{T}">
<param name="arraySegment"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(System.Span{T})~System.ReadOnlySpan{T}">
<param name="span"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Implicit(T[])~System.Span{T}">
<param name="array"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.op_Inequality(System.Span{`0},System.Span{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Slice(System.Int32)">
<param name="start"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.Slice(System.Int32,System.Int32)">
<param name="start"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.Span`1.ToArray">
<returns></returns>
</member>
<member name="M:System.Span`1.TryCopyTo(System.Span{`0})">
<param name="destination"></param>
<returns></returns>
</member>
<member name="T:System.SpanExtensions">
</member>
<member name="M:System.SpanExtensions.AsBytes``1(System.ReadOnlySpan{``0})">
<param name="source"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsBytes``1(System.Span{``0})">
<param name="source"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan(System.String)">
<param name="text"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan``1(System.ArraySegment{``0})">
<param name="arraySegment"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.AsSpan``1(``0[])">
<param name="array"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.CopyTo``1(``0[],System.Span{``0})">
<param name="array"></param>
<param name="destination"></param>
<typeparam name="T"></typeparam>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.Span{System.Byte},System.Byte)">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.ReadOnlySpan{System.Byte},System.Byte)">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.ReadOnlySpan{``0},``0)">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOf``1(System.Span{``0},``0)">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.Byte,System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<param name="value2"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.Byte,System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<param name="value2"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="values"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="values"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.IndexOfAny(System.ReadOnlySpan{System.Byte},System.Byte,System.Byte)">
<param name="span"></param>
<param name="value0"></param>
<param name="value1"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.NonPortableCast``2(System.ReadOnlySpan{``0})">
<param name="source"></param>
<typeparam name="TFrom"></typeparam>
<typeparam name="TTo"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.NonPortableCast``2(System.Span{``0})">
<param name="source"></param>
<typeparam name="TFrom"></typeparam>
<typeparam name="TTo"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="first"></param>
<param name="second"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="first"></param>
<param name="second"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="first"></param>
<param name="second"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.SequenceEqual``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="first"></param>
<param name="second"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith(System.ReadOnlySpan{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith(System.Span{System.Byte},System.ReadOnlySpan{System.Byte})">
<param name="span"></param>
<param name="value"></param>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith``1(System.ReadOnlySpan{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:System.SpanExtensions.StartsWith``1(System.Span{``0},System.ReadOnlySpan{``0})">
<param name="span"></param>
<param name="value"></param>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="T:System.ReadOnlySpan`1">
<typeparam name="T"></typeparam>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[])">
<param name="array"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(System.Void*,System.Int32)">
<param name="pointer"></param>
<param name="length"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[],System.Int32)">
<param name="array"></param>
<param name="start"></param>
</member>
<member name="M:System.ReadOnlySpan`1.#ctor(`0[],System.Int32,System.Int32)">
<param name="array"></param>
<param name="start"></param>
<param name="length"></param>
</member>
<member name="M:System.ReadOnlySpan`1.CopyTo(System.Span{`0})">
<param name="destination"></param>
</member>
<member name="M:System.ReadOnlySpan`1.DangerousCreate(System.Object,`0@,System.Int32)">
<param name="obj"></param>
<param name="objectData"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.DangerousGetPinnableReference">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Empty">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Equals(System.Object)">
<param name="obj"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.GetHashCode">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.IsEmpty">
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Item(System.Int32)">
<param name="index"></param>
<returns></returns>
</member>
<member name="P:System.ReadOnlySpan`1.Length">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Equality(System.ReadOnlySpan{`0},System.ReadOnlySpan{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Implicit(System.ArraySegment{T})~System.ReadOnlySpan{T}">
<param name="arraySegment"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Implicit(T[])~System.ReadOnlySpan{T}">
<param name="array"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.op_Inequality(System.ReadOnlySpan{`0},System.ReadOnlySpan{`0})">
<param name="left"></param>
<param name="right"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Slice(System.Int32)">
<param name="start"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.Slice(System.Int32,System.Int32)">
<param name="start"></param>
<param name="length"></param>
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.ToArray">
<returns></returns>
</member>
<member name="M:System.ReadOnlySpan`1.TryCopyTo(System.Span{`0})">
<param name="destination"></param>
<returns></returns>
</member>
</members>
</doc>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="utf-8"?>
<doc>
<assembly>
<name>System.Runtime.CompilerServices.Unsafe</name>
</assembly>
<members>
<member name="T:System.Runtime.CompilerServices.Unsafe">
<summary>Contains generic, low-level functionality for manipulating pointers.</summary>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.Int32)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.IntPtr)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(``0@,System.UIntPtr)">
<summary>Adds an element offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Add``1(System.Void*,System.Int32)">
<summary>Adds an element offset to the given void pointer.</summary>
<param name="source">The void pointer to add the offset to.</param>
<param name="elementOffset">The offset to add.</param>
<typeparam name="T">The type of void pointer.</typeparam>
<returns>A new void pointer that reflects the addition of offset to the specified pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AddByteOffset``1(``0@,System.IntPtr)">
<summary>Adds a byte offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="byteOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of byte offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AddByteOffset``1(``0@,System.UIntPtr)">
<summary>Adds a byte offset to the given reference.</summary>
<param name="source">The reference to add the offset to.</param>
<param name="byteOffset">The offset to add.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the addition of byte offset to pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AreSame``1(``0@,``0@)">
<summary>Determines whether the specified references point to the same location.</summary>
<param name="left">The first reference to compare.</param>
<param name="right">The second reference to compare.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> and <paramref name="right" /> point to the same location; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.As``1(System.Object)">
<summary>Casts the given object to the specified type.</summary>
<param name="o">The object to cast.</param>
<typeparam name="T">The type which the object will be cast to.</typeparam>
<returns>The original object, casted to the given type.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.As``2(``0@)">
<summary>Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo" />.</summary>
<param name="source">The reference to reinterpret.</param>
<typeparam name="TFrom">The type of reference to reinterpret.</typeparam>
<typeparam name="TTo">The desired type of the reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="TTo" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsPointer``1(``0@)">
<summary>Returns a pointer to the given by-ref parameter.</summary>
<param name="value">The object whose pointer is obtained.</param>
<typeparam name="T">The type of object.</typeparam>
<returns>A pointer to the given value.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsRef``1(``0@)">
<summary>Reinterprets the given read-only reference as a reference.</summary>
<param name="source">The read-only reference to reinterpret.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.AsRef``1(System.Void*)">
<summary>Reinterprets the given location as a reference to a value of type <typeparamref name="T" />.</summary>
<param name="source">The location of the value to reference.</param>
<typeparam name="T">The type of the interpreted location.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ByteOffset``1(``0@,``0@)">
<summary>Determines the byte offset from origin to target from the given references.</summary>
<param name="origin">The reference to origin.</param>
<param name="target">The reference to target.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>Byte offset from origin to target i.e. <paramref name="target" /> - <paramref name="origin" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Copy``1(``0@,System.Void*)">
<summary>Copies a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to copy to.</param>
<param name="source">A pointer to the value to copy.</param>
<typeparam name="T">The type of value to copy.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Copy``1(System.Void*,``0@)">
<summary>Copies a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to copy to.</param>
<param name="source">A reference to the value to copy.</param>
<typeparam name="T">The type of value to copy.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Byte@,System.Byte@,System.UInt32)">
<summary>Copies bytes from the source address to the destination address.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlock(System.Void*,System.Void*,System.UInt32)">
<summary>Copies bytes from the source address to the destination address.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Byte@,System.Byte@,System.UInt32)">
<summary>Copies bytes from the source address to the destination address without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.CopyBlockUnaligned(System.Void*,System.Void*,System.UInt32)">
<summary>Copies bytes from the source address to the destination address without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The destination address to copy to.</param>
<param name="source">The source address to copy from.</param>
<param name="byteCount">The number of bytes to copy.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Byte@,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlock(System.Void*,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Byte@,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value without assuming architecture dependent alignment of the address.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(System.Void*,System.Byte,System.UInt32)">
<summary>Initializes a block of memory at the given location with a given initial value without assuming architecture dependent alignment of the address.</summary>
<param name="startAddress">The address of the start of the memory block to initialize.</param>
<param name="value">The value to initialize the block to.</param>
<param name="byteCount">The number of bytes to initialize.</param>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressGreaterThan``1(``0@,``0@)">
<summary>Returns a value that indicates whether a specified reference is greater than another specified reference.</summary>
<param name="left">The first value to compare.</param>
<param name="right">The second value to compare.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> is greater than <paramref name="right" />; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsAddressLessThan``1(``0@,``0@)">
<summary>Returns a value that indicates whether a specified reference is less than another specified reference.</summary>
<param name="left">The first value to compare.</param>
<param name="right">The second value to compare.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="left" /> is less than <paramref name="right" />; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.IsNullRef``1(``0@)">
<summary>Determines if a given reference to a value of type <typeparamref name="T" /> is a null reference.</summary>
<param name="source">The reference to check.</param>
<typeparam name="T">The type of the reference.</typeparam>
<returns>
<see langword="true" /> if <paramref name="source" /> is a null reference; otherwise, <see langword="false" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.NullRef``1">
<summary>Returns a reference to a value of type <typeparamref name="T" /> that is a null reference.</summary>
<typeparam name="T">The type of the reference.</typeparam>
<returns>A reference to a value of type <typeparamref name="T" /> that is a null reference.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Read``1(System.Void*)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ReadUnaligned``1(System.Byte@)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.ReadUnaligned``1(System.Void*)">
<summary>Reads a value of type <typeparamref name="T" /> from the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="source">The location to read from.</param>
<typeparam name="T">The type to read.</typeparam>
<returns>An object of type <typeparamref name="T" /> read from the given location.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SizeOf``1">
<summary>Returns the size of an object of the given type parameter.</summary>
<typeparam name="T">The type of object whose size is retrieved.</typeparam>
<returns>The size of an object of type <typeparamref name="T" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SkipInit``1(``0@)">
<summary>Bypasses definite assignment rules for a given value.</summary>
<param name="value">The uninitialized object.</param>
<typeparam name="T">The type of the uninitialized object.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.Int32)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.IntPtr)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(``0@,System.UIntPtr)">
<summary>Subtracts an element offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subraction of offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Subtract``1(System.Void*,System.Int32)">
<summary>Subtracts an element offset from the given void pointer.</summary>
<param name="source">The void pointer to subtract the offset from.</param>
<param name="elementOffset">The offset to subtract.</param>
<typeparam name="T">The type of the void pointer.</typeparam>
<returns>A new void pointer that reflects the subtraction of offset from the specified pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SubtractByteOffset``1(``0@,System.IntPtr)">
<summary>Subtracts a byte offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="byteOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subtraction of byte offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.SubtractByteOffset``1(``0@,System.UIntPtr)">
<summary>Subtracts a byte offset from the given reference.</summary>
<param name="source">The reference to subtract the offset from.</param>
<param name="byteOffset">The offset to subtract.</param>
<typeparam name="T">The type of reference.</typeparam>
<returns>A new reference that reflects the subraction of byte offset from pointer.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Unbox``1(System.Object)">
<summary>Returns a <see langword="mutable ref" /> to a boxed value.</summary>
<param name="box">The value to unbox.</param>
<typeparam name="T">The type to be unboxed.</typeparam>
<exception cref="T:System.NullReferenceException">
<paramref name="box" /> is <see langword="null" />, and <typeparamref name="T" /> is a non-nullable value type.</exception>
<exception cref="T:System.InvalidCastException">
<paramref name="box" /> is not a boxed value type.
-or-
<paramref name="box" /> is not a boxed <typeparamref name="T" />.</exception>
<exception cref="T:System.TypeLoadException">
<typeparamref name="T" /> cannot be found.</exception>
<returns>A <see langword="mutable ref" /> to the boxed value <paramref name="box" />.</returns>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.Write``1(System.Void*,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.WriteUnaligned``1(System.Byte@,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
<member name="M:System.Runtime.CompilerServices.Unsafe.WriteUnaligned``1(System.Void*,``0)">
<summary>Writes a value of type <typeparamref name="T" /> to the given location without assuming architecture dependent alignment of the addresses.</summary>
<param name="destination">The location to write to.</param>
<param name="value">The value to write.</param>
<typeparam name="T">The type of value to write.</typeparam>
</member>
</members>
</doc>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>System.ValueTuple</name>
</assembly>
<members>
</members>
</doc>

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1 @@
f6e128d7149dc184a405058b92396b0925da92456f0d37d8147cf7685d3d5e9f

View File

@@ -0,0 +1,34 @@
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamExchange.dll.config
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamExchange.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamExchange.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamBaseClasses.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamHelper.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\Microsoft.Bcl.Cryptography.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Buffers.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Formats.Asn1.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Management.Automation.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Memory.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Numerics.Vectors.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Runtime.CompilerServices.Unsafe.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Security.Principal.Windows.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.ValueTuple.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\Newtonsoft.Json.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\Microsoft.Management.Infrastructure.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamBaseClasses.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamHelper.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\Microsoft.Bcl.Cryptography.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Buffers.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Formats.Asn1.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Management.Automation.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Memory.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Numerics.Vectors.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Runtime.CompilerServices.Unsafe.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.Security.Principal.Windows.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Debug\System.ValueTuple.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Debug\LiamExchange.csproj.AssemblyReference.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Debug\LiamExchange.csproj.CoreCompileInputs.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Debug\LiamExch.7F93E524.Up2Date
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Debug\LiamExchange.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Debug\LiamExchange.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1 @@
98cf57f4af408c0d6fb600e7f35f4b4ad9afb179b478f70b8c3490f5c097e5b7

View File

@@ -0,0 +1,34 @@
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamExchange.dll.config
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamExchange.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamExchange.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamBaseClasses.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamHelper.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamNtfs.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\Microsoft.Bcl.Cryptography.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Buffers.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Formats.Asn1.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Management.Automation.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Memory.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Numerics.Vectors.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Runtime.CompilerServices.Unsafe.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Security.Principal.Windows.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.ValueTuple.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\Newtonsoft.Json.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\Microsoft.Management.Infrastructure.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamBaseClasses.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamHelper.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\LiamNtfs.pdb
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\Microsoft.Bcl.Cryptography.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Buffers.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Formats.Asn1.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Management.Automation.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Memory.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Numerics.Vectors.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Runtime.CompilerServices.Unsafe.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.Security.Principal.Windows.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\bin\Release\System.ValueTuple.xml
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Release\LiamExchange.csproj.AssemblyReference.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Release\LiamExchange.csproj.CoreCompileInputs.cache
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Release\LiamExch.7F93E524.Up2Date
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Release\LiamExchange.dll
C:\Workspace\C4IT DEV LIAM WEB Service\LiamExchange\obj\Release\LiamExchange.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Bcl.Cryptography" version="9.0.4" targetFramework="net472" />
<package id="Microsoft.PowerShell.5.ReferenceAssemblies" version="1.1.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.DirectoryServices.AccountManagement" version="9.0.4" targetFramework="net472" />
<package id="System.Formats.Asn1" version="9.0.4" targetFramework="net472" />
<package id="System.Memory" version="4.5.5" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
</packages>