Skip to content

Commit f15885e

Browse files
authored
v3.3 (#275)
* declaring dependency (#274) Declaring MimeKit as hosted on Github as a dependency for the project * technet links (#271) updating links to technet articles that are now hosted on the System Center blog * codeql badge (#272) adding CodeQL security scanning status to readme * Additional Attachment handling (#277) * Additional Attachment handling Updating the Attach-FileToWorkItem function to support File and Item Attachments as well if they are Encrypted and or Signed * signed/encrypted attachments Extending digitally signed/encrypted messages to support cases wherein they have File/Item Attachments * improved RE: logic (#270) extending use cases for Merge Replies functionality * OAuth error handling (#278) When connecting to 365 it's possible that the SCSM Run As Account is entered as simply a username and the domain selected VS. entering the username as an email address thereby preventing the selection of the domain. This distinction is also made in the stock Exchange Connector documentation as follows "Ensure that the email address of the account that you enter is in down-level logon name format (for example, DOMAIN\UserName)". In either case, both formats ensure the use of "domain.tld" which grants a successful connection. * History UI (#279) * load settings history when the UI is loaded, history is retrieved and stored in memory * History Form in Build When the project is built, include the History form * Form and Code Behind History Form and History Form code behind placeholders. Will compile with build, but currently do not render the History in the UI. * History Form in UI Including the History Form as a Wizard Step so it appears in the UI on load * render History updating the History Form and Code Behind to pull the history of changes for the connector and render them in the UI. * Revert "History UI (#279)" (#280) This reverts commit 550e70c. * History UI (#281) * load settings history when the UI is loaded, history is retrieved and stored in memory * History Form in Build When the project is built, include the History form * Form and Code Behind History Form and History Form code behind placeholders. Will compile with build, but currently do not render the History in the UI. * History Form in UI Including the History Form as a Wizard Step so it appears in the UI on load * render History updating the History Form and Code Behind to pull the history of changes for the connector and render them in the UI. * History reference missing history reference in build * Extending logging (#273) * Get-SCSMWorkItemParent logging Updating the Get-SCSMWorkItemParent function with New-SMExcoEvent functions instead of write-verbose * Get-AzureEmailLanguage logging Adding logging for when the language of the email is identified by Azure Cognitive Services * Get-TierMembers logging Adding logging for when the users of a Support Group (enum) are requested * Get-AssignedToWorkItemVolume logging Introducing logging when a user's active assigned work count is requested. Given the potential size of a support group, this requires verbose logging as it could potentially generate a lot of events. * Readme and Inline Notes (#282) * history form screenshot for history form in the Settings UI * Settings UI - History Form screenshot and brief explanation of the History form in the UI * version notes updating notes to include relevant GitHub issues * History Form and Logging (#283) * null history handling In the event a feature was never set (null) or set to null through PowerShell, the SDK call for history fails trying to parse the value to a string * dynamic analyst logging introducing logging for the Set-AssignedToPerSupportGroup function so there is clearer path as to how and why Get-TierMembers is used
1 parent 1d3493b commit f15885e

9 files changed

Lines changed: 504 additions & 184 deletions

File tree

FeatureScreenshots/history.png

12.8 KB
Loading

ManagementPack/2016/SMLetsExchangeConnectorSettingsUI/AdminSettingsWizardData.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ class AdminSettingWizardData : WizardData
227227
//logging
228228
private String strLoggingLevel = String.Empty;
229229
private String strLoggingType = String.Empty;
230+
231+
//history
232+
private IList<EnterpriseManagementObjectHistoryTransaction> emoHistoryTransactions;
230233

231234
//management pack guid
232235
private Guid guidEnterpriseManagementObjectID = Guid.Empty;
@@ -2509,6 +2512,21 @@ public String LoggingType
25092512
}
25102513
}
25112514
}
2515+
2516+
public IList<EnterpriseManagementObjectHistoryTransaction> SMExcoSettingsHistory
2517+
{
2518+
get
2519+
{
2520+
return this.emoHistoryTransactions;
2521+
}
2522+
set
2523+
{
2524+
if (this.emoHistoryTransactions != value)
2525+
{
2526+
this.emoHistoryTransactions = value;
2527+
}
2528+
}
2529+
}
25122530

25132531
//management pack guid
25142532
public Guid EnterpriseManagementObjectID
@@ -3295,6 +3313,10 @@ returned Type Projection.
32953313
//logging
32963314
this.LoggingLevel = emoAdminSetting[smletsExchangeConnectorSettingsClass, "LogLevel"].ToString();
32973315
this.LoggingType = emoAdminSetting[smletsExchangeConnectorSettingsClass, "LogType"].ToString();
3316+
3317+
//smlets exchange connector settings history
3318+
EnterpriseManagementObject smletsSettings = emg.EntityObjects.GetObject<EnterpriseManagementObject>(smletsExchangeConnectorSettingsClass.Id, ObjectQueryOptions.Default);
3319+
this.SMExcoSettingsHistory = emg.EntityObjects.GetObjectHistoryTransactions(smletsSettings);
32983320

32993321
//load the MP
33003322
this.EnterpriseManagementObjectID = emoAdminSetting.Id;

ManagementPack/2016/SMLetsExchangeConnectorSettingsUI/AdminTaskHandler.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ against the ServiceManager DB to figure out the following strSingletonBaseManage
7979
wizard.AddLast(new WizardStep("Transcription", typeof(AzureSpeech), wizard.WizardData));
8080
wizard.AddLast(new WizardStep("Workflow", typeof(WorkflowSettings), wizard.WizardData));
8181
wizard.AddLast(new WizardStep("Logging", typeof(Logging), wizard.WizardData));
82+
wizard.AddLast(new WizardStep("History", typeof(HistoryForm), wizard.WizardData));
8283
wizard.AddLast(new WizardStep("About", typeof(AboutForm), wizard.WizardData));
8384

8485
//Show the property page
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<wpfwiz:WizardRegularPageBase
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:wpfwiz="clr-namespace:Microsoft.EnterpriseManagement.UI.WpfWizardFramework;assembly=Microsoft.EnterpriseManagement.UI.WpfWizardFramework"
5+
xmlns:smcontrols="clr-namespace:Microsoft.EnterpriseManagement.UI.WpfControls;assembly=Microsoft.EnterpriseManagement.UI.SMControls"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
xmlns:views="clr-namespace:Microsoft.EnterpriseManagement.UI.FormsInfra;assembly=Microsoft.EnterpriseManagement.UI.FormsInfra"
9+
xmlns:Custom="http://schemas.microsoft.com/SystemCenter/Common/UI/Wpf"
10+
xmlns:scuictrls="http://schemas.microsoft.com/SystemCenter/Common/UI/Controls"
11+
x:Class="SMLetsExchangeConnectorSettingsUI.HistoryForm"
12+
mc:Ignorable="d" Width="900" Height="460">
13+
14+
<Grid x:Name="ConfigurationGrid" Margin="15,10">
15+
<Label Content="Configuration History" Margin="0,10,10,0" VerticalAlignment="Top" Height="48" FontWeight="Bold" FontSize="26"/>
16+
<TextBlock Margin="10,58,10,0" VerticalAlignment="Top" Height="32" FontWeight="Light" FontSize="14" TextWrapping="Wrap">
17+
<Run Text="View changes made to SMLets Exchange Connector Settings"/>
18+
</TextBlock>
19+
20+
<ListView Name="dgHistory" Margin="0,90,0,0">
21+
<ListView.View>
22+
<GridView >
23+
<!-- DateOccured and UserName we won't show as headers, because that's how we're performing GroupBy seen below -->
24+
<GridViewColumn Header="Property" Width="Auto" DisplayMemberBinding="{Binding Property}" />
25+
<GridViewColumn Header="Old Value" Width="Auto" DisplayMemberBinding="{Binding OldValue}" />
26+
<GridViewColumn Header="New Value" Width="Auto" DisplayMemberBinding="{Binding NewValue}" />
27+
</GridView>
28+
</ListView.View>
29+
30+
<!-- Having created a "PropertyGroupDescription" in the code-behind, use "Binding = Name" to reference the grouped value. In this case, DateOccured -->
31+
<ListView.GroupStyle>
32+
<GroupStyle>
33+
<GroupStyle.ContainerStyle>
34+
<Style TargetType="{x:Type GroupItem}">
35+
<Setter Property="Template">
36+
<Setter.Value>
37+
<ControlTemplate>
38+
<Expander IsExpanded="True">
39+
<Expander.Header>
40+
<StackPanel Orientation="Horizontal">
41+
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Black" FontSize="12" VerticalAlignment="Bottom" />
42+
</StackPanel>
43+
</Expander.Header>
44+
<ItemsPresenter />
45+
</Expander>
46+
</ControlTemplate>
47+
</Setter.Value>
48+
</Setter>
49+
</Style>
50+
</GroupStyle.ContainerStyle>
51+
</GroupStyle>
52+
</ListView.GroupStyle>
53+
</ListView>
54+
</Grid>
55+
</wpfwiz:WizardRegularPageBase>
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Windows;
6+
using System.Windows.Controls;
7+
using System.Windows.Data;
8+
using System.Windows.Documents;
9+
using System.Windows.Input;
10+
using System.Windows.Media;
11+
using System.Windows.Media.Imaging;
12+
using System.Windows.Navigation;
13+
using System.Windows.Shapes;
14+
using Microsoft.EnterpriseManagement.UI.WpfControls;
15+
using Microsoft.EnterpriseManagement.UI.WpfWizardFramework;
16+
using Microsoft.EnterpriseManagement.UI.DataModel;
17+
using Microsoft.EnterpriseManagement.UI;
18+
using Microsoft.EnterpriseManagement.UI.Controls;
19+
using Microsoft.EnterpriseManagement.ServiceManager.Application.Common;
20+
using Microsoft.EnterpriseManagement;
21+
using Microsoft.EnterpriseManagement.Common;
22+
using Microsoft.EnterpriseManagement.Configuration;
23+
using Microsoft.EnterpriseManagement.UI.FormsInfra;
24+
using Microsoft.Win32;
25+
using System.Collections.ObjectModel;
26+
27+
namespace SMLetsExchangeConnectorSettingsUI
28+
{
29+
/// <summary>
30+
/// Interaction logic for HistoryForm.xaml
31+
/// </summary>
32+
33+
public partial class HistoryForm : WizardRegularPageBase
34+
{
35+
private HistoryForm adminSettingWizardData = null;
36+
AdminSettingWizardData settings;
37+
38+
public HistoryForm(WizardData wizardData)
39+
{
40+
InitializeComponent();
41+
this.DataContext = wizardData;
42+
this.adminSettingWizardData = this.DataContext as HistoryForm;
43+
44+
//retrieve smlets exchange connector settings
45+
settings = wizardData as AdminSettingWizardData;
46+
47+
//build a custom list based on SMexco configuration history
48+
//Based on SMlets Get-SCSMObjectHistory - https://github.com/SMLets/SMLets/blob/795242d4a44cf8857957a7628cca67655e2e4252/SMLets.Shared/Code/EntityObjects.cs#L1181-L1216
49+
List<CustomHistoryObject> smexcoConfigHistory = new List<CustomHistoryObject>();
50+
51+
foreach (EnterpriseManagementObjectHistoryTransaction historyItem in settings.SMExcoSettingsHistory)
52+
{
53+
string propertyName = null;
54+
string oldVal = null;
55+
string newVal = null;
56+
57+
foreach (KeyValuePair<Guid, EnterpriseManagementObjectHistory> h in historyItem.ObjectHistory)
58+
{
59+
foreach (EnterpriseManagementObjectClassHistory ch in h.Value.ClassHistory)
60+
{
61+
foreach (KeyValuePair<ManagementPackProperty, Microsoft.EnterpriseManagement.Common.Pair<EnterpriseManagementSimpleObject, EnterpriseManagementSimpleObject>> hpc in ch.PropertyChanges)
62+
{
63+
//Simplify properties to variables
64+
propertyName = hpc.Key.Name;
65+
// propertyName = hpc.Key.DisplayName;
66+
try { oldVal = hpc.Value.First.Value.ToString(); } catch { oldVal = ""; }
67+
try { newVal = hpc.Value.Second.Value.ToString(); } catch { newVal = ""; }
68+
69+
//Create a new custom history object
70+
smexcoConfigHistory.Add(new CustomHistoryObject()
71+
{
72+
UserName = historyItem.UserName,
73+
Property = propertyName,
74+
OldValue = oldVal,
75+
NewValue = newVal,
76+
DateOccured = historyItem.DateOccurred.ToLocalTime(),
77+
DateAndUser = historyItem.DateOccurred.ToLocalTime().ToString() + " " + historyItem.UserName
78+
});
79+
}
80+
}
81+
}
82+
}
83+
84+
//With the Custom History Objects created, update the list to all of them. Then define a grouping property for the XAML
85+
dgHistory.ItemsSource = smexcoConfigHistory;
86+
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(dgHistory.ItemsSource);
87+
view.SortDescriptions.Add(new System.ComponentModel.SortDescription("DateOccured", System.ComponentModel.ListSortDirection.Descending));
88+
PropertyGroupDescription groupDescription = new PropertyGroupDescription("DateAndUser");
89+
view.GroupDescriptions.Add(groupDescription);
90+
}
91+
92+
//create a class for a custom history object to display, this is similiar to the MultipleMailboxes XAML and Code behind
93+
public class CustomHistoryObject
94+
{
95+
public string UserName { get; set; }
96+
public string Property { get; set; }
97+
public string OldValue { get; set; }
98+
public string NewValue { get; set; }
99+
public DateTime DateOccured { get; set; }
100+
public string DateAndUser { get; set; }
101+
}
102+
103+
private void WizardRegularPageBase_Loaded(object sender, RoutedEventArgs e)
104+
{
105+
106+
}
107+
}
108+
}

ManagementPack/2016/SMLetsExchangeConnectorSettingsUI/SMLetsExchangeConnectorSettingsUI.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@
8989
<Compile Include="Forms\AzureSpeech.xaml.cs">
9090
<DependentUpon>AzureSpeech.xaml</DependentUpon>
9191
</Compile>
92+
<Compile Include="Forms\HistoryForm.xaml.cs">
93+
<DependentUpon>HistoryForm.xaml</DependentUpon>
94+
</Compile>
9295
<Compile Include="Forms\Logging.xaml.cs">
9396
<DependentUpon>Logging.xaml</DependentUpon>
9497
</Compile>
@@ -163,6 +166,10 @@
163166
<Generator>MSBuild:Compile</Generator>
164167
<SubType>Designer</SubType>
165168
</Page>
169+
<Page Include="Forms\HistoryForm.xaml">
170+
<Generator>MSBuild:Compile</Generator>
171+
<SubType>Designer</SubType>
172+
</Page>
166173
<Page Include="Forms\Logging.xaml">
167174
<Generator>MSBuild:Compile</Generator>
168175
<SubType>Designer</SubType>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net45</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Mimekit" Version="2.9.2" />
9+
</ItemGroup>
10+
11+
</Project>

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
<img src="https://github.com/AdhocAdam/smletsexchangeconnector/workflows/Primary%20Branch%20-%20Build/badge.svg?branch=primary" />
88
<img src="https://github.com/AdhocAdam/smletsexchangeconnector/workflows/Dev%20Branch%20-%20Build/badge.svg?branch=dev" />
99
</p>
10+
<p align="left">
11+
<a href="https://securitylab.github.com/tools/codeql"><img src="https://github.com/AdhocAdam/smletsexchangeconnector/actions/workflows/codeql-analysis.yml/badge.svg" /></a>
12+
</p>
1013

1114
This PowerShell script leverages the [SMlets module](https://www.powershellgallery.com/packages/SMLets/) to build an open and flexible Exchange Connector for controlling Microsoft System Center Service Manager 2016+
1215

@@ -18,6 +21,15 @@ The stock Exchange Connector is a seperate download that enables SCSM deployment
1821
This is aimed at SCSM administrators looking to further push the automation limits of what their SCSM deployment can do with inbound email processing. As such, you should be comfortable with PowerShell and navigating SCSM via SMlets.
1922

2023
## What new things can it do?
24+
<table border="0">
25+
<tr>
26+
<td colspan="3"><i>History Pane (v3.3)</i></td>
27+
</tr>
28+
<tr>
29+
<td width="50%"><img src ="/FeatureScreenshots/history.png" /></td>
30+
<td width="auto">Whether you're changing regex patterns, updating machine learning scores, or modifying any other configuration in the connector. Now just like any Work Item or Config Item you can view the complete history of changes you and your peers have set.</td>
31+
</tr>
32+
</table>
2133
<table border="0">
2234
<tr>
2335
<td colspan="3"><i>[pwsh] Keyword (v3.1)</i></td>

0 commit comments

Comments
 (0)