Src/Helper.cs
using System;
using System.IO; using System.Xml; using System.Xml.XPath; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Management.Automation; using Microsoft.EnterpriseManagement; using Microsoft.EnterpriseManagement.Common; using Microsoft.EnterpriseManagement.Configuration; using Microsoft.EnterpriseManagement.Subscriptions; using System.Text.RegularExpressions; using System.Reflection; using System.Text; namespace SMLets { public class SMCmdletBase : PSCmdlet { // This contains the ComputerName parameter and the // setup for the ManagementGroup where needed // data internal EnterpriseManagementGroup _mg; // Parameters private string _computerName = "localhost"; [Parameter(Mandatory = false, HelpMessage = "The computer to use for the connection to the Service Manager Data Access Service")] [ValidateNotNullOrEmpty] public string ComputerName { get { return _computerName; } set { _computerName = value; } } private PSCredential _credential = null; [Parameter] public PSCredential Credential { get { return _credential; } set { _credential = value; } } private EnterpriseManagementGroup _scsmSession = null; [Parameter(HelpMessage = "A connection to a Service Manager Data Access Service")] public EnterpriseManagementGroup SCSMSession { get { return _scsmSession; } set { _scsmSession = value; } } protected override void BeginProcessing() { try { // A provided session always wins if (SCSMSession != null) { // Make sure that we have this session in our hash table ConnectionHelper.SetMG(SCSMSession); _mg = SCSMSession; } else // No session, go hunting { PSVariable DefaultComputer = SessionState.PSVariable.Get("SMDefaultComputer"); if (DefaultComputer != null) { _mg = ConnectionHelper.GetMG(DefaultComputer.Value.ToString(), _credential); } else { _mg = ConnectionHelper.GetMG(ComputerName, _credential); } } } catch (Exception e) // If we had a problem, the connection is bad, so we have to stop { ThrowTerminatingError( new ErrorRecord(e, "GenericMessage", ErrorCategory.InvalidOperation, ComputerName) ); } } } internal class DataAdapter { public string Assembly; public string Name; public string Type; } public class Column { public string Name; public string DisplayMemberBinding; public string Width; public string DisplayNameId; public string DisplayNameString; public string Property; public string DataType; } public class ItemStatistics { public Object Type; public string TypeName; public int Count; public ItemStatistics(Object o, string s, int c) { Type = o; TypeName = s; Count = c; } } public class UserHelper { public static object GetUserObjectFromString(EnterpriseManagementGroup EMG, string userName, Cmdlet currentCmdlet) { try { ManagementPackClass userClass = EMG.EntityTypes.GetClass("System.Domain.User", EMG.ManagementPacks.GetManagementPack(SystemManagementPack.System)); string name = userName.Split('\\')[1]; string domain = userName.Split('\\')[0]; EnterpriseManagementObjectCriteria c = new EnterpriseManagementObjectCriteria(String.Format("UserName = '{0}' and Domain = '{1}'", name, domain), userClass); IObjectReader<EnterpriseManagementObject> reader = EMG.EntityObjects.GetObjectReader<EnterpriseManagementObject>(c, ObjectQueryOptions.Default); if (reader.Count == 1) { return ServiceManagerObjectHelper.AdaptManagementObject(reader.GetData(0)); } else { return userName; } } catch (Exception e) { currentCmdlet.WriteError(new ErrorRecord(e, "GetUserObjectFromString", ErrorCategory.NotSpecified, userName)); return userName; } } } public class EnterpriseManagementGroupObject { public EnterpriseManagementObject __EnterpriseManagementObject; public ManagementPackClass __Class; public String Description; public String DisplayName; public Guid Id; public String Name; public ManagementPack ManagementPack; public List<XmlNode> MembershipRules; public List<EnterpriseManagementObject> IncludeList; public List<EnterpriseManagementObject> ExcludeList; public List<EnterpriseManagementObject> Members; public string Configuration; public EnterpriseManagementGroupObject(EnterpriseManagementObject emo) { __EnterpriseManagementObject = emo; __Class = emo.GetLeastDerivedNonAbstractClass(); Id = emo.Id; Description = emo.GetLeastDerivedNonAbstractClass().Description; DisplayName = emo.GetLeastDerivedNonAbstractClass().DisplayName; Name = __Class.Name; ManagementPack = __Class.GetManagementPack(); ManagementPackDiscovery d = ManagementPack.GetDiscovery(Name + ".Discovery"); Configuration = d.DataSource.Configuration; XmlDocument xmld = new XmlDocument(); xmld.LoadXml(d.CreateNavigator().OuterXml); MembershipRules = new List<XmlNode>(); Hashtable includeHT = new Hashtable(); Hashtable excludeHT = new Hashtable(); XmlNodeList l; foreach (XmlNode node in xmld.SelectNodes("Discovery/DataSource/MembershipRules/MembershipRule")) { MembershipRules.Add(node); l = node.SelectNodes("IncludeList/MonitoringObjectId"); if (l.Count > 0) { foreach (XmlNode MO in l) { string value = MO.FirstChild.Value; if (value != string.Empty && !includeHT.ContainsKey(value)) { includeHT.Add(value, 1); } } } l = node.SelectNodes("ExcludeList/MonitoringObjectId"); if (l.Count > 0) { foreach (XmlNode MO in l) { string value = MO.FirstChild.Value; if (value != string.Empty && !excludeHT.ContainsKey(value)) { excludeHT.Add(value, 1); } } } } IncludeList = new List<EnterpriseManagementObject>(); foreach (string s in includeHT.Keys) { IncludeList.Add(emo.ManagementGroup.EntityObjects.GetObject<EnterpriseManagementObject>(new Guid(s), ObjectQueryOptions.Default)); } ExcludeList = new List<EnterpriseManagementObject>(); foreach (string s in excludeHT.Keys) { ExcludeList.Add(emo.ManagementGroup.EntityObjects.GetObject<EnterpriseManagementObject>(new Guid(s), ObjectQueryOptions.Default)); } Members = new List<EnterpriseManagementObject>(); foreach (EnterpriseManagementObject remo in emo.ManagementGroup.EntityObjects.GetRelatedObjects<EnterpriseManagementObject>(emo.Id, TraversalDepth.OneLevel, ObjectQueryOptions.Default)) { Members.Add(remo); } } } public class WorkflowHelper { public static PSObject[] GetJobStatus(PSObject instance) { ManagementPackRule rule = (ManagementPackRule)instance.BaseObject; List<PSObject> statuslist = new List<PSObject>(); foreach (SubscriptionJobStatus s in rule.ManagementGroup.Subscription.GetSubscriptionStatusById(rule.Id)) { PSObject o = new PSObject(s); // sometimes the object id is empty, handle that gracefully try { if (s.ObjectId == Guid.Empty) { o.Members.Add(new PSNoteProperty("Object", null)); } else { o.Members.Add(new PSNoteProperty("Object", rule.ManagementGroup.EntityObjects.GetObject<EnterpriseManagementObject>(s.ObjectId, ObjectQueryOptions.Default))); } } catch { o.Members.Add(new PSNoteProperty("Object", null)); } o.Members.Add(new PSNoteProperty("Rule", rule.ManagementGroup.Monitoring.GetRule(s.RuleId))); statuslist.Add(o); } PSObject[] jobstatus = new PSObject[statuslist.Count]; statuslist.CopyTo(jobstatus); return jobstatus; } } public sealed class ConnectionHelper { private static Hashtable ht; public static List<string> GetMGList() { return GetMGList(".*"); } public static List<string> GetMGList(string re) { List<string> l = new List<string>(); Regex r = new Regex(re,RegexOptions.IgnoreCase); foreach(string k in ht.Keys) { if ( r.Match(k).Success ) { l.Add(k.ToString()); } } return l; } public static EnterpriseManagementGroup GetMG(string computerName) { if ( ht == null ) { ht = new Hashtable(StringComparer.OrdinalIgnoreCase); } if ( ht.ContainsKey(computerName)) { return (EnterpriseManagementGroup)ht[computerName]; } else { return null; } } public static EnterpriseManagementGroup GetMG(string computerName, PSCredential credential) { if ( ht == null ) { ht = new Hashtable(StringComparer.OrdinalIgnoreCase); } if (!ht.ContainsKey(computerName)) { EnterpriseManagementGroup emg; if ( credential != null ) { EnterpriseManagementConnectionSettings settings = new EnterpriseManagementConnectionSettings(computerName); settings.UserName = credential.GetNetworkCredential().UserName; settings.Domain = credential.GetNetworkCredential().Domain; settings.Password = credential.Password; emg = new EnterpriseManagementGroup(settings); } else { emg = new EnterpriseManagementGroup(computerName); } ht.Add(computerName, emg); } if ( ! ((EnterpriseManagementGroup)ht[computerName]).IsConnected ) { ((EnterpriseManagementGroup)ht[computerName]).Reconnect(); } return ht[computerName] as EnterpriseManagementGroup; } public static void SetMG(EnterpriseManagementGroup emg) { if ( ht == null ) { ht = new Hashtable(StringComparer.OrdinalIgnoreCase); } if ( ! ht.ContainsKey(emg.ConnectionSettings.ServerName)) { ht.Add(emg.ConnectionSettings.ServerName,emg); } } public static void RemoveMG(string computerName) { if ( ht == null ) { ht = new Hashtable(StringComparer.OrdinalIgnoreCase); } if (ht.ContainsKey(computerName)) { ht.Remove(computerName); } } private ConnectionHelper() { ; } } public sealed class ObjectHelper { public static PSObject PromoteProjectionProperties(EnterpriseManagementObjectProjection projection, string node, string typeName) { PSObject PromotedObject = new PSObject(); PromotedObject.TypeNames[0] = typeName; try { Collection<PSObject> objectList = new Collection<PSObject>(); XPathNavigator Navigator = projection.CreateNavigator(); if ( Navigator.Select(node).Count > 1) { foreach(XPathNavigator xnav in Navigator.Select(node)) { PSObject listmember = new PSObject(); IComposableProjection composedProjection = (IComposableProjection)xnav.UnderlyingObject; listmember.Members.Add(new PSNoteProperty("__base", composedProjection.Object)); foreach ( ManagementPackProperty p in composedProjection.Object.GetProperties()) { listmember.Members.Add(new PSNoteProperty(p.Name, composedProjection.Object[p].Value)); } objectList.Add(listmember); } PromotedObject.Members.Add(new PSNoteProperty(typeName, objectList)); } else { XPathNavigator singleNodeNavigator = Navigator.SelectSingleNode(node); IComposableProjection composedProjection = (IComposableProjection)singleNodeNavigator.UnderlyingObject; PromotedObject.Members.Add(new PSNoteProperty("__base", composedProjection.Object)); foreach ( ManagementPackProperty p in composedProjection.Object.GetProperties()) { PromotedObject.Members.Add(new PSNoteProperty(p.Name, composedProjection.Object[p].Value)); } } } catch ( Exception e ) { PromotedObject.Members.Add(new PSNoteProperty("PromotionFailure",e.Message)); } return PromotedObject; } // This looks through *all* the enumerations in the system // This could be done more efficiently, but at least does't // require a round trip to the server since these are cached // the client side. public static ManagementPackEnumeration GetEnumerationFromName(EnterpriseManagementGroup emg, string name) { foreach( ManagementPackEnumeration e in emg.EntityTypes.GetEnumerations()) { int CompareResult = String.Compare(e.Name, name, StringComparison.OrdinalIgnoreCase); if ( CompareResult == 0) { return e; } } return null; } private ObjectHelper() { ; } } public class ProjectionConverter : PSTypeConverter { // Currently, this converter is only targeted at/ EnterpriseManagementObjectProjection, // (via the SMLets.Types.ps1xml file) but could easily be extended public override bool CanConvertFrom(object source, Type destination) { PSObject o = source as PSObject; return CanConvertFrom(o, destination); } public override bool CanConvertFrom(PSObject source, Type destination) { if ( source.Properties["__base"] != null ) { return true; } return false; } public override object ConvertFrom(Object source, Type destination, IFormatProvider p, bool ignoreCase ) { PSObject o = source as PSObject; if ( o == null ) { throw new InvalidCastException("Conversion failed"); } if ( this.CanConvertFrom(o, destination)) { try { return o.Properties["__base"].Value; } catch { throw new InvalidCastException("Conversion failed"); } } throw new InvalidCastException("Conversion failed"); } public override object ConvertFrom(PSObject source, Type destination, IFormatProvider p, bool ignoreCase ) { if ( source == null ) { throw new InvalidCastException("Conversion failed"); } if ( this.CanConvertFrom(source, destination)) { try { return source.Properties["__base"].Value; } catch { throw new InvalidCastException("Conversion failed"); } } throw new InvalidCastException("Conversion failed"); } public override bool CanConvertTo(object source, Type destination) { PSObject o = source as PSObject; return CanConvertTo(o, destination); } public override bool CanConvertTo(PSObject value, Type destination) { return false; } public override object ConvertTo(object value, Type destination, IFormatProvider p, bool ignoreCase) { throw new InvalidCastException("Conversion failed"); } public override object ConvertTo(PSObject value, Type destination, IFormatProvider p, bool ignoreCase) { throw new InvalidCastException("Conversion failed"); } } public class PropertyOperatorValue { public string Property; public string Operator; public string Value; public PropertyOperatorValue() { ; } public PropertyOperatorValue(string filter) { RegexOptions ropt = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase; Regex r = new Regex("(?<Property>.*)\\s+(?<Operator>-like|-notlike|=|==|<|>|!=|-eq|-ne|-gt|-ge|-le|-lt|-isnull|-isnotnull)\\s+(?<Value>.*)", ropt); // OK - we have a filter we can use Match m = r.Match(filter); if (!m.Success) { throw new InvalidOperationException("Filter '" + filter + "' is invalid"); } Property = m.Groups["Property"].Value.Trim(); Operator = GetOperator(m.Groups["Operator"].Value.Trim().ToLower()); // this now handles wildcard characters in a simple minded way Value = m.Groups["Value"].Value.Trim().Trim('"', '\'').Replace("*", "%").Replace("?", "_"); } public static string GetOperator(string myOperator) { switch (myOperator.ToLowerInvariant()) { case "-like": return "Like"; case "-notlike": return "NotLike"; case "-eq": case "=": case "==": return "Equal"; case "-ne": case "!=": return "NotEqual"; case "-gt": case ">": return "Greater"; case "-ge": case ">=": return "GreaterEqual"; case "-le": case "<=": return "LessEqual"; case "-lt": case "<": return "Less"; case "-isnull": return "Is Null"; case "-isnotnull": return "Is Not Null"; default: throw new InvalidOperationException("'" + myOperator + "' is not a valid operator"); } } } public static class CriteriaHelper<T> { // // Usage pattern: // ManagementPackClassCriteria mpcc = CriteriaHelper<ManagementPackClassCriteria>.CreateGenericCriteria("Name -like '*Entity'"); // EnterpriseManagementRelationshipObjectGenericCriteria foo = CriteriaHelper<EnterpriseManagementRelationshipObjectGenericCriteria>.CreateCriteria("TargetObjectDisplayName -like 'Custom%'"); // // If the Criteria schema changes this will break public const string CriteriaFormatString = "<Criteria xmlns='http://Microsoft.EnterpriseManagement.Core.Criteria/'><Expression><SimpleExpression><ValueExpressionLeft><GenericProperty>{0}</GenericProperty></ValueExpressionLeft><Operator>{1}</Operator><ValueExpressionRight><Value>{2}</Value></ValueExpressionRight></SimpleExpression></Expression></Criteria>"; public static string critXml; public static string getGenericXml(Type t, string filter) { String message = "unknown error"; try { PropertyOperatorValue POV = new PropertyOperatorValue(filter); BindingFlags flags = BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static; string method = "GetValidPropertyNames"; if (string.Compare(t.Name, "EnterpriseManagementObjectCriteria", true) == 0) { method = "GetSpecialPropertyNames"; } ReadOnlyCollection<string> propertyNames = (ReadOnlyCollection<String>)t.InvokeMember(method, flags, null, t, null); string[] names = new string[propertyNames.Count]; propertyNames.CopyTo(names,0); message = String.Format("Property '{0}' not found, allowed values: {1}", POV.Property, String.Join(", ", names)); foreach (string pn in propertyNames) { if (String.Compare(pn, POV.Property, true) == 0) { return String.Format(CriteriaFormatString, pn, POV.Operator, POV.Value); } } } catch (Exception e) { throw e; } throw new ObjectNotFoundException(message); } // Usefull for Generic Criteria and ManagementPack public static T CreateGenericCriteria(string filter) { critXml = getGenericXml(typeof(T), filter); if (critXml == null) { return default(T); } return (T)Activator.CreateInstance(typeof (T), critXml); } public static T CreateGenericCriteria(string filter, ManagementPackTypeProjection p, EnterpriseManagementGroup emg) { critXml = getGenericXml(typeof(T), filter); if (critXml == null) { return default(T); } return (T)Activator.CreateInstance(typeof(T), critXml,p,emg); } public static T CreateGenericCriteria(string filter, ManagementPackClass c, EnterpriseManagementGroup emg) { critXml = getGenericXml(typeof(T), filter); if (critXml == null) { return default(T); } return (T)Activator.CreateInstance(typeof(T), critXml, c, emg); } } public static class SMHelpers { public static bool GuidTryParse(string s, out Guid result) { if (s == null) throw new ArgumentNullException("s"); Regex format = new Regex( "^[A-Fa-f0-9]{32}$|" + "^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|" + "^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, {0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$"); Match match = format.Match(s); if (match.Success) { result = new Guid(s); return true; } else { result = Guid.Empty; return false; } } public static ManagementPackEnumeration GetEnum(string identifier, ManagementPackEnumeration etype) { // Try really hard to find an enumeration based on a parent enumeration // Match in the following order: // ID // Name // The last token of the Name after the last "." // The DisplayName // A regex match of the name // A regex match of the DisplayName // If any of those is found, return the first one you succeed in matching // if you still can't find a match, then throw and provide a helping message if (etype == null) { throw new ArgumentException("Base Enumeration is null"); } try { Regex r = new Regex(identifier, RegexOptions.IgnoreCase); Regex removeToDot = new Regex(".*\\."); foreach (ManagementPackEnumeration e in etype.ManagementGroup.EntityTypes.GetChildEnumerations(etype.Id, TraversalDepth.Recursive)) { if (String.Compare(identifier, e.Id.ToString(), true) == 0) { return e; } if (String.Compare(identifier, e.Name, true) == 0) { return e; } if (String.Compare(identifier, removeToDot.Replace(e.Name, ""), true) == 0) { return e; } if (String.Compare(identifier, e.DisplayName, true) == 0) { return e; } if (r.Match(e.Name).Success == true) { return e; } if (r.Match(e.DisplayName).Success == true) { return e; } } } catch { ; } StringBuilder sb = new StringBuilder(); sb.Append("Could not find '" + identifier + "' in enumeration '"); sb.Append(etype.DisplayName); sb.Append("'. Allowed values are:\n"); foreach (ManagementPackEnumeration e in etype.ManagementGroup.EntityTypes.GetChildEnumerations(etype.Id, TraversalDepth.Recursive)) { sb.Append("\t '" + e.DisplayName + "' (" + e.Name + ")\n"); } throw new ArgumentException(sb.ToString()); } public static ManagementPackEnumeration GetEnum(string identifier, EnterpriseManagementGroup emg) { // This one is very strict - it will only match the name and really targeted at helper methods foreach (ManagementPackEnumeration e in emg.EntityTypes.GetEnumerations()) { if (string.Compare(e.Name, identifier, true) == 0) { return e; } } return null; } public static int DeterminePriority(ManagementPackEnumeration Urgency, ManagementPackEnumeration Impact, EnterpriseManagementGroup _mg) { // give it a good try, if something goes wrong, just return 5 try { EnterpriseManagementGroup emg = Urgency.ManagementGroup; ManagementPackClass settingClass = SMHelpers.GetManagementPackClass(ClassTypes.System_WorkItem_Incident_GeneralSetting, SMHelpers.GetManagementPack(ManagementPacks.ServiceManager_IncidentManagement_Library, _mg), _mg); EnterpriseManagementObject settings = emg.EntityObjects.GetObject<EnterpriseManagementObject>(settingClass.Id, ObjectQueryOptions.Default); XmlDocument x = new XmlDocument(); string xmlstring = settings[null, "PriorityMatrix"].Value as string; x.LoadXml(xmlstring); string u = Urgency.Id.ToString(); string i = Impact.Id.ToString(); string xpath = String.Format("/Matrix/U[@Id='{0}']/I[@Id='{1}']/P", u, i); XmlNode s = x.SelectSingleNode(xpath); string ts = s.InnerText; return Int32.Parse(ts); } catch { // Try to do something sensible, compute some sensible defaults try { Dictionary<string,int> matrix = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase); matrix.Add("Low",1); matrix.Add("Medium",2); matrix.Add("High",3); int v = (3 * (matrix[Urgency.DisplayName] - 1)) + matrix[Impact.DisplayName]; return v; } catch // nevermind, return 5 { return 5; } } } public static void UpdateIncident(EnterpriseManagementGroup emg, ManagementPackClass clsIncident, EnterpriseManagementObjectProjection emop, string impact, string urgency, string status, string classification, string source, string supportGroup, string comment, string userComment, string description, string attachmentPath) { FileStream item = null; try { // get the BaseEnums, these are used later! ManagementPackEnumeration impactBase = SMHelpers.GetEnum("System.WorkItem.TroubleTicket.ImpactEnum", emg); ManagementPackEnumeration urgencyBase = SMHelpers.GetEnum("System.WorkItem.TroubleTicket.UrgencyEnum", emg); ManagementPackEnumeration statusBase = SMHelpers.GetEnum("IncidentStatusEnum", emg); ManagementPackEnumeration classificationBase = SMHelpers.GetEnum("IncidentClassificationEnum", emg); ManagementPackEnumeration sourceBase = SMHelpers.GetEnum("IncidentSourceEnum", emg); ManagementPackEnumeration supportGroupBase = SMHelpers.GetEnum("IncidentTierQueuesEnum", emg); ManagementPackEnumeration impactEnum = null; ManagementPackEnumeration urgencyEnum = null; ManagementPackEnumeration statusEnum = null; ManagementPackEnumeration classificationEnum = null; ManagementPackEnumeration sourceEnum = null; ManagementPackEnumeration supportGroupEnum = null; //If impact supplies, update the current value if (impact != null) { impactEnum = SMHelpers.GetEnum(impact, impactBase); emop.Object[clsIncident, "Impact"].Value = impactEnum.Id; } //If value supplied, update the current value if (urgency != null) { urgencyEnum = SMHelpers.GetEnum(urgency, urgencyBase); emop.Object[clsIncident, "Urgency"].Value = urgencyEnum.Id; } //If value supplied, update the current value if (status != null) { statusEnum = SMHelpers.GetEnum(status, statusBase); emop.Object[clsIncident, "Status"].Value = statusEnum.Id; if (String.Compare(status, "Closed", true) == 0) { emop.Object[clsIncident, "ClosedDate"].Value = DateTime.Now.ToUniversalTime(); } else if (String.Compare(status, "Resolved") == 0) { emop.Object[clsIncident, "ResolvedDate"].Value = DateTime.Now.ToUniversalTime(); } } //If source supplied, update the current value if (source != null) { sourceEnum = SMHelpers.GetEnum(source, sourceBase); emop.Object[clsIncident, "Source"].Value = sourceEnum.Id; } //If classification supplied, update the current value if (classification != null) { classificationEnum = SMHelpers.GetEnum(classification, classificationBase); emop.Object[clsIncident, "Classification"].Value = classificationEnum.Id; } if (supportGroup != null) { supportGroupEnum = SMHelpers.GetEnum(supportGroup, supportGroupBase); emop.Object[clsIncident, "TierQueue"].Value = supportGroupEnum.Id; } //Description supplied, update the current value if (description != null) { emop.Object[clsIncident, "Description"].Value = description; } //If comment supplied, update the current value if (comment != null) { ManagementPackClass analystCommentClass = GetManagementPackClass(ClassTypes.System_WorkItem_TroubleTicket_AnalystCommentLog, GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); CreatableEnterpriseManagementObject analystComment = new CreatableEnterpriseManagementObject(emg, analystCommentClass); analystComment[analystCommentClass, "Id"].Value = Guid.NewGuid().ToString();// "comment-" + DateTime.Now.ToString(); //Had to change from date time dependent since the speed was an issues analystComment[null, "Comment"].Value = comment; analystComment[null, "EnteredBy"].Value = EnterpriseManagementGroup.CurrentUserName; analystComment[null, "EnteredDate"].Value = DateTime.Now.ToUniversalTime(); ManagementPackRelationship incidentEmbedsAnalystComment = SMHelpers.GetManagementPackRelationship(RelationshipTypes.System_WorkItem_TroubleTicketHasAnalystComment, GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); emop.Add(analystComment, incidentEmbedsAnalystComment.Target); } //If comment supplied, update the current value if (userComment != null) { ManagementPackClass userCommentClass = GetManagementPackClass(ClassTypes.System_WorkItem_TroubleTicket_UserCommentLog, GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); CreatableEnterpriseManagementObject userCommentObject = new CreatableEnterpriseManagementObject(emg, userCommentClass); userCommentObject[userCommentClass, "Id"].Value = Guid.NewGuid().ToString();// "comment-" + DateTime.Now.ToString(); //Had to change from date time dependent since the speed was an issues userCommentObject[null, "Comment"].Value = userComment; userCommentObject[null, "EnteredBy"].Value = EnterpriseManagementGroup.CurrentUserName; userCommentObject[null, "EnteredDate"].Value = DateTime.Now.ToUniversalTime(); ManagementPackRelationship incidentEmbedsUserComment = SMHelpers.GetManagementPackRelationship(RelationshipTypes.System_WorkItem_TroubleTicketHasUserComment, SMHelpers.GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); emop.Add(userCommentObject, incidentEmbedsUserComment.Target); } //If file path for attachment supplied, attach file if (attachmentPath != null) { ManagementPackClass fileAttachmentClass = GetManagementPackClass(ClassTypes.System_FileAttachment, GetManagementPack(ManagementPacks.System_SupportingItem_Library, emg), emg); CreatableEnterpriseManagementObject fileAttachment = new CreatableEnterpriseManagementObject(emg, fileAttachmentClass); item = new FileStream(attachmentPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); string fileName = Path.GetFileName(attachmentPath); fileAttachment[fileAttachmentClass, "Id"].Value = Guid.NewGuid().ToString(); fileAttachment[fileAttachmentClass, "DisplayName"].Value = fileName; fileAttachment[fileAttachmentClass, "Description"].Value = fileName; fileAttachment[fileAttachmentClass, "Extension"].Value = Path.GetExtension(attachmentPath); fileAttachment[fileAttachmentClass, "Size"].Value = (int)item.Length; fileAttachment[fileAttachmentClass, "AddedDate"].Value = DateTime.Now.ToUniversalTime(); fileAttachment[fileAttachmentClass, "Content"].Value = item; ManagementPackRelationship workItemHasFileAttachment = SMHelpers.GetManagementPackRelationship( RelationshipTypes.System_WorkItemHasFileAttachment, SMHelpers.GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); emop.Add(fileAttachment, workItemHasFileAttachment.Target); //File add Action log ManagementPackClass logCommentClass = GetManagementPackClass( ClassTypes.System_WorkItem_TroubleTicket_ActionLog, GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); CreatableEnterpriseManagementObject logComment = new CreatableEnterpriseManagementObject(emg, logCommentClass); logComment[logCommentClass, "Id"].Value = Guid.NewGuid().ToString(); logComment[logCommentClass, "Description"].Value = fileName; logComment[logCommentClass, "EnteredDate"].Value = DateTime.Now.ToUniversalTime(); ManagementPackEnumeration enumeration = GetEnum(Enumerations.SystemWorkItemActionLogEnumFileAttached, emg); logComment[logCommentClass, "ActionType"].Value = enumeration; logComment[logCommentClass, "EnteredBy"].Value = Environment.UserName; logComment[logCommentClass, "Title"].Value = enumeration.DisplayName; ManagementPackRelationship fileAttachmentComment = SMHelpers.GetManagementPackRelationship( RelationshipTypes.System_WorkItem_TroubleTicketHasActionLog, GetManagementPack(ManagementPacks.System_WorkItem_Library, emg), emg); emop.Add(logComment, fileAttachmentComment.Target); } if (urgencyEnum != null && impactEnum != null) { int priority = SMHelpers.DeterminePriority(urgencyEnum, impactEnum, emg); emop.Object[clsIncident, "Priority"].Value = priority; } //Commit all changes emop.Commit(); } catch (Exception e) { throw e; } finally { if (item != null) { item.Close(); item.Dispose(); } } } public static void AddAffectedCI(EnterpriseManagementObjectProjection projection, EnterpriseManagementObject affectedCI, EnterpriseManagementGroup mg) { //Set the created by user to the user who used the web form. ManagementPackRelationship affectedItem = SMHelpers.GetManagementPackRelationship(RelationshipTypes.System_WorkItemAboutConfigItem, GetManagementPack(ManagementPacks.System_WorkItem_Library, mg), mg); projection.Add(affectedCI, affectedItem.Target); } public static void AddAffectedUser(EnterpriseManagementObjectProjection projection, string userIdentifier, EnterpriseManagementGroup mg) { EnterpriseManagementObject user = GetUser(mg, userIdentifier); //Set the created by user to the user who used the web form. ManagementPackRelationship affectedUser = SMHelpers.GetManagementPackRelationship(RelationshipTypes.System_WorkItemAffectedUser, GetManagementPack(ManagementPacks.System_WorkItem_Library, mg), mg); projection.Add(user, affectedUser.Target); } public static EnterpriseManagementObject GetUser(EnterpriseManagementGroup mg, string userIdentifier) { ManagementPack mpWindows = mg.ManagementPacks.GetManagementPack(SystemManagementPack.Windows); ManagementPackClass userClass = GetManagementPackClass(ClassTypes.Microsoft_AD_User, GetManagementPack(ManagementPacks.Microsoft_Windows_Library, mg), mg); //Create the criteria XML and criteria object string userCriteria = CreateUserCriteriaXml(mg, userIdentifier); EnterpriseManagementObjectCriteria criteria = new EnterpriseManagementObjectCriteria(userCriteria, userClass, mpWindows, mg); //Retrieve the user that corresponds to the criteria IEnumerable<EnterpriseManagementObject> users = (IEnumerable<EnterpriseManagementObject>)mg.EntityObjects.GetObjectReader<EnterpriseManagementObject>(criteria, ObjectQueryOptions.Default); //Get the enumerator IEnumerator<EnterpriseManagementObject> enumUsers = users.GetEnumerator(); while (enumUsers.MoveNext()) { return enumUsers.Current; } //If no user was found, throw an exception throw new Exception("No user with user identified by: " + userIdentifier + " found in Service Manager"); } public static string CreateUserCriteriaXml(EnterpriseManagementGroup mg, string userIdentifier) { ManagementPack mpWindows = mg.ManagementPacks.GetManagementPack(SystemManagementPack.Windows); string userCriteria = string.Empty; // Check the format of the userName to make sure we create the correct filter if (userIdentifier.StartsWith("CN=")) { // This is XML that validates against the Microsoft.EnterpriseManagement.Core.Criteria schema. userCriteria = String.Format(@" <Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/""> <Expression> <SimpleExpression> <ValueExpressionLeft> <Property>$Target/Property[Type='Microsoft.AD.User']/DistinguishedName$</Property> </ValueExpressionLeft> <Operator>Equal</Operator> <ValueExpressionRight> <Value>{0}</Value> </ValueExpressionRight> </SimpleExpression> </Expression> </Criteria> ", userIdentifier); } else if (userIdentifier.StartsWith("S-1-5")) { // This is XML that validates against the Microsoft.EnterpriseManagement.Core.Criteria schema. userCriteria = String.Format(@" <Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/""> <Expression> <SimpleExpression> <ValueExpressionLeft> <Property>$Target/Property[Type='Microsoft.AD.User']/SID$</Property> </ValueExpressionLeft> <Operator>Equal</Operator> <ValueExpressionRight> <Value>{0}</Value> </ValueExpressionRight> </SimpleExpression> </Expression> </Criteria> ", userIdentifier); } else { string[] userData = userIdentifier.Split('\\'); // This is XML that validates against the Microsoft.EnterpriseManagement.Core.Criteria schema. userCriteria = String.Format(@" <Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/""> <Expression> <And> <Expression> <SimpleExpression> <ValueExpressionLeft> <Property>$Target/Property[Type='Microsoft.AD.User']/UserName$</Property> </ValueExpressionLeft> <Operator>Equal</Operator> <ValueExpressionRight> <Value>{1}</Value> </ValueExpressionRight> </SimpleExpression> </Expression> <Expression> <SimpleExpression> <ValueExpressionLeft> <Property>$Target/Property[Type='Microsoft.AD.User']/Domain$</Property> </ValueExpressionLeft> <Operator>Equal</Operator> <ValueExpressionRight> <Value>{0}</Value> </ValueExpressionRight> </SimpleExpression> </Expression> </And> </Expression> </Criteria> ", userData[0], userData[1]); } return userCriteria; } public static string MakeMPElementSafeUniqueIdentifier(string strElementType) { string[] strDisallowedCharacters = new string[]{"!","@","#","$","%","^","&","*","(",")","_","-","+","=","{","}","[","]","|","\\",":","?","/","<",">",".","~",",","'","\""," "}; string strSafeUniqueIdentifier = String.Format("{0}.{1}", strElementType, Guid.NewGuid().ToString("N")); foreach(string strDisallowedCharacter in strDisallowedCharacters) { strSafeUniqueIdentifier = strSafeUniqueIdentifier.Replace(strDisallowedCharacter, ""); } return (strSafeUniqueIdentifier); } public static ManagementPack GetManagementPack(string id, EnterpriseManagementGroup emg) { ManagementPackCriteria mpcriteria = new ManagementPackCriteria(String.Format("Name = '{0}'", id)); IList<ManagementPack> mps = emg.ManagementPacks.GetManagementPacks(mpcriteria); //assuming there is only one - return the first one regardless if (mps.Count > 0) return (mps[0]); else return null; } public static ManagementPackRelationship GetManagementPackRelationship(string id, ManagementPack mp) { ManagementPackRelationshipCriteria mprcriteria = new ManagementPackRelationshipCriteria(String.Format("Name = '{0}'", id)); #if ( _SERVICEMANAGER_R2_ ) IList<ManagementPackRelationship> mprelationships = mp.Store.EntityTypes.GetRelationshipClasses(mprcriteria); #else MethodInfo method = mp.GetType().GetMethod("GetManagementGroupObject",BindingFlags.NonPublic|BindingFlags.Instance); EnterpriseManagementGroup emg = method.Invoke(mp,null) as EnterpriseManagementGroup; IList<ManagementPackRelationship> mprelationships = emg.EntityTypes.GetRelationshipClasses(mprcriteria); #endif foreach (ManagementPackRelationship mprelationship in mprelationships) { if (mprelationship.GetManagementPack().Id == mp.Id) return mprelationship; } //Didnt find any matches return (null); } public static ManagementPackRelationship GetManagementPackRelationship(string id, ManagementPack mp, EnterpriseManagementGroup emg) { ManagementPackRelationshipCriteria mprcriteria = new ManagementPackRelationshipCriteria(String.Format("Name = '{0}'", id)); IList<ManagementPackRelationship> mprelationships = emg.EntityTypes.GetRelationshipClasses(mprcriteria); foreach (ManagementPackRelationship mprelationship in mprelationships) { if (mprelationship.GetManagementPack().Id == mp.Id) return mprelationship; } //Didnt find any matches return (null); } public static ManagementPackClass GetManagementPackClass(string id, ManagementPack mp) { ManagementPackClassCriteria mpccriteria = new ManagementPackClassCriteria(String.Format("Name = '{0}'", id)); #if ( _SERVICEMANAGER_R2_ ) IList<ManagementPackClass> mpclasses = mp.Store.EntityTypes.GetClasses(mpccriteria); #else MethodInfo method = mp.GetType().GetMethod("GetManagementGroupObject",BindingFlags.NonPublic|BindingFlags.Instance); EnterpriseManagementGroup emg = method.Invoke(mp,null) as EnterpriseManagementGroup; IList<ManagementPackClass> mpclasses = emg.EntityTypes.GetClasses(mpccriteria); #endif foreach (ManagementPackClass mpclass in mpclasses) { if (mpclass.GetManagementPack().Id == mp.Id) return (mpclass); } //Didn't find any matches return (null); } public static ManagementPackClass GetManagementPackClass(string id, ManagementPack mp, EnterpriseManagementGroup emg) { ManagementPackClassCriteria mpccriteria = new ManagementPackClassCriteria(String.Format("Name = '{0}'", id)); IList<ManagementPackClass> mpclasses = emg.EntityTypes.GetClasses(mpccriteria); foreach (ManagementPackClass mpclass in mpclasses) { if(mpclass.GetManagementPack().Id == mp.Id) return(mpclass); } //Didn't find any matches return (null); } public static ManagementPackTypeProjection GetManagementPackTypeProjection(string id, ManagementPack mp) { ManagementPackTypeProjectionCriteria mptpcriteria = new ManagementPackTypeProjectionCriteria(String.Format("Name = '{0}'", id)); #if ( _SERVICEMANAGER_R2_ ) IList<ManagementPackTypeProjection> mptps = mp.Store.EntityTypes.GetTypeProjections(mptpcriteria); #else MethodInfo method = mp.GetType().GetMethod("GetManagementGroupObject",BindingFlags.NonPublic|BindingFlags.Instance); EnterpriseManagementGroup emg = method.Invoke(mp,null) as EnterpriseManagementGroup; IList<ManagementPackTypeProjection> mptps = emg.EntityTypes.GetTypeProjections(mptpcriteria); #endif foreach (ManagementPackTypeProjection mptp in mptps) { if (mptp.GetManagementPack().Id == mp.Id) return (mptp); } //Didn't find any matches return (null); } public static ManagementPackTypeProjection GetManagementPackTypeProjection(string id, ManagementPack mp, EnterpriseManagementGroup emg) { ManagementPackTypeProjectionCriteria mptpcriteria = new ManagementPackTypeProjectionCriteria(String.Format("Name = '{0}'", id)); IList<ManagementPackTypeProjection> mptps = emg.EntityTypes.GetTypeProjections(mptpcriteria); foreach (ManagementPackTypeProjection mptp in mptps) { if (mptp.GetManagementPack().Id == mp.Id) return (mptp); } //Didn't find any matches return (null); } public static ManagementPackObjectTemplate GetObjectTemplateFromRequestOffering(EnterpriseManagementObjectProjection requestOffering) { string TemplateIdentifier = requestOffering.Object[null, "TargetTemplate"].Value.ToString(); string TemplateName = TemplateIdentifier.Split('|')[3]; ManagementPackObjectTemplateCriteria c = new ManagementPackObjectTemplateCriteria("Name = '" + TemplateName + "'"); return requestOffering.Object.ManagementGroup.Templates.GetObjectTemplates(c)[0]; } } } |