diff --git a/LiamWorkflowDiagnostics/MainWindow.xaml b/LiamWorkflowDiagnostics/MainWindow.xaml
index 3b86f61..52da712 100644
--- a/LiamWorkflowDiagnostics/MainWindow.xaml
+++ b/LiamWorkflowDiagnostics/MainWindow.xaml
@@ -1,253 +1,489 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LiamWorkflowDiagnostics/MainWindow.xaml.cs b/LiamWorkflowDiagnostics/MainWindow.xaml.cs
index ba9fffc..377cb4a 100644
--- a/LiamWorkflowDiagnostics/MainWindow.xaml.cs
+++ b/LiamWorkflowDiagnostics/MainWindow.xaml.cs
@@ -11,7 +11,10 @@ using System.IO;
using C4IT.LIAM;
using C4IT.Logging;
using C4IT.Matrix42.ServerInfo;
+using C4IT.MsGraph;
+using C4IT_IAM_Engine;
using LiamWorkflowActivities;
+using LiamAD;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -31,6 +34,8 @@ namespace LiamWorkflowDiagnostics
InitializeCombos();
MaxDepthTextBox.Text = "1";
LoadSettings();
+ UpdateProviderActionPanel();
+ ToggleActionButtons(true);
this.Closing += MainWindow_Closing;
AppendLog("Diagnostics tool bereit.");
}
@@ -67,6 +72,18 @@ namespace LiamWorkflowDiagnostics
GroupStrategyCombo.ItemsSource = Enum.GetValues(typeof(eLiamGroupStrategies)).Cast();
GroupStrategyCombo.SelectedItem = eLiamGroupStrategies.Ntfs_AGDLP;
+ AdScopeComboBox.ItemsSource = Enum.GetValues(typeof(eLiamAccessRoleScopes))
+ .Cast()
+ .Where(i => i != eLiamAccessRoleScopes.Unknown);
+ AdScopeComboBox.SelectedItem = eLiamAccessRoleScopes.Universal;
+ AdGroupTypeComboBox.ItemsSource = Enum.GetValues(typeof(ADServiceGroupCreator.ADGroupType))
+ .Cast();
+ AdGroupTypeComboBox.SelectedItem = ADServiceGroupCreator.ADGroupType.Distribution;
+ MsTeamsVisibilityComboBox.ItemsSource = Enum.GetValues(typeof(cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType))
+ .Cast();
+ MsTeamsVisibilityComboBox.SelectedItem = cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType.Private;
+ MsTeamsCloneSettingsCheckBox.IsChecked = true;
+ MsTeamsCloneChannelsCheckBox.IsChecked = true;
FetchDataAreasButton.IsEnabled = false;
FetchSecurityGroupsButton.IsEnabled = false;
@@ -131,19 +148,17 @@ namespace LiamWorkflowDiagnostics
if (success)
{
AppendLog("Provider initialisiert und authentifiziert.", LogLevels.Info);
- FetchDataAreasButton.IsEnabled = true;
- FetchSecurityGroupsButton.IsEnabled = true;
ResultTextBox.Text = _session.SanitizedConfigJson;
}
else
{
+ _session = null;
AppendLog("Initialisierung fehlgeschlagen. Prüfe Log für Details.", LogLevels.Error);
- FetchDataAreasButton.IsEnabled = false;
- FetchSecurityGroupsButton.IsEnabled = false;
}
}
catch (Exception ex)
{
+ _session = null;
AppendLog($"Fehler bei Initialisierung: {ex.Message}", LogLevels.Error);
MessageBox.Show(this, ex.ToString(), "Initialisierung fehlgeschlagen", MessageBoxButton.OK, MessageBoxImage.Error);
}
@@ -158,6 +173,26 @@ namespace LiamWorkflowDiagnostics
InitializeButton.IsEnabled = enabled;
LoadJsonButton.IsEnabled = enabled;
ExportJsonButton.IsEnabled = enabled;
+ var providerReady = enabled && _session?.Provider != null;
+ FetchDataAreasButton.IsEnabled = providerReady;
+ FetchSecurityGroupsButton.IsEnabled = providerReady;
+ ActionsGroupBox.IsEnabled = providerReady;
+ UpdateActionHint();
+ }
+
+ private void ProviderTypeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (_session?.Provider != null
+ && ProviderTypeCombo.SelectedItem is eLiamProviderTypes providerType
+ && _session.Provider.ProviderType != providerType)
+ {
+ _session = null;
+ AppendLog("Provider-Typ gewechselt. Bitte Provider neu initialisieren, bevor Calls ausgeführt werden.", LogLevels.Warning);
+ }
+
+ UpdateProviderActionPanel();
+ ToggleActionButtons(true);
+ SaveSettings();
}
private void ClearLogButton_Click(object sender, RoutedEventArgs e)
@@ -225,9 +260,47 @@ namespace LiamWorkflowDiagnostics
ServerNameTextBox.Text = settings.ServerName ?? string.Empty;
UseHttpsCheckBox.IsChecked = settings.UseHttps;
LicenseTextBox.Text = settings.License ?? string.Empty;
+ NtfsCreateFolderPathTextBox.Text = settings.NtfsCreateFolderPath ?? string.Empty;
+ NtfsCreateParentPathTextBox.Text = settings.NtfsCreateParentPath ?? string.Empty;
+ NtfsCreateOwnerSidsTextBox.Text = settings.NtfsCreateOwnerSids ?? string.Empty;
+ NtfsCreateReaderSidsTextBox.Text = settings.NtfsCreateReaderSids ?? string.Empty;
+ NtfsCreateWriterSidsTextBox.Text = settings.NtfsCreateWriterSids ?? string.Empty;
+ NtfsEnsureFolderPathTextBox.Text = settings.NtfsEnsureFolderPath ?? string.Empty;
+ NtfsEnsureOwnerSidsTextBox.Text = settings.NtfsEnsureOwnerSids ?? string.Empty;
+ NtfsEnsureReaderSidsTextBox.Text = settings.NtfsEnsureReaderSids ?? string.Empty;
+ NtfsEnsureWriterSidsTextBox.Text = settings.NtfsEnsureWriterSids ?? string.Empty;
+ NtfsEnsureTraverseCheckBox.IsChecked = settings.NtfsEnsureTraverse;
+ AdServiceNameTextBox.Text = settings.AdServiceName ?? string.Empty;
+ AdDescriptionTextBox.Text = settings.AdDescription ?? string.Empty;
+ AdOwnerSidsTextBox.Text = settings.AdOwnerSids ?? string.Empty;
+ AdMemberSidsTextBox.Text = settings.AdMemberSids ?? string.Empty;
+ MsTeamsSourceTeamIdTextBox.Text = settings.MsTeamsSourceTeamId ?? string.Empty;
+ MsTeamsNewNameTextBox.Text = settings.MsTeamsNewName ?? string.Empty;
+ MsTeamsDescriptionTextBox.Text = settings.MsTeamsDescription ?? string.Empty;
+ MsTeamsCloneAppsCheckBox.IsChecked = settings.MsTeamsCloneApps;
+ MsTeamsCloneTabsCheckBox.IsChecked = settings.MsTeamsCloneTabs;
+ MsTeamsCloneSettingsCheckBox.IsChecked = settings.MsTeamsCloneSettings;
+ MsTeamsCloneChannelsCheckBox.IsChecked = settings.MsTeamsCloneChannels;
+ MsTeamsCloneMembersCheckBox.IsChecked = settings.MsTeamsCloneMembers;
+ MsTeamsAdditionalMembersTextBox.Text = settings.MsTeamsAdditionalMembers ?? string.Empty;
+ MsTeamsAdditionalOwnersTextBox.Text = settings.MsTeamsAdditionalOwners ?? string.Empty;
+ ExchangeMailboxNameTextBox.Text = settings.ExchangeMailboxName ?? string.Empty;
+ ExchangeMailboxAliasTextBox.Text = settings.ExchangeMailboxAlias ?? string.Empty;
+ ExchangeMailboxDisplayNameTextBox.Text = settings.ExchangeMailboxDisplayName ?? string.Empty;
+ ExchangeMailboxPrimarySmtpTextBox.Text = settings.ExchangeMailboxPrimarySmtp ?? string.Empty;
+ ExchangeDistributionNameTextBox.Text = settings.ExchangeDistributionName ?? string.Empty;
+ ExchangeDistributionAliasTextBox.Text = settings.ExchangeDistributionAlias ?? string.Empty;
+ ExchangeDistributionDisplayNameTextBox.Text = settings.ExchangeDistributionDisplayName ?? string.Empty;
+ ExchangeDistributionPrimarySmtpTextBox.Text = settings.ExchangeDistributionPrimarySmtp ?? string.Empty;
if (Enum.IsDefined(typeof(eLiamGroupStrategies), settings.GroupStrategy))
GroupStrategyCombo.SelectedItem = (eLiamGroupStrategies)settings.GroupStrategy;
+ if (Enum.IsDefined(typeof(eLiamAccessRoleScopes), settings.AdScope))
+ AdScopeComboBox.SelectedItem = (eLiamAccessRoleScopes)settings.AdScope;
+ if (Enum.IsDefined(typeof(ADServiceGroupCreator.ADGroupType), settings.AdGroupType))
+ AdGroupTypeComboBox.SelectedItem = (ADServiceGroupCreator.ADGroupType)settings.AdGroupType;
+ if (Enum.IsDefined(typeof(cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType), settings.MsTeamsVisibility))
+ MsTeamsVisibilityComboBox.SelectedItem = (cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType)settings.MsTeamsVisibility;
}
private void SaveSettings()
@@ -264,7 +337,42 @@ namespace LiamWorkflowDiagnostics
ServerName = ServerNameTextBox.Text ?? string.Empty,
UseHttps = UseHttpsCheckBox.IsChecked ?? false,
License = LicenseTextBox.Text ?? string.Empty,
- GroupStrategy = GroupStrategyCombo.SelectedItem is eLiamGroupStrategies gs ? (int)gs : (int)eLiamGroupStrategies.Ntfs_AGDLP
+ GroupStrategy = GroupStrategyCombo.SelectedItem is eLiamGroupStrategies gs ? (int)gs : (int)eLiamGroupStrategies.Ntfs_AGDLP,
+ NtfsCreateFolderPath = NtfsCreateFolderPathTextBox.Text ?? string.Empty,
+ NtfsCreateParentPath = NtfsCreateParentPathTextBox.Text ?? string.Empty,
+ NtfsCreateOwnerSids = NtfsCreateOwnerSidsTextBox.Text ?? string.Empty,
+ NtfsCreateReaderSids = NtfsCreateReaderSidsTextBox.Text ?? string.Empty,
+ NtfsCreateWriterSids = NtfsCreateWriterSidsTextBox.Text ?? string.Empty,
+ NtfsEnsureFolderPath = NtfsEnsureFolderPathTextBox.Text ?? string.Empty,
+ NtfsEnsureOwnerSids = NtfsEnsureOwnerSidsTextBox.Text ?? string.Empty,
+ NtfsEnsureReaderSids = NtfsEnsureReaderSidsTextBox.Text ?? string.Empty,
+ NtfsEnsureWriterSids = NtfsEnsureWriterSidsTextBox.Text ?? string.Empty,
+ NtfsEnsureTraverse = NtfsEnsureTraverseCheckBox.IsChecked ?? false,
+ AdServiceName = AdServiceNameTextBox.Text ?? string.Empty,
+ AdDescription = AdDescriptionTextBox.Text ?? string.Empty,
+ AdScope = AdScopeComboBox.SelectedItem is eLiamAccessRoleScopes scope ? (int)scope : (int)eLiamAccessRoleScopes.Universal,
+ AdGroupType = AdGroupTypeComboBox.SelectedItem is ADServiceGroupCreator.ADGroupType groupType ? (int)groupType : (int)ADServiceGroupCreator.ADGroupType.Distribution,
+ AdOwnerSids = AdOwnerSidsTextBox.Text ?? string.Empty,
+ AdMemberSids = AdMemberSidsTextBox.Text ?? string.Empty,
+ MsTeamsSourceTeamId = MsTeamsSourceTeamIdTextBox.Text ?? string.Empty,
+ MsTeamsNewName = MsTeamsNewNameTextBox.Text ?? string.Empty,
+ MsTeamsDescription = MsTeamsDescriptionTextBox.Text ?? string.Empty,
+ MsTeamsVisibility = MsTeamsVisibilityComboBox.SelectedItem is cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType visibility ? (int)visibility : (int)cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType.Private,
+ MsTeamsCloneApps = MsTeamsCloneAppsCheckBox.IsChecked ?? false,
+ MsTeamsCloneTabs = MsTeamsCloneTabsCheckBox.IsChecked ?? false,
+ MsTeamsCloneSettings = MsTeamsCloneSettingsCheckBox.IsChecked ?? true,
+ MsTeamsCloneChannels = MsTeamsCloneChannelsCheckBox.IsChecked ?? true,
+ MsTeamsCloneMembers = MsTeamsCloneMembersCheckBox.IsChecked ?? false,
+ MsTeamsAdditionalMembers = MsTeamsAdditionalMembersTextBox.Text ?? string.Empty,
+ MsTeamsAdditionalOwners = MsTeamsAdditionalOwnersTextBox.Text ?? string.Empty,
+ ExchangeMailboxName = ExchangeMailboxNameTextBox.Text ?? string.Empty,
+ ExchangeMailboxAlias = ExchangeMailboxAliasTextBox.Text ?? string.Empty,
+ ExchangeMailboxDisplayName = ExchangeMailboxDisplayNameTextBox.Text ?? string.Empty,
+ ExchangeMailboxPrimarySmtp = ExchangeMailboxPrimarySmtpTextBox.Text ?? string.Empty,
+ ExchangeDistributionName = ExchangeDistributionNameTextBox.Text ?? string.Empty,
+ ExchangeDistributionAlias = ExchangeDistributionAliasTextBox.Text ?? string.Empty,
+ ExchangeDistributionDisplayName = ExchangeDistributionDisplayNameTextBox.Text ?? string.Empty,
+ ExchangeDistributionPrimarySmtp = ExchangeDistributionPrimarySmtpTextBox.Text ?? string.Empty
};
var directory = Path.GetDirectoryName(_settingsPath);
@@ -285,6 +393,72 @@ namespace LiamWorkflowDiagnostics
SaveSettings();
}
+ private void UpdateProviderActionPanel()
+ {
+ NtfsActionPanel.Visibility = Visibility.Collapsed;
+ AdActionPanel.Visibility = Visibility.Collapsed;
+ MsTeamsActionPanel.Visibility = Visibility.Collapsed;
+ ExchangeActionPanel.Visibility = Visibility.Collapsed;
+
+ if (!(ProviderTypeCombo.SelectedItem is eLiamProviderTypes providerType))
+ {
+ UpdateActionHint();
+ return;
+ }
+
+ switch (providerType)
+ {
+ case eLiamProviderTypes.Ntfs:
+ NtfsActionPanel.Visibility = Visibility.Visible;
+ break;
+ case eLiamProviderTypes.ActiveDirectory:
+ AdActionPanel.Visibility = Visibility.Visible;
+ break;
+ case eLiamProviderTypes.MsTeams:
+ MsTeamsActionPanel.Visibility = Visibility.Visible;
+ break;
+ case eLiamProviderTypes.Exchange:
+ ExchangeActionPanel.Visibility = Visibility.Visible;
+ break;
+ }
+
+ UpdateActionHint();
+ }
+
+ private void UpdateActionHint()
+ {
+ if (!(ProviderTypeCombo.SelectedItem is eLiamProviderTypes providerType))
+ {
+ ActionHintTextBlock.Text = "Waehle einen Provider-Typ aus.";
+ return;
+ }
+
+ var providerReady = _session?.Provider != null;
+ var providerHint = string.Empty;
+ switch (providerType)
+ {
+ case eLiamProviderTypes.Ntfs:
+ providerHint = "NTFS: neue Ordner anlegen oder auf bestehenden Ordnern fehlende Berechtigungsgruppen und ACLs additiv sicherstellen.";
+ break;
+ case eLiamProviderTypes.ActiveDirectory:
+ providerHint = "Active Directory: Owner- und Member-Gruppen fuer einen Service anhand der konfigurierten Namenskonvention sicherstellen.";
+ break;
+ case eLiamProviderTypes.MsTeams:
+ providerHint = "Microsoft Teams: Team-Clone mit steuerbaren Clone-Bestandteilen ausfuehren.";
+ break;
+ case eLiamProviderTypes.Exchange:
+ providerHint = "Exchange: Shared Mailbox oder Distribution Group inklusive Ownership-Gruppen erzeugen.";
+ break;
+ default:
+ providerHint = "Fuer diesen Provider sind keine Anlage-Aktionen hinterlegt.";
+ break;
+ }
+
+ ActionHintTextBlock.Text = providerReady
+ ? providerHint
+ : $"Initialisiere zuerst einen Provider. {providerHint}";
+ }
+
private async void FetchDataAreasButton_Click(object sender, RoutedEventArgs e)
{
if (_session?.Provider == null)
@@ -336,6 +510,148 @@ namespace LiamWorkflowDiagnostics
}
}
+ private async void ExecuteNtfsCreateButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("NTFS Folder Create", async () =>
+ {
+ var provider = EnsureInitializedProvider("NTFS");
+ var folderPath = GetRequiredText(NtfsCreateFolderPathTextBox.Text, "New Folder Path");
+ var parentPath = NormalizeOptionalText(NtfsCreateParentPathTextBox.Text);
+ if (string.IsNullOrWhiteSpace(parentPath))
+ {
+ parentPath = Directory.GetParent(folderPath)?.FullName;
+ }
+ if (string.IsNullOrWhiteSpace(parentPath))
+ throw new InvalidOperationException("Parent Folder Path konnte nicht ermittelt werden.");
+
+ var result = await provider.CreateDataAreaAsync(
+ folderPath,
+ parentPath,
+ ParseKeyValueLines(CustomTagsTextBox.Text, "Custom Tags"),
+ ParseIdentifierList(NtfsCreateOwnerSidsTextBox.Text, "Owner SIDs"),
+ ParseIdentifierList(NtfsCreateReaderSidsTextBox.Text, "Reader SIDs"),
+ ParseIdentifierList(NtfsCreateWriterSidsTextBox.Text, "Writer SIDs"));
+
+ return MapResultToken(result);
+ });
+ }
+
+ private async void ExecuteNtfsEnsureButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("NTFS Ensure Groups / ACLs", async () =>
+ {
+ var provider = EnsureInitializedProvider("NTFS");
+ var folderPath = GetRequiredText(NtfsEnsureFolderPathTextBox.Text, "Folder Path");
+ var result = await provider.EnsureMissingPermissionGroupsAsync(
+ folderPath,
+ ParseKeyValueLines(CustomTagsTextBox.Text, "Custom Tags"),
+ ParseIdentifierList(NtfsEnsureOwnerSidsTextBox.Text, "Owner SIDs"),
+ ParseIdentifierList(NtfsEnsureReaderSidsTextBox.Text, "Reader SIDs"),
+ ParseIdentifierList(NtfsEnsureWriterSidsTextBox.Text, "Writer SIDs"),
+ NtfsEnsureTraverseCheckBox.IsChecked ?? false);
+
+ return MapResultToken(result);
+ });
+ }
+
+ private async void ExecuteAdCreateButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("AD Ensure Service Groups", async () =>
+ {
+ var provider = EnsureInitializedProvider("Active Directory");
+ var serviceName = GetRequiredText(AdServiceNameTextBox.Text, "Service Name");
+ var description = NormalizeOptionalText(AdDescriptionTextBox.Text);
+ var scope = AdScopeComboBox.SelectedItem is eLiamAccessRoleScopes selectedScope
+ ? selectedScope
+ : eLiamAccessRoleScopes.Universal;
+ var groupType = AdGroupTypeComboBox.SelectedItem is ADServiceGroupCreator.ADGroupType selectedType
+ ? selectedType
+ : ADServiceGroupCreator.ADGroupType.Distribution;
+ var ownerSids = ParseIdentifierList(AdOwnerSidsTextBox.Text, "Owner SIDs");
+ var memberSids = ParseIdentifierList(AdMemberSidsTextBox.Text, "Member SIDs");
+
+ var result = await Task.Run(() => provider.CreateServiceGroups(
+ serviceName,
+ description,
+ scope,
+ groupType,
+ ownerSids,
+ memberSids));
+
+ return MapSecurityGroupResults(result);
+ });
+ }
+
+ private async void ExecuteMsTeamsCloneButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("MsTeams Clone Team", async () =>
+ {
+ var provider = EnsureInitializedProvider("MsTeams");
+ var sourceTeamId = GetRequiredText(MsTeamsSourceTeamIdTextBox.Text, "Source Team ID");
+ var newTeamName = GetRequiredText(MsTeamsNewNameTextBox.Text, "New Team Name");
+ var visibility = MsTeamsVisibilityComboBox.SelectedItem is cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType selectedVisibility
+ ? selectedVisibility
+ : cMsGraphSharepoint.CloneTeamRequest.TeamVisibilityType.Private;
+
+ var result = await provider.cloneTeam(
+ sourceTeamId,
+ newTeamName,
+ NormalizeOptionalText(MsTeamsDescriptionTextBox.Text),
+ (int)visibility,
+ GetSelectedCloneParts(),
+ string.Join(";", ParseIdentifierList(MsTeamsAdditionalMembersTextBox.Text, "Additional Members")),
+ string.Join(";", ParseIdentifierList(MsTeamsAdditionalOwnersTextBox.Text, "Additional Owners")));
+
+ return MapMsGraphResult(result);
+ });
+ }
+
+ private async void ExecuteExchangeMailboxButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("Exchange Create Shared Mailbox", async () =>
+ {
+ var provider = EnsureInitializedProvider("Exchange");
+ var name = GetRequiredText(ExchangeMailboxNameTextBox.Text, "Name");
+ var alias = GetRequiredText(ExchangeMailboxAliasTextBox.Text, "Alias");
+ var displayName = NormalizeOptionalText(ExchangeMailboxDisplayNameTextBox.Text);
+ var primarySmtp = NormalizeOptionalText(ExchangeMailboxPrimarySmtpTextBox.Text);
+ var result = await Task.Run(() => provider.exchangeManager.CreateSharedMailboxWithOwnershipGroups(
+ name,
+ alias,
+ displayName,
+ primarySmtp));
+
+ return new
+ {
+ ObjectGuid = result.Item1,
+ Groups = MapSecurityGroupResults(result.Item2)
+ };
+ });
+ }
+
+ private async void ExecuteExchangeDistributionButton_Click(object sender, RoutedEventArgs e)
+ {
+ await ExecuteProviderActionAsync("Exchange Create Distribution Group", async () =>
+ {
+ var provider = EnsureInitializedProvider("Exchange");
+ var name = GetRequiredText(ExchangeDistributionNameTextBox.Text, "Name");
+ var alias = GetRequiredText(ExchangeDistributionAliasTextBox.Text, "Alias");
+ var displayName = NormalizeOptionalText(ExchangeDistributionDisplayNameTextBox.Text);
+ var primarySmtp = NormalizeOptionalText(ExchangeDistributionPrimarySmtpTextBox.Text);
+ var result = await Task.Run(() => provider.exchangeManager.CreateDistributionGroupWithOwnershipGroups(
+ name,
+ alias,
+ displayName,
+ primarySmtp));
+
+ return new
+ {
+ ObjectGuid = result.Item1,
+ Groups = MapSecurityGroupResults(result.Item2)
+ };
+ });
+ }
+
private async void FetchSecurityGroupsButton_Click(object sender, RoutedEventArgs e)
{
if (_session?.Provider == null)
@@ -412,6 +728,150 @@ namespace LiamWorkflowDiagnostics
}
}
+ private async Task ExecuteProviderActionAsync(string actionName, Func> action)
+ {
+ if (action == null)
+ throw new ArgumentNullException(nameof(action));
+
+ ToggleActionButtons(false);
+ try
+ {
+ SaveSettings();
+ AppendLog($"{actionName} gestartet.");
+ var result = await action();
+ ResultTextBox.Text = JsonConvert.SerializeObject(result, Formatting.Indented);
+ AppendLog($"{actionName} erfolgreich abgeschlossen.");
+ }
+ catch (Exception ex)
+ {
+ AppendLog($"{actionName} fehlgeschlagen: {ex.Message}", LogLevels.Error);
+ MessageBox.Show(this, ex.ToString(), actionName, MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ finally
+ {
+ ToggleActionButtons(true);
+ }
+ }
+
+ private TProvider EnsureInitializedProvider(string providerName) where TProvider : cLiamProviderBase
+ {
+ if (_session?.Provider == null)
+ throw new InvalidOperationException("Bitte zuerst den Provider initialisieren.");
+
+ if (!(_session.Provider is TProvider provider))
+ throw new InvalidOperationException($"Der initialisierte Provider ist nicht vom Typ '{providerName}'. Bitte Einstellungen pruefen und neu initialisieren.");
+
+ return provider;
+ }
+
+ private List ParseIdentifierList(string text, string context)
+ {
+ if (string.IsNullOrWhiteSpace(text))
+ return new List();
+
+ var trimmed = text.Trim();
+ if (trimmed.StartsWith("[", StringComparison.Ordinal))
+ {
+ try
+ {
+ var array = JArray.Parse(trimmed);
+ return array.Values()
+ .Where(i => !string.IsNullOrWhiteSpace(i))
+ .Select(i => i.Trim())
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"{context}: JSON-Array konnte nicht gelesen werden. {ex.Message}");
+ }
+ }
+
+ return trimmed
+ .Split(new[] { '\r', '\n', ';', ',' }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(i => i.Trim())
+ .Where(i => !string.IsNullOrWhiteSpace(i))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+ }
+
+ private string GetRequiredText(string value, string fieldName)
+ {
+ var trimmed = NormalizeOptionalText(value);
+ if (string.IsNullOrWhiteSpace(trimmed))
+ throw new InvalidOperationException($"{fieldName} ist erforderlich.");
+ return trimmed;
+ }
+
+ private string NormalizeOptionalText(string value)
+ {
+ var trimmed = value?.Trim();
+ return string.IsNullOrWhiteSpace(trimmed) ? null : trimmed;
+ }
+
+ private int GetSelectedCloneParts()
+ {
+ var parts = cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.None;
+ if (MsTeamsCloneAppsCheckBox.IsChecked ?? false)
+ parts |= cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.Apps;
+ if (MsTeamsCloneTabsCheckBox.IsChecked ?? false)
+ parts |= cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.Tabs;
+ if (MsTeamsCloneSettingsCheckBox.IsChecked ?? false)
+ parts |= cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.Settings;
+ if (MsTeamsCloneChannelsCheckBox.IsChecked ?? false)
+ parts |= cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.Channels;
+ if (MsTeamsCloneMembersCheckBox.IsChecked ?? false)
+ parts |= cMsGraphSharepoint.CloneTeamRequest.ClonableTeamParts.Members;
+ return (int)parts;
+ }
+
+ private object MapResultToken(ResultToken token)
+ {
+ if (token == null)
+ return null;
+
+ return new
+ {
+ Function = token.resultFunction ?? string.Empty,
+ Message = token.resultMessage ?? string.Empty,
+ ErrorId = token.resultErrorId,
+ CreatedGroups = token.createdGroups ?? new List(),
+ ReusedGroups = token.reusedGroups ?? new List(),
+ AddedAclEntries = token.addedAclEntries ?? new List(),
+ SkippedAclEntries = token.skippedAclEntries ?? new List(),
+ EnsuredTraverseGroups = token.ensuredTraverseGroups ?? new List(),
+ Warnings = token.warnings ?? new List()
+ };
+ }
+
+ private List