使用 Service Manager SDK 列出用户的所有事件

Using Service Manager SDK to list all incidents for a user

我正在使用 Service Manager/System Center 2012,Service Pack 1。(版本 7.5.2905.0

我正在尝试做一些应该很简单的事情,但是关于如何实际进行查询的文档似乎为零。因此,我有一个用户对象(该用户的 EnterpriseManagementObject),我想查询服务管理器以了解该用户是受影响用户的所有事件。

代码是:(来自我找到的一个例子)

            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);

这会引发异常:

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

参数名称:pathReference

我很确定 属性 字段是错误的,但似乎没有关于如何创建 XML 或如何指定 属性 的文档, 或任何东西。

如果我将搜索更改为:

,围绕此的代码将正常工作
    //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>");

(当然,没有注释掉)

此外,另一个问题:如果我执行上面的查询并且 return 所有匹配的事件都已解决 - 它在能够枚举之前内存不足 - 显然,它是这样写的,所以它拉所有匹配到列表或其他东西的东西然后你枚举它 - 而不是根据需要提取更多数据。我有什么办法可以拉动一切吗? (我最初的方法是提取所有内容,然后自己对其进行过滤——这是一次性的,如果需要的话,我可以忍受它花费一个小时。(但是,对于一个长期项目,我也需要这个查询,所以我'我真的需要知道如何查询影响给定用户的所有事件,然后还查询所有分配给 X 的用户,等等。你在哪里学这些东西??)

谢谢

更新:

这个查询失败了,我该如何让它工作。 (这是我最终要开始工作的事情)

<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>

=======更新与解决========

明白了,你必须告诉它事件类型所在的位置,所以这个查询有效:

<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>

我建议您了解类型投影...为什么?因为类型投影就像服务管理器中的视图。您评论的标准非常有效,因为您只使用了一个简单的 EnterpriseManagementObject 并且他的属性在 System.WorkItem.Incident class 中可用,而 System.WorkItem.Incident.Library 管理包又存在。您的代码抛出的异常是正确的,因为他无法在事件的基本定义中找到该路径 class.

解决方案?输入投影。

此路径:$Context/Path[Relationship='WorkItem!System.WorkItemAffectedUser' TypeConstraint='System!System.Domain.User']/Property[Type='System!System.Domain.User']/UserName$属于事件与受影响用户之间的关系。

所以如果你运行这个查询你可以找到这个类型投影的名称:

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%'

您会发现您正在搜索的 Type Projection 的名称是 System.WorkItem.Incident.ProjectionType,他住在 ServiceManager.IncidentManagement.Library 管理包中。

现在是时候去 VS 了。现在我们必须更改我们为 EnterpriseManagementObjectProjection 使用的对象 (EnterpriseManagementObject) 所以:

     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
            }
        }

现在您的路径将完美运行,这将 return 您想要的对象:-)。希望对您有所帮助。

来自智利的欢呼!