- update multiple LIAM projects and solution/config files - add LiamWorkflowDiagnostics app sources and generated outputs - include current workspace state (dependencies and build outputs)
671 lines
25 KiB
Plaintext
671 lines
25 KiB
Plaintext
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());
|
|
}
|
|
}
|
|
|
|
}
|
|
} |