1

I am using Service Manager/System Center 2012, Service Pack 1. (Version 7.5.2905.0

I am attempting to do something that should be simple, but there appears to be ZERO documentation on how to actually do the queries. So, I have a User object (EnterpriseManagementObject for that user), and I want to query service manager for all incidents that that user is the affected user.

Code is: (From an example I found)

            strIncidentSearchCriteria =
            String.Format(@"<Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">
                               <Expression>                                            
                                  <SimpleExpression>
                                      <ValueExpressionLeft>
                                       <Property>$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$</Property>
                                       </ValueExpressionLeft>
                                       <Operator>Equal</Operator>
                                      <ValueExpressionRight>
                                        <Value>" + user.FullName + @"</Value>
                                      </ValueExpressionRight>
                                  </SimpleExpression>
                               </Expression>                             
                            </Criteria>");

            EnterpriseManagementObjectCriteria emocWorkitem = new EnterpriseManagementObjectCriteria(incidentSearchCriteria, mpc, mp, emg);

This throws an exception:

The provided path ($Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$) was not valid.

Parameter name: pathReference

I'm pretty sure that the Property field is wrong, but there seems to be no documentation on how you could create the XML, or how to specify the Property, or anything.

The code around this works correctly if I change the search to:

    //strIncidentSearchCriteria = String.Format(@"<Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">" +
    //                "<Expression>" +
    //                "<SimpleExpression>" +
    //                    "<ValueExpressionLeft>" +
    //                    "<Property>$Context/Property[Type='System.WorkItem.Incident']/Status$</Property>" +
    //                    "</ValueExpressionLeft>" +
    //                    "<Operator>NotEqual</Operator>" +
    //                    "<ValueExpressionRight>" +
    //                    "<Value>" + new Guid("2b8830b6-59f0-f574-9c2a-f4b4682f1681") + "</Value>" +  // Resolved
    //                    //Closed:"<Value>" + new Guid("bd0ae7c4-3315-2eb3-7933-82dfc482dbaf") + "</Value>" +
    //                    "</ValueExpressionRight>" +
    //                "</SimpleExpression>" +
    //                "</Expression>" +
    //            "</Criteria>");

(Of course, not commented out)

Also, another issue: If I do the query above and return all the matching incidents that are resolved - It runs out of memory before it is able to enumerate - apparently, it was written so it pulls everything that matches into a list or something and then you enumerate that - instead of pulling more data as needed. Any way I can pull everything? (My original method was to pull everything and then filter it myself - this was a one-off and I could live with it taking an hour if needed. (However, I will also need this query for a long term project, so I'm really needing to know how to query all incidents that affect a given user, and then also all that the assigned user is X, etc. Where do you learn this stuff??)

Thanks

Update:

This query, fails, how to I make it work. (This is the thing that I'm ultimately trying to get working)

<Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/"> 
   <Expression>
      <And>
         <Expression>
            <SimpleExpression>
               <ValueExpressionLeft>
                  <Property>$Context/Property[Type='System.WorkItem.Incident']/Status$</Property>
               </ValueExpressionLeft>
               <Operator>NotEqual</Operator>
               <ValueExpressionRight>
                  <Value>2b8830b6-59f0-f574-9c2a-f4b4682f1681</Value>
               </ValueExpressionRight>
            </SimpleExpression>
         </Expression>

         <Expression>
            <And>
               <Expression>
                  <SimpleExpression>
                     <ValueExpressionLeft>
                        <Property>$Context/Property[Type='System.WorkItem.Incident']/Status$</Property>
                     </ValueExpressionLeft>
                     <Operator>NotEqual</Operator>
                     <ValueExpressionRight>
                        <Value>bd0ae7c4-3315-2eb3-7933-82dfc482dbaf</Value>
                     </ValueExpressionRight>
                  </SimpleExpression>
               </Expression>


          <Expression>
            <SimpleExpression>
              <ValueExpressionLeft>
                                <Property>$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/DisplayName$</Property>
              </ValueExpressionLeft>
                 <Operator>Like</Operator>
              <ValueExpressionRight>
                <Value>%Bill%</Value>
              </ValueExpressionRight>
            </SimpleExpression>
          </Expression>

            </And>       
      </And>
   </Expression>
</Criteria>

======= Update and solution ========

Figured it out, you have to tell it where the Incident type is located, so this query works:

<Criteria xmlns="http://Microsoft.EnterpriseManagement.Core.Criteria/"> 
   <Expression>
      <And>
         <Expression>
            <SimpleExpression>
               <ValueExpressionLeft>
                  <Property>$Context/Property[Type='CoreIncident!System.WorkItem.Incident']/Status$</Property>
               </ValueExpressionLeft>
               <Operator>NotEqual</Operator>
               <ValueExpressionRight>
                  <Value>2b8830b6-59f0-f574-9c2a-f4b4682f1681</Value>
               </ValueExpressionRight>
            </SimpleExpression>
         </Expression>

         <Expression>
            <And>
               <Expression>
                  <SimpleExpression>
                     <ValueExpressionLeft>
                        <Property>$Context/Property[Type='CoreIncident!System.WorkItem.Incident']/Status$</Property>
                     </ValueExpressionLeft>
                     <Operator>NotEqual</Operator>
                     <ValueExpressionRight>
                        <Value>bd0ae7c4-3315-2eb3-7933-82dfc482dbaf</Value>
                     </ValueExpressionRight>
                  </SimpleExpression>
               </Expression>


          <Expression>
            <SimpleExpression>
              <ValueExpressionLeft>
                                <Property>$Context/Path[Relationship='WorkItem!System.WorkItemAssignedToUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/DisplayName$</Property>
              </ValueExpressionLeft>
                 <Operator>Like</Operator>
              <ValueExpressionRight>
                <Value>%Bill%</Value>
              </ValueExpressionRight>
            </SimpleExpression>
          </Expression>

            </And>       
         </Expression>
      </And>
   </Expression>
</Criteria>
Traderhut Games
  • 1,222
  • 1
  • 15
  • 30
  • 1
    I got into the same problem. I am pretty sure that my path it's correct. I hope that this https://minimumrequiredeffort.wordpress.com/2014/08/10/mp-variables-and-mp-references/ give you some lights. – Max Becerra Aug 13 '15 at 20:33

1 Answers1

1

I recommend you to learn about Type Projections... ¿Why? Because Type Projections are like Views in Service Manager. Your commented criteria works perfect because you're only using a simple EnterpriseManagementObject and his properties are available in System.WorkItem.Incident class which in turn lives into System.WorkItem.Incident.Library management pack. The exception that your code is throwing is correct because he can't find that path inside the basic definition of an incident class.

The Solution? Type Projections.

This path: $Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$ belongs to a relationship between the incident and the affected user.

So if you run this query you can find the name of this Type Projection:

SELECT
LT.ElementName,
LT.LTValue,
LT.MPElementId,
MP.MPName,
MP.MPFriendlyName,
MP.MPKeyToken,
MP.MPVersion
FROM 
LocalizedText LT 
INNER JOIN 
ManagementPack MP ON LT.ManagementPackId = MP.ManagementPackId
WHERE 
LT.ElementName like '%Incident.Projection%'
AND
LT.LanguageCode like '%ENU%'

You'll find that the name of the Type Projection that you´re searching is System.WorkItem.Incident.ProjectionType and he lives in ServiceManager.IncidentManagement.Library management pack.

Now is time to go to VS. Now we have to change the object that we're using (EnterpriseManagementObject) for EnterpriseManagementObjectProjection so:

     string strCriteria =
     String.Format(@"<Criteria xmlns=""http://Microsoft.EnterpriseManagement.Core.Criteria/"">
          <Expression>
            <SimpleExpression>
              <ValueExpressionLeft>
                <Property>$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$</Property>
              </ValueExpressionLeft>
                 <Operator>Like</Operator>
              <ValueExpressionRight>
                <Value>%" + userName + @"%</Value>
              </ValueExpressionRight>
            </SimpleExpression>
          </Expression>
        </Criteria>");


        ManagementPack workItemMp = emg.GetManagementPack("System.WorkItem.Incident.Library", "31bf3856ad364e35", new Version("7.5.3079.0"));  // Incident MP
        ManagementPack projMp = emg.GetManagementPack("ServiceManager.IncidentManagement.Library", "31bf3856ad364e35", new Version("7.5.3079.0")); // <-- MP where Type Projection lives
        ManagementPackTypeProjection workItemRelConfigProj = emg.EntityTypes.GetTypeProjection("System.WorkItem.Incident.ProjectionType", projMp); // <-- Type Projection Name
        ObjectProjectionCriteria projCriteria = new ObjectProjectionCriteria(strCriteria, workItemRelConfigProj, projMp, emg);
        IObjectProjectionReader<EnterpriseManagementObject> reader = emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(projCriteria, ObjectQueryOptions.Default);

        if (reader != null && reader.Count > 0)
        {
            foreach (EnterpriseManagementObjectProjection obj in reader)
            {
                //TO DO
            }
        }

So now your path will works perfectly and this will return the objects that you want :-). I hope this help.

Cheers from Chile!

Max Becerra
  • 466
  • 10
  • 20
  • Thanks!! This is the best information I've gotten, and I was actually able to get it to return a couple matches. Didn't work correctly, but it did come back with something. The following code matched 'Ron Billist' but NOT 'Billie Jones' - the search was for 'bill' - WTF? – Traderhut Games Aug 20 '15 at 16:35
  • String.Format(@" $Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$ Like %{0}% – Traderhut Games Aug 20 '15 at 16:36
  • (I lothe the fact you can't put real replies to the answers here) WTF not? – Traderhut Games Aug 20 '15 at 16:37
  • If I change the WorkItemAffectedUser to WorkItemAssignedToUser then it fails. Also, I have the user's ID (a Guid) and it would seem a MUCH better idea to search for that - the field doesn't seem to be ID, or Id, and I have ZERO clue how to find out what things I can actually search for, and how to format the request. It seems that it is ONLY searching on last name, and not full name (or it is searching their actual username, which is something ike 'rbillist' and 'bjones' - which would explain the error. – Traderhut Games Aug 20 '15 at 16:41
  • And if I set it to 'b' search of: '%b%', it matched: "Virginia Romero" - Ah, Interesting. But WTF? – Traderhut Games Aug 20 '15 at 18:01
  • I got it to work if I changed the query to look for DisplayName instead of UserName - then it worked for both WorkItemAssignedToUser as well as the WorkItemAffectedUser - This is Awesome! Now I just have to add the check for the Status being not-closed and not-resolved! Thanks!!! – Traderhut Games Aug 20 '15 at 18:53
  • I got it to work - BUT, Now I have to have the query get all Incidents for the user and then check them locally for ones that are closed or Resolved and leave them out. When I tried to put the (working) query to limit to just open (Anding of two status checks - one for not closed, the other for not resolved) it comes back saying it can't find some Management pack Guid - and I agree, I can't find that one either - but it isn't in the query, or anywhere else so who cares you can't find it?? So, it works, but takes 10 seconds to run instead of 1 (the console) - better than 3 minutes! – Traderhut Games Aug 20 '15 at 19:50