Quantcast
Channel: The Official System Center Service Manager Blog
Viewing all 562 articles
Browse latest View live

Tasks Part 2 – Custom Console Tasks for Create, Edit, Delete

$
0
0

Awhile back I started a series of blog posts on explaining tasks – check out the first post which was an overview of tasks:

http://blogs.technet.com/servicemanager/archive/2010/02/11/tasks-part-1-tasks-overview.aspx

In this blog post, I’ll describe how to create some of the most common types of custom console tasks that you might want to create.  I’ll show an example of using one of the standard “platform” tasks by just referencing it in the MP and also how you can create  your own custom console task handlers.  Along the way, I’ll also show you a few tricks about how to enable tasks to support double click events in a view and how to enable tasks for multi-select.

First – let’s set the context of this blog post.  I’ve extended the Service Request solution to support a new class called ‘Cost Center’ for purposes of this example.  Cost Center derives from System.Entity just to show you how to do this without inheriting anything special from the model.  Generally speaking you don’t want to derive your classes directly from System.Entity.  This is mostly just as an example.  Although the Service Request solution is functional and people can use it, the Service Request solution is intended more for showing how to use the platform to extend Service Manager.

Step 0 – Include some MP references for MPs that we will need to reference for this solution

      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.0.6555.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Console">
        <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Console</ID>
        <Version>7.0.6555.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Authoring">
        <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring</ID>
        <Version>7.0.6555.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>

Step 1 – Create the new class:

        <ClassType ID="Microsoft.Demo.CostCenter" Accessibility="Public" Abstract="false" Base="System!System.Entity" Hosted="false" Singleton="false" Extension="false">
          <Property ID="CostCenterID" Type="int" AutoIncrement="false" Key="true" CaseSensitive="false" MaxLength="256" MinLength="0" Required="false" />
          <Property ID="ChargebackRate" Type="decimal" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="30" MinLength="0" Required="true" />
        </ClassType>

Step 2 – Next we are going to add a view for our Cost Centers.  The way I usually do this is to import the MP after I have defined the class.  Then in the Work Items or Configuration Items view I make a view for the Cost Center class.  Then I export the MP and change the parent folder as needed.  I’m not going to go into creating views in this blog post.   For now, just know that we have created a view that looks like this.

<View ID="CostCentersView" Accessibility="Public" Enabled="true" Target="Microsoft.Demo.CostCenter" TypeID="Console!GridViewType" Visible="true">

You can see the details of the view in the MP XML file linked to on the Code Plex site below.

Step 3 – Now we are going to create a couple of Console Tasks – one for Edit(aka Properties) and one for Delete.  The Console Task Definitions look like this.

      <ConsoleTask ID="EditCostCenterTask" Accessibility="Public" Enabled="true" Target="Microsoft.Demo.CostCenter" RequireOutput="false">
        <Assembly>Console!SdkDataAccessAssembly</Assembly>
        <Handler>Microsoft.EnterpriseManagement.UI.SdkDataAccess.ConsoleTaskHandler</Handler>
        <Parameters>
          <Argument Name="Assembly">Microsoft.Demo.ServiceRequest</Argument>
          <Argument Name="Type">Microsoft.Demo.ServiceRequest.CostCenterTaskHandler</Argument>
          <Argument>Edit</Argument>
        </Parameters>
      </ConsoleTask>
      <ConsoleTask ID="DeleteCostCenterTask" Accessibility="Public" Enabled="true" Target="Microsoft.Demo.CostCenter" RequireOutput="false">
        <Assembly>Console!SdkDataAccessAssembly</Assembly>
        <Handler>Microsoft.EnterpriseManagement.UI.SdkDataAccess.ConsoleTaskHandler</Handler>
        <Parameters>
          <Argument Name="Assembly">Microsoft.Demo.ServiceRequest</Argument>
          <Argument Name="Type">Microsoft.Demo.ServiceRequest.CostCenterTaskHandler</Argument>
          <Argument>Delete</Argument>
        </Parameters>
      </ConsoleTask>

The ID property of the task can be anything you want it to be like any MP element.  The target of these two tasks should be the ClassType ID of the class for which you want to enable these tasks.  That way whenever an object of that class is selected these console tasks will show up in the tasks pane.  The Assembly and Handler should always be the same.  The Assembly Argument should be the name of the assembly which contains the ConsoleCommand.ExecuteCommand() method you want to invoke.  More on that later.  The Type Argument is the fully qualified ConsoleCommand class name (including namespace) in the assembly.  Again, more on that later.  The argument can be anything you want to “pass in” to the ExecuteCommand() method that provides context of what you want the task to do when it is clicked.  More on that later.

Step 4 – Now we need to create some special Category elements in the MP to do certain things.

The first Category is one that tells Service Manager that the MP that it is dealing with is specifically intended to be run in SCSM:

    <Category ID="Category.SCSM.MP.ServiceRequest" Value="Console!Microsoft.EnterpriseManagement.ServiceManager.ManagementPack">
      <ManagementPackName>Microsoft.Demo.ServiceRequest</ManagementPackName>
      <ManagementPackVersion>1.0.0.0</ManagementPackVersion>
    </Category>

Without this category SM will hide any ConsoleTasks defined in this MP from the console because it will think that you are importing an MP designed originally for SCOM and it shouldn’t show the Console Tasks defined in the MP because they might not be appropriate for use in SCSM.

If you are going to be sealing your management pack you will need to include the Public Key Token as part of the MP Category declaration like this:

    <Category ID="Category.SCSM.MP.ServiceRequest" Value="Console!Microsoft.EnterpriseManagement.ServiceManager.ManagementPack">
      <ManagementPackName>Microsoft.Demo.ServiceRequest</ManagementPackName>
      <ManagementPackVersion>1.0.0.0</ManagementPackVersion>
      <ManagementPackPublicKeyToken>9396306c2be7fcc4</ManagementPackPublicKeyToken>
    </Category>

The next category will make a ‘Create <Class Name>’ task show up in the task pane in the view that it is targeted at.  When the user clicks on the task, the task handler will determine what class or type projection the view is targeted at and will then open the form that corresponds to that class or type projection.

<Category ID="Category.CostCenterCreateType" Target="CostCentersView" Value="Authoring!Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring.CreateTypeCategory" />

Notice how the Target attribute points to the ID of the view that we created above.  This is all you need to do to get a Create task in your view to create objects.

You may want to enable the view to support double click on the rows.  You just need to specify which task should handle the double click event by including a Category like this:

<Category ID="Category.DoubleClickEditCostCenter" Target="EditCostCenterTask" Value="Console!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.DoubleClickTask" />

Just point the Target attribute at the task that you want to be the handler for a double click event on a row in the view.

Lastly, you may want to enable some of your tasks to support multi-select.  To do so you just need to include a Category like this:

<Category ID="Category.MultiSelectTask.DeleteCostCenter" Target="DeleteCostCenterTask" Value="Console!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.MultiSelectTask" />

The Target attribute just needs to point at the task that you want to be able to support multi-select.

Step 5 – You will need to specify DisplayStrings for your Class Type, Console Tasks and the View

        <DisplayString ElementID="EditCostCenterTask">
          <Name>Properties</Name>
        </DisplayString>
        <DisplayString ElementID="DeleteCostCenterTask">
          <Name>Delete</Name>
        </DisplayString>
        <DisplayString ElementID="CostCentersView">
          <Name>Cost Centers</Name>
        </DisplayString>

More information on language packs can be found here.

Step 6 – You may want to include some Image References for the tasks so that they show pretty icons that look consistent with the rest of the Service Manager console.  This is optional.

      <ImageReference ElementID="EditCostCenterTask" ImageID="Console!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.Image.Properties"/>
      <ImageReference ElementID="DeleteCostCenterTask" ImageID="Console!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.Image.Remove"/>

Step 7 – Now you need to create a new Visual Studio project with a Class in it.  Add references to the following assemblies which can be found in either the C:\Program Files\Microsoft System Center\Service Manager 2010 directory or the C:\Program Files\Microsoft System Center\Service Manager 2010\SDK Binaries directory:

  • Microsoft.EnterpriseManagement.Core
  • Microsoft.EnterpriseManagement.ServiceManager.Application.Common
  • Microsoft.EnterpriseManagement.UI.FormsInfra
  • Microsoft.EnterpriseManagement.UI.Foundation
  • Microsoft.EnterpriseManagement.UI.SdkDataAccess

Now add using statements for the following:

using System;
using System.Collections.Generic;
using System.Windows;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.ConnectorFramework;
using Microsoft.EnterpriseManagement.ConsoleFramework;
using Microsoft.EnterpriseManagement.UI.SdkDataAccess;
using Microsoft.EnterpriseManagement.UI.DataModel;
using Microsoft.EnterpriseManagement.ServiceManager.Application.Common;

Next, you’ll need to change your Class so that it derives from ConsoleCommand:

namespace Microsoft.Demo.ServiceRequest
{
    class CostCenterTaskHandler : ConsoleCommand

Notice how this Namespace and class are used in the Type Argument above in the MP XML declaration of the Console Task.

Then create an overload for the ExecuteCommand method like this:

public override void ExecuteCommand(IList<NavigationModelNodeBase> nodes, NavigationModelNodeTask task, ICollection<string> parameters)

Then handle the command by first creating an EnterpriseManagementGroup from the existing console context:

//*** IMPORTANT NOTE: The IManagementGroupSession is not a part of the publicly document/supported official SDK and is subject to change in a future release.
IManagementGroupSession session = (IManagementGroupSession)FrameworkServices.GetService<IManagementGroupSession>();
EnterpriseManagementGroup emg = session.ManagementGroup;

Then you can decide what to do based on the Argument (remember this from the Console Task XML declaration above?) that is passed in:

if (parameters.Contains("Edit"))
...do something
else if (parameters.Contains("Delete"))
...do something else

In the case of Edit we will do this:

//There will only ever be one item because we are going to limit this task to single select
foreach (NavigationModelNodeBase node in nodes)
{
    //*** IMPORTANT NOTE: The ConsoleContextHelper class is not a part of the publicly document/supported official SDK and is subject to change in a future release.
    ConsoleContextHelper.Instance.PopoutForm(node);
}

This basically just gets the selected item and uses a console helper method to open that object in the appropriate form.

In the case of Delete we will do this:

MessageBoxResult result = MessageBox.Show("Are you sure you want to delete the selected Cost Centers?", "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result != MessageBoxResult.Yes)
    return;

//Create an IncrementalDiscoveryData "bucket" for capturing all the deletes that will be processed at the same time
IncrementalDiscoveryData idd = new IncrementalDiscoveryData();

foreach (NavigationModelNodeBase node in nodes)
{
    EnterpriseManagementObject emoCostCenter = emg.EntityObjects.GetObject<EnterpriseManagementObject>(new Guid(node["$Id$"].ToString()), ObjectQueryOptions.Default);
    idd.Remove(emoCostCenter);
}

idd.Commit(emg);
RequestViewRefresh();

This basically just confirms the deletion first.  Then it creates a “bucket” called an IncrementalDiscoveryData that we can put things in to be bulk processed later when we call .Commit().  In this case, we just need to get a EnterpriseManagementObject for each selected item (aka “node”) in the view.  Then we add it to the bucket as a remove action that will happen later.  At the end we can call a console helper method to update the view.

Step 8 – Now we need to build the assembly.  Then we need to add a Reference to the assembly in the MP.

  <Resources>
    <Assembly ID="Assembly.ServiceRequest" Accessibility="Public" FileName="Microsoft.Demo.ServiceRequest.dll" HasNullStream="false" QualifiedName="Microsoft.Demo.ServiceRequest, Version=1.0.0.0" />
  </Resources>

Step 9 – Because we are referencing the assembly we need to include the MP .xml file and the assembly file in a Management Pack Bundle.  See this blog post for more information on creating management pack bundles and getting the PowerShell script New-MPBundle.ps1.  Starting in SP1 if your console task executes a executable file or assembly that is not signed and the console task is defined in an MP that is not sealed you will get this warning message when running the task:

image

So – if you want this dialog to not show up when users click your console task you need to seal your MP and/or sign the assembly.

Now you can import the MP Bundle and after restarting the console you’ll see a new view:

image

And a new console task for creating a cost center:

image

And when you have a cost center selected you’ll see two tasks:

image

So – this blog showed you some examples of creating custom console tasks that use some of the built in framework helper methods.  You could execute any code you wanted to in the task handler code though.  For those cases above where there are console helper methods being used that are subject to change – these methods are probably going to change namespaces in the “r2” release of SCSM.  That is going to break any code that uses them until the namespace declarations are changed.  You’ll probably need to update your code and make a new release that will work with the “R2” release.  More information will be announced about these changes later.

Some other examples of creating custom console task handlers can be found in these blog posts:

CSV Connector: http://blogs.technet.com/b/servicemanager/archive/2010/05/28/new-code-plex-project-csv-connector.aspx

SLA Management: http://blogs.technet.com/servicemanager/archive/2010/05/06/incident-sla-management-in-service-manager.aspx

These updates to the Service Request Code Plex project have been uploaded to the Code Plex site as Change Set #82260.  They are not part of a new release yet.  I’m going to do some additional modification to this project soon and then create a new release.


Form Validation in Custom Forms

$
0
0

When you create a custom form you may want to have code behind to evaluate the user’s data entry based on some business logic before the object is created/updated.  To demonstrate how to do this I have extended the Service Request CodePlex project to provide a simple example of form validation.

In the code behind for the Service Request form, we already had added an Event  Handler for the PreviewSubmitEvent

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            this.AddHandler(FormEvents.PreviewSubmitEvent, new EventHandler<PreviewFormCommandEventArgs>(this.OnPreviewSubmit));
        }

This event is called when the user clicks the OK button on a form.  It allows you to do some last minute validation or property manipulation before the object is saved to the database.  Originally I just had a piece of code in there that would take the Title the user entered and concatenate that together with the work item ID to form the Display Name value for the service request like this:

itemServiceRequest["DisplayName"] = itemServiceRequest["Id"] + " - " + itemServiceRequest["Title"];

Now, let’s say I only want to allow the user to save the service request if they have provided a Title value.  I can do that like this:

        private void OnPreviewSubmit(object sender, PreviewFormCommandEventArgs e)
        {
            /* NOTE: The use of the IDataItem interface here is not supported/documented.
            * This interface may change in the future and no migration path is guaranteed by Microsoft.
            */
            IDataItem itemServiceRequest = this.DataContext as IDataItem;
            if (String.IsNullOrEmpty(this.txtTitle.Text.Trim()))
            {
                e.Cancel = true;
                MessageBox.Show("Please provide a title"); 
            }
            else
            {
                itemServiceRequest["DisplayName"] = itemServiceRequest["Id"] + " - " + itemServiceRequest["Title"];
            }
        }

This is how you can hook up whatever form validation you want to do.  Just include it in the event handler for the PreviewSubmitEvent event and if it fails validation set the PreviewFormCommandEventArgs.Cancle = true.  The default for PreviewFormCommandEventArgs.Cancel is false so unless you set it to true it will go through.

With this code in place if the user doesn’t enter a Title the user will see a warning message box like this:

image

The form will stay open so the user can fix any validation errors and nothing will be saved to the database yet.  Once the user provides a title and clicks OK the form will close and the object will be updated in the database.

The change list #82264 contains the latest code sample.

Manually Creating Service Connection Points (SCP) for SCSM

$
0
0

This blog post was written up by one of our Senior Escalation Engineers in Microsoft Support – Richard Usher.  Thanks Richard!

=======

After installation and when you are trying to connect to a list of Service Manager Servers, the list may be empty:

clip_image002

Even when clicking the Registered Servers Icon, no servers are returned. This usually means that the Service Connection Point for the Service Manager Server did not get created in Active Directory during install.

A service publishes its specific details in Active Directory as a Service Connection Point (SCP) to enable clients of the service to locate and connect to the service. Service Manager utilises SCPs on the Service Manager Server and the Data Warehouse Server and normally creates these during install.  Perhaps due to a permissions issue the SCP may fail to be created during install, this leaves the Admin UI unable to automatically locate the Server using the above window, although manually typing the Server name still works OK.

Using ADSIEdit you should see a SCP for the Service Manager Server.

clip_image004

If this was not created during install, then you can manually add this.

Manually Adding an SCP

Start ADSI Edit and connect to the domain in which Service Manager was installed.

clip_image006

Drill down to the Service Manager Server in the Computers container.

clip_image008

Right-click it and select New, Object

clip_image010

Select the serviceConnectionPoint class from the list and click Next

clip_image012

In the Create Object window set the Value to SMSDKServiceSCP and click Next

clip_image014

Click the More Attributes button

clip_image016

In the Select a property to view, drop-down list select keywords and set the value to SMSDKSCP. Click Add.

clip_image018

Change the Select a Property to view to serviceBindingInformation and add the fqdn of the Service Manager Server followed by :5724 and click Add

clip_image020

Change the Select a Property to view to serviceClassName and add the name of the Service Manager Management Group Name and click Set

clip_image022

Finally, change the Select a Property to view to serviceDNSName and add the fqdn of the Service Manager Server and click Set.

clip_image024

Click OK, and Click Finish.

Return to the Admin Console and attempt to connect. Click the Registered Servers icon again and now you should get the SM Server(s) you added, returned.

clip_image026

NB If you have also installed a DW Server, you may also be missing the appropriate SCP for that Server too. Check the quick ref below for those specific settings, Take care to specify the DW Management Group name for the serviceClassName, rather than the Service Manager Management Group, as well as the other attribute values.

Quick Ref for properties to add:

Service Manager Server

Object Name                                     SMSDKServiceSCP

Attribute Value

serviceBindingInformation          fqdn_of_SMServer:5724

serviceClassName                           ManagementGroupName

serviceDNSName                             fqdn_of_SMServer

keywords                                            SMSDKSCP

Data Warehouse Server

Object Name                                     SMSDKServiceSCP

Attribute                                             Value

serviceBindingInformation          fqdn_of_SMDWServer:5724

serviceClassName                           DWManagementGroupName

serviceDNSName                             fqdn_of_SMDWServer

keywords                                            SCDWSDKSCP

Just Released: Exchange Connector and Send Email Solution (Update on “Resource Kit”)

$
0
0

Awhile back I announced that there would be a “resource kit” for Service Manager which would include a bunch of things that we already had put out on the blogs like…

and some new things…

  • Exchange connector: Process emails sent to an email inbox on an Exchange server.  Convert new emails to new incidents and update incidents for replies to an email address.
  • Send message to a user related to the incident from the console.  Message can be optionally logged in the action log.
  • Visio diagram of the entire SCSM data model including classes, properties, and relationships.

We’ve decided that instead of packaging up all of this stuff as one downloadable “resource kit” package we would create a Tools/Downloads page on TechNet.  Then we can add to it whenever we want and point to all kinds of locations like CodePlex, third party software vendors, blogs with tools attached, and microsoft.com/downloads to get releases from Microsoft.  It will be one convenient place to get all the tools and solutions available for Service Manager and we can update it continuously without the overhead of a release.

While it will take just a couple more weeks to set up the Tools page on TechNet….

I’m pleased today to announce the release to microsoft.com/downloads the Exchange Connector and the Send Email solution!  You can get it from here:

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=0b48d1f1-434a-4ee6-8017-fc13f4c16785&displaylang=en

Note: allow up to 30 minutes from the posting of this blog post for worldwide replication on the microsoft.com/downloads site.

Exchange Connector

It’s taken awhile to build these solutions because I had them thoroughly tested by about 15-20 customers.  These customers found bugs and submitted feature requests that I went ahead and implemented to expand the scope of the Exchange connector to include a lot of additional capabilities beyond the scope defined originally.  The Exchange Connector now features the following capabilities:

  • Create incident from email (replaces out of the box functionality; just turn it off)
    • The sending user is looked up in the CMDB and related to the incident as the affected user
    • The email subject becomes the incident title
    • The email body becomes the incident description
  • Update incident action log from email
  • Resolve or close incidents from email
  • Approve/reject change requests from email
  • Update change request “action log” from email
  • Mark manual activities completed from email
  • Add email file attachment to work items as attachments
  • Emails can be sent in from outside the organization
  • Emails can be sent from users which do not exist in the CMDB yet and a new user record will be created for them and related to the incident

Send Email Solution

The Send Email solution is a separate solution that I’ve packaged with the Exchange Connector for convenience, but it can be deployed with or without the Exchange connector technically.  When you have both of them deployed and configured correctly you can enable the end-to-end lifecycle for emails around incident management.  For example, an analyst can be looking at a ticket and click a ‘Send Email’ task to request additional information from the affected user.  When the user replies to that email with the additional information, the incident is automatically updated.

Important Notes

  • I really recommend using the included deployment guides.  Deploying both of these solutions can be tricky and really require reading the deployment guide.
  • These solutions are not officially supported by Microsoft and are not a part of the Service Manager product.  You can provide feedback, report bugs, request new features, etc. on the forums but there are no guarantees on anything.
  • For those of you that have been testing pre-official-release versions of these solutions please follow the upgrade steps in the deployment guides.  You may need to close the console or stop the System Center Management service to replace the DLLs.
  • The Exchange connector and Send Email solution are not localized.  You can however specify keywords in different languages for the Exchange connector to use to process incidents with.

Thank You!

Lastly a big, huge thank you to all the community testers that made this possible.  You know who you are.  I really appreciate the effort you put in to test these solutions, provide feedback, and report bugs!  Thank You!

Enjoy!

Customizing Forms – Part 1 – Adding a New User Picker Control to the Incident Form

$
0
0

Customizing Forms in SCSM can be pretty tricky.  It seems like it is going to be really easy – just drag, drop, move, resize, etc. right?  Well – yes, if you know a little bit about what is going on with the technology involved and have seen some examples.  Otherwise it can be REALLY frustrating trying to do it.  I’m going to do a few blog posts on how to customize forms to provide some tips and tricks and explain some of the technology involved to hopefully make it easier to customize forms using the Authoring Tool.

I’ll use examples from the “real world” that customers or partners have raised and how I have shown them how to do it.  First I will start with the scenario where a customer is adding a new user relationship type between incident and user and wants to put a new user picker on the incident form.

First the customer tried to drag, drop, and configure and ended up with this in design mode (notice the new label and user picker control on the right labeled ‘Caller/Anforderer’):

clip_image002

Great! Right?  Well, no because when he imported it into Service Manager it looked like this:

clip_image002[5]

What happened?!!

Well – I don’t know exactly in this case since I didn’t look at the customization XML that was generated but one important thing to understand about XAML forms technology is that everything is controlled on a layout system comprised of containers and controls.  Containers are things like Grids and StackPanels.  Controls are things like text boxes, user pickers,labels, etc.  Containers can contain containers and controls.  Controls can even contain other controls but we won’t get into that in SCSM form customization scenarios.  Every control on the form is positioned in relative position to other controls and the size can be relative to the container control or a fixed size.  For example, you could say that a given control is going to start at 5 pixels away from the left of the container or other neighbor control and 5 pixels from the top.  This is what the Right, Left, Top, and Bottom Margin properties are for:

image

You can specify the size of the control by setting the Layout properties:

image

When you say something has Auto height or Width it will expand to fill up the container in that direction.  If you specify a minimum height or width the control will never get smaller than that in that direction.  These numbers are in terms of the number of pixels.  The alignment property can be Stretch (span across the container), Center, Left, or Right for the Horizontal alignment and Stretch, Center, Top, or Bottom for the Vertical alignment.  This determines what side(s) of the container the control will line up with.

I’ll go into more detail on these things in a later post but for now let’s get back to the example.  The reason the control didn’t end up where it was expected to was because in the designer the form was a certain width and when the customer loaded it up in the console it was a different width.  Because the new controls were positioned with the incorrect layout and margin property values it ended up being in an unexpected place because relative to the size of the new form it ended up on top of another control in the container!

How do we avoid this?

The easy way is to use the concept of a StackPanel to our advantage.  A StackPanel control is a container control in which every control inside it is stacked on top of each other either vertically or horizontally.  Typically in SCSM forms we put a given label and the control that corresponds to it inside of a StackPanel.  The entire form is typically actually a series of StackPanels inside of StackPanels!  Trying to add another control into the area to the right of the Alternate Contact Method field is actually pretty tricky because of the way the form is originally laid out in a grid with StackPanels inside.  This is what the form looks like when you first drag a control over it:

image

The green lines indicate Grid rows and columns.  If you drop your control onto the form in this mode the behavior is going to be a little bit unexpected because it is going to start positioning your control in more absolute terms which is going to behave strangely as the form resizes.  What you want to do instead is drop your controls inside of StackPanels on the form which are already programmed to resize correctly.  In this case my suggestion to the customer was to drop the new controls into the same StackPanel that contains the Affected User stack panel out of the box so that it would look like this when he was done:

clip_image002[7]

Here’s is how to do that step by step:

When you mouse over something that looks like this with a gray dotted line around it that is a StackPanel.  All of the controls inside of it will be stacked on top of each other (typically vertically, but it can also be horizontal).

clip_image002[9]

If you drop your control in there it will be added to the bottom of the StackPanel like this:

clip_image004

At this point there are three controls stacked on top of each other in the StackPanel – the ‘Affected User’ label, the Affected User user picker control and the new label (‘Label1’).

You can then drag a UserPicker control on there in the same way and have it go just under the label:

clip_image006

Now just set the label string, bind the user picker control and you’re set.

I put in a Top margin of 5 for the new label control to separate it from the user picker above a bit.

I also added in Top margin of –5 (yes, you can use negative numbers!) to move the user picker control closer to the label.

 

Now here are a couple of general tips on form customization:

1) CTRL + Z will undo customizations.  If you don’t like the way something turned out just hit CTRL + Z to undo it.  It’s better to undo the customization and try something different than continue to just tweak and tweak over and over.  Remember that the Authoring Tool is essentially recording your every move and those modifications will be replayed on the form in the console before it is shown to the user.

2) You can undo all the customizations on the form by right clicking on the customization form in the Management Pack Explorer and choosing ‘Undo all customizations’

image

 

Hopefully that helps!

Customizing Forms – Part 2 – Adding the Affected User Picker to the Change Request Form

$
0
0

This is a continuation of a series that I started here:

Customizing Forms – Part 1 – Adding a New User Picker Control to the Incident Form

In this example we’ll look at a different scenario a customer brought up.  In this case the goal is to add the Affected User relationship to the Change Request form using a User Picker control bound to the inherited Affected User relationship.

In this case the customer tried to do something similar to the approach used in the first post in this series by adding the control to the stack panel but ended up with this:

clip_image002

The new user picker control was ending up being displayed behind the Description field!

Here is how to make the Title StackPanel bigger so that it will have the additional room required to show the new controls:

First you need to move the Description StackPanel down.  Select the StackPanel around Description.  This is a little hard to grab.  I can get it easiest by clicking just below the textbox. It  should look like this when you have it selected:

clip_image002[5]

Change the Top margin from 5 to something like 45.  This will move it down relative to the Title stack panel:

clip_image004

The next thing you need to do is resize the Title StackPanel so it will show the additional new content you are going to show in there.  So – select the Title StackPanel.

clip_image006

And drag the lower right corner down a bit until it lines up with the top of the Description label:

clip_image008

Now drag and drop the label control into the Title StackPanel as I previously explained making sure you drop it when the gray dotted lines are showing around the stack panel.

clip_image010

Change the label so it says ‘Affected user:’

clip_image012

Now drag and drop the User Picker into the Title StackPanel.  Bind it to the AffectedUser relationship using the BindingPath attribute in the Details pane.  I also set the Top margin to -5 to make it move closer to the label and changed the width to 220 since there is plenty of room there.

In the end you get this in the designer:

clip_image014

And this in the console after importing the MP:

clip_image016

If you have other scenarios you would like me to use as examples in this series please leave them or send me an email.  My email address is twright@YouKnowWhere.com  :)

Figuring out Management Pack Dependencies

$
0
0

I hope none of you ever have to do this but it does come up occasionally and it’s good to know how to do this just in case….

Sometimes when you go to remove a management pack in the console you will discover that you can’t because there are some other management packs that depend on it.  You’ll see an error message like this:

image

You can look up which management packs depend on that management pack by opening the Properties dialog for that management pack:

image

If you really don’t care about what is in those management packs you can just delete them but chances are there are things in there that you care about but there are also potentially a few things in there which have a dependency on the MP you are trying to delete.  It would be really nice if we had a button right here that you could click on that said “Show me all the templates, notification templates, queues, groups, etc. in this MP that depend on the MP I am trying to delete”.    First of all that is way too long of a name for a button! Smile  It’s also not something that is easy to figure out in the database in some cases. 

It’s actually not too bad to figure it out with a little exploring in the Service Manager database if you know what you are doing though.

First, start by finding the GUID of the MP that you are trying to delete using a query like this:

SELECT MPName, ManagementPackID FROM ManagementPack WHERE MPName like ‘%<something…>%’

image

Now take the GUID of the MP that you are trying to delete and run a query like this:

SELECT ManagementPackIdReffedBy FROM ManagementPackReferences WHERE ManagementPackIdSource = ‘<the GUID you got from the first query>’

image

Then for each of the GUIDs that you get back run this query:

SELECT CONVERT (XML, MPXML) FROM ManagementPack WHERE ManagementPackId = ‘<the GUID from the previous query>’

image

Then click the hyperlink that results:

image

Then you can look for the alias that is used to reference the management pack you are trying to delete:

image

Then look for the alias throughout the management pack using CTRL + F (find).  Search for the Alias + ! like this:

image

You’ll find cases like this one:

image

Now search for the ID until you find the DisplayString element like this:

image

image

Now you know to look for ‘Company Web Application event workflow’ and you can delete that item from the UI so there is no longer a dependency between the MPs!

The Exchange Connector for System Center Service Manager is now available

$
0
0

AnnouncementOn Friday, 14 January 2010, the SCSM-Exchange connector was released to Microsoft.com/downloads.  The Exchange Connector and Send Email solution extend the current out of the box capabilities for System Center Service Manager 2010 by providing a connector experience for integrating with a Microsoft Exchange server to send and receive email messages.

[Nexus SC: The System Center Team blog]

J.C. Hornbeck | System Center Knowledge Engineer

The App-V Team blog: http://blogs.technet.com/appv/
The WSUS Support Team blog: http://blogs.technet.com/sus/
The SCMDM Support Team blog: http://blogs.technet.com/mdm/
The ConfigMgr Support Team blog: http://blogs.technet.com/configurationmgr/
The SCOM 2007 Support Team blog: http://blogs.technet.com/operationsmgr/
The SCVMM Team blog: http://blogs.technet.com/scvmm/
The MED-V Team blog: http://blogs.technet.com/medv/
The DPM Team blog: http://blogs.technet.com/dpm/
The OOB Support Team blog: http://blogs.technet.com/oob/
The Opalis Team blog: http://blogs.technet.com/opalis
The Service Manager Team blog: http: http://blogs.technet.com/b/servicemanager
The AVIcode Team blog: http: http://blogs.technet.com/b/avicode

clip_image001 clip_image002


SMLets Beta 2 Released

$
0
0

We have addressed all the bug reports and feature requests that were reported on the SMLets CodePlex site and compiled a new beta 2 of SMLets with SP1 of SCSM. 

Some of the more significant improvements are:

  • Added support for a –SupportGroup parameter on the Get-, Set-SCSMIncident classes
  • Added an Alias for all cmdlets so you can always use ___-SCSM____ instead of having to worry about which ones were ____-SC___ and which ones were ____-SCSM_____
  • Added a new cmdlet – Set-SCSMRunAsAccount which can be used to set the credentials for a Run As Account
  • Added a new generic cmldet for applying templates – Set-SCSMTemplate
  • Added logic to each of the parameters that use enums so that you can use either the GUID, the ID, or the display name of the enum

A full listing of all the bug fixes and other checkins can be found on the project site.

http://smlets.codeplex.com

Thanks to Jim Truher, PM on the SCSM team for doing most of this work! 

Please continue to post issues and feature requests on the CodePlex site so we can continue to improve the project. Any developers that would like to contribute can post their interest on the CodePlex site.

Great New Service Manager Blog–SCSMFAQ.ch

$
0
0

Marcel Zehner, a consultant located in Bern, Switzerland has started a new SCSM blog and already has a bunch of great posts on there.  I’ve added his blog to the blog roll on the left nav over there.

Here are some of his blog posts so far:

Make Service Manager Customer-aware

Mobile Devices and SIM Cards

Auto-Close resolved Incidents

Service Manager Workflows – Part 1

Adding a custom field to Incident Forms

Automated Change Requests using Microsoft Opalis

CSV Import of Objects

Custom Icons for Views and Folders

Relations between Objects

Creating Classes

I’ll link to some of his blog posts in the future just to raise awareness of the goodness going on over there.

Really great work Marcel!  Thanks for sharing with all of us!

 

If you have a great SCSM blog that you would like to share more broadly, let me know and I’ll add you to the blog roll – twright@you.know.where.com

Enabling Users to Take Action from Email Using Web Pages/Web Services

$
0
0

This is a guest blog post from a Microsoft Consulting Services Senior Consultant – Andreas Rynes.  He has become a Service Manager expert lately and has come up with a really innovative solution I wanted to share with you all.  The scenario that Andreas writes about in this blog post is a way to enable an end user to receive an email notification when his incident is resolved and then to click a link to either reactivate or close the incident.  The link passes the work item ID on the query string and the web page the user is directed to by clicking on the link either updates the incident status to closed or active depending on the link the user clicked.  The exciting thing about this is not just this particular solution but the pattern which can be followed to enable many other types of scenarios for SCSM.  Some other scenarios I could see working with this pattern are: change request approval/reject, going to a web page to provide additional information about an incident, viewing the status of a change request, etc. 

This solution is similar to some of these that we have already published if you are interested in looking at other examples of doing this kind of thing:

Incident Resolution Satisfaction Surveys on SharePoint

Automatically Sending Notifications to Reviewers

Inserting links to Review/Manual Activities in notifications

Thanks for writing this up Andreas and sharing with the community!

====================================================================================================================

During a SCSM session with my customer, while we gathering requirements for their implementation of SCSM, they asked me for the following requirement: whenever an incident is resolved by an analyst the affected end user should be notified with an email. This is nothing special and can be done easily with SCSM workflow features out of the box. So I thought: “yes, of course”, but then they continue with their requirements, that this email should include an option to close or reactivate an incident. The idea behind that requirement is that the end user is the one that can decide if the topic described within the incident was resolved or needs further attention by an analyst.

So the solution is not that complex, but it needs some very different parts to fulfill the requirement. First you need to use the SDK from Service Manager to define methods to close and activate an incident, the second part is the mail template, which can be defined within the Service Manager console and the third part is the workflow that triggers the notification, also managed within the console.

Part I – Visual Studio

1) First I’ve created a solution within Visual Studio. I’ve decided to create a Web Service to implement the functionality for the simple reason that a web service gives you the flexibility to use it both from a web and rich client application.

Start Visual Studio, click on File – New – Web Site … and choose ASP.NET Web Service and give it a meaningful name like SCSMIncidentService

VS creates a template for a asmx web service with three important files called service.cs, service.asmx and a web.config file. I won’t go into detail about SOA architecture or web services and how to implement that within Visual Studio. So I just mention all the details needed for this specific solution.

1) Now go on and remove the already generated first web method “HelloWorld” and implement the SCSM functionality.

2) After that you need to add references to the SDK, for that switch to the Solution Explorer, click on the right mouse button at the project and choose Add Reference and go to the tab Browse and go to the Service Manager installation folder (normally on C:\Program Files\Microsoft System Center\Service Manager 2010\SDK Binaries and choose all three files there.

clip_image002

3) Then add these using statements in the service.cs file by adding the following lines at the very top:

using Microsoft.EnterpriseManagement;

using Microsoft.EnterpriseManagement.Configuration;

using Microsoft.EnterpriseManagement.Common;

clip_image004

You can also add another namespace, System.Configuration (as shown in the screenshot). I’ll describe later why we could use this one as well.

4) We first start implementing a constructor for the service that initiates all the required classes like the ManagementGroup with either an FQDN or localhost (I’m hosting that service on the same server as the Service Manager Data Access Service) of the Service Manager.

In the second line you’ll see the usage of ConfigurationSettings.AppSettings, which is why we add the System.Configuration namespace to the service. This uses the AppSettings section of the web.config file to gather the Version and PublicKeyToken for the Management Pack. The advantage of using the web.config is that you don’t have to hardcode those values in the code and with every change you would have to re-compile it everytime. If you put those values in the web.config you can just change the xml file.

Then we need the ManagementPack for the Incident class and the enumeration of the status of incidents. We put all these in the constructor of the service class.

clip_image006

5) Then we are going forward to implement the two web methods, I’ve called them CloseIncident and ActivateIncident. Those methods accept the ID from the incident (e.g. IR10) and a string for the current user, who called the method. That mechanism is needed to avoid closing or activating incidents by accident from other users (I’ll describe that feature in a moment). Both methods call another private method called UpdateIncident. That method does the real work and accepts three parameters - those two from the Webmethods and another one that defines if the incident needs to be closed or activated.

clip_image007

6) UpdateIncident has some more lines, but not that much. It initiates another MP that hosts a TypeProjection. This is required to get the Affected User (as this is not part of the Incident class, but is a relationship to a user instance) to compare it with the actual user (we’ll get the user from the security principial context of the webpage).

From that MP we initiate the TypeProjection and with the help of a criteria string that defines the search criteria for the TypeProjection (in this case the incident class is the seed of the TypeProjection) we can use GetObjectProjectionReader to receive the specific incident. If the incident with the specified ID was not found then the method return false. If there is a record found we use a ManagementPackRelationship instance to get the Affected User. Then we compare it with the activeUser string and make sure that the incident is not closed already (because from an ITIL process view a closed incident should not be re-activated again).

The real work is done within two lines of code, set the status to the string that is passed in the UpdateIncident method (close or active) and overwrite the instance.

clip_image009

7) The last thing we need to clarify for the service is the CreateIncidentCriteriaXml method that just returns the criteria that is needed to receive the correct incident. For that we just use a simple expression that uses the ID attribute of the WorkItem as the left part and the searchString as the right part and the equal operator.

clip_image011

So with that, we’ve finished the service.

8) You would be able to test that asmx service already, just press F5. You will get an interface in the browser to test your two webmethod.

Next, we need to create two aspx websites that calls the service and give the user some sort of feedback, if the call was successful or not.

After adding those aspx webpages to your solution go and add a method to each of both, one for activateIncident and one for closeIncident. There are two parameters that we need to get to call the service, the ID of the incident and the name of the current user. For the first parameter we just crawl the QueryString (so we have to set the ID in the URL in the email template later) and for the current user we call the WindowsIdentity.GetCurrent() method. Then initiate the service and call one method per each aspx webpage.

9) After that you’re absolutely free to design the webpage and customize it that it fits your needs and UI definitions and requirements. In my case I’ve just added some positive text if the method returns 0 or some negative text for the value 1.

clip_image013

Part II – eMail Template

Now it’s time to create the email template

Before you create the email template, the second part of our solution, it’s time to configure the notification channels within the SCSM console. Go to Administration – Notifications – Channels and choose the e-Mail Notification Channel and double click it or click on Properties in the task pane. There you need to configure your SMTP server, a return email address and enable the e-mail notification.

clip_image015

After that click on the templates within Administration – Notifications to create your new template.

i) General

Give the template a name and describe it. The most important part on that first page of the wizard is to choose the correct target class, which is Incident in this case and put it in your own management pack.

ii) Template Design

In the Template Design tab you can design your mail, if it’s old-style text email or a HTML formatted mail, the mail subject and the body. For me, I’ve decided to generate an HTML-formatted mail with some fancy stuff like images and different font-styles. The result could looks like this or even better if you like:

clip_image017

You can define your own CSS styles and arrange the text and images where you want them to be. The best way it works for me was using an editor outside of the console and create the entire look and feel there. Then the HTML source can just be copy/pasted into Service Manager’s notification template wizard textbox.

You can see more information about how to create notification templates in this blog post:

http://blogs.technet.com/servicemanager/archive/2009/09/28/creating-notification-templates-in-system-center-service-manager.aspx

The most importing thing is the URL of those two hyperlinks, as we defined two webpages we need to use those and add the incident ID with ?ID=IR10 (we need to replace that in the console with dynamic data from the incident)

clip_image019

Then just paste the complete HTML code to the console template wizard and replace the dynamic text parts with those items from the incident instance with the Insert… button (don’t try to just type the value in – that won’t work. Use the Insert… button).

From there you can choose the attributes from the incident and related entities, which are then placed within the template (both body and subject field). For example you have to replace the URL with <a href="http://atssm/ServiceManagerSample/CloseIncident.aspx?ID=$Context/Property[Type='CustomSystem_WorkItem_Library!System.WorkItem']/Id$">Incident wieder eröffnen</a> (Please note that you have to customize the URL to your own webserver and webapplication!)

The result looks like the screenshot below:

clip_image021

After that you’re done with the template, just click on Next for the Summary tab and finish the wizard.

Part III – Workflow

Now we have the web services/site pages and the email template, now we need the workflow that triggers the entire solution.

Open the console and go to the workflow configuration view that can be found under Administration – Workflow – Configuration. There are some already defined workflow configurations that can be used and we go with the Incident Event Workflow Configuration. After selecting that entry click on Properties in the task pane.

clip_image023

Now you can setup a new workflow that runs whenever an Incident is updated or created.

So click on Add and fill out the Workflow Information that are asked, take care to choose “When an incident is updated” in our case and choose also the correct Management Pack (it makes sense to choose the same as for the template, so that the solution is built in one single MP). And of course, enabling the workflow with the checkbox makes a lot of sense here J

clip_image025

Now we have to define the criteria when the workflow should be triggered. For now we just said whenever an incident is updates (which would be true, if someone just updates a description or any other field on the incident form). So we need to define that this should run only if the Status is changed to Resolved.

clip_image027

So keep the “Changed from” empty as this is not important to us, but add the Status in the “Changed To” tab and enter resolved to the textbox next to it.

So now it’s time to tell the workflow configuration what to do, when it is triggered. In our solution we’d like to Select People to Notify. So in the specific tab make sure the checkbox Enable notification is set and choose Affected User in the ComboBox and choose the new created mail template a couple of minutes before. And don’t forget to click the Add button (I did this from time to time J).

clip_image029

After that setup we are all set and done. Finish the wizard and see if the window for the Incident Event Workflows is updated with your new workflow definition.

clip_image031

Now it’s time to test the complete solution by resolving an incident in the console. Make sure that you have an incident that has an Affected User filled out and that this user has an email-address in the Active Directory and in the Service Manager database, otherwise there will no email be generated. If that’s a test lab environment like it was in my case, you can enter an email address in the CMBD on the user entity form, but make sure that you disable the AD Connector for a test, as it might overwrite the email-address with a blank value again J

In my template, I’m using also the Resolution Category and Comments from the analyst, so I put some more or less useful text in those fields and resolve the incident.

clip_image033

A couple of seconds later the email is generated and showing the correct values from the incident and the option to close or re-activate the incident with a simple click on the specific link.

clip_image034

The user gets a response that his/her incident was closed now (or re-activated) with the HTML page I designed before.

The source files for this solution are attached.

Partner Demo: Lieberman Software –Enterprise Random Password Management Integration with SCSM

$
0
0

Lieberman Software’s Enterprise Random Password Management product allows a privileged user to “check out” a system password for a configurable period of time.  The password is randomly generated so that effectively only the user checking it out knows the password for that time period.  Once the period expires a new random password is generated effectively locking that person out from using the account.  This is great for incident management scenarios when someone needs to go fix a system but you don’t want them to necessarily have carte blanch access to the sensitive account all the time.   This integration with Service Manager make it easy to associate password check outs with particular incidents for traceability.  Further it will log any event in the ERPM system you choose in to SCSM as an incident.  For example, you could generate an incident based on a failed login.

Check out the demo video below, the press release, product information page on their web site, or the solution brief attached for more information.

This is a great solution for improving security!  It always amazes me the variety of different solutions that can be built on or integrated with SCSM!

FYI: Integration of TechNet Blog User Account with TechNet Forums Profile

$
0
0

InformationFor those of you who sign-in to comment on the TechNet Blogs, there is a change coming on January 27th 1:00 pm (PST) regarding user accounts and profiles. Please click here to read about this change.

If you have questions please leave a comment on the linked blog post so that the TechNet Blogs platform team can reply to you directly.

J.C. Hornbeck | System Center Knowledge Engineer

The App-V Team blog: http://blogs.technet.com/appv/
The WSUS Support Team blog: http://blogs.technet.com/sus/
The SCMDM Support Team blog: http://blogs.technet.com/mdm/
The ConfigMgr Support Team blog: http://blogs.technet.com/configurationmgr/
The SCOM 2007 Support Team blog: http://blogs.technet.com/operationsmgr/
The SCVMM Team blog: http://blogs.technet.com/scvmm/
The MED-V Team blog: http://blogs.technet.com/medv/
The DPM Team blog: http://blogs.technet.com/dpm/
The OOB Support Team blog: http://blogs.technet.com/oob/
The Opalis Team blog: http://blogs.technet.com/opalis
The Service Manager Team blog: http: http://blogs.technet.com/b/servicemanager
The AVIcode Team blog: http: http://blogs.technet.com/b/avicode

clip_image001 clip_image002

Model Visio Diagram Released! Job Aids Package Update (Update on “Resource Kit”)

$
0
0

One of the main new components promised in the “Resource Kit” was a Visio diagram of the data model.  I’m pleased to announce the release of that data model diagram today in an updated Job Aids download package.  The new Job Aids package now includes the following:

  • Model Visio diagram
  • Architecture Visio diagram
  • Visio Stencils for designing SM deployment topologies
  • EnumCreator Excel workbook for creating enums (aka List Items) in bulk
  • Change management Visio workflow diagrams
  • Incident management Visio workflow diagrams
  • Excel sizing tool for determining the optimum deployment topology

That completes the delivery of all the content that was promised in the “Resource Kit”.  The Tools/Downloads page that was announced here will be coming later this week.

Here is a quick guide to the Model Visio diagram.

Here is a very small portion of the model which describes users:

image

Each class is represented by a box in the diagram.  The bold name at the top indicates the ID of the class.  Each of the items below the ID is a property of the class.  The ID of the property is indicated followed by the data type of the property.  If the property is a key property that will be indicated by the text ‘(key)’ being included in the ID.

Black thin lines which have an arrow head on them like those above indicate class inheritance where the arrow points from the child class to the parent class.

Classes which have their name highlighted in yellow like the above are the more commonly used classes.  They are highlighted to make them easier to see.

The class boxes are color coded to make it easier to distinguish types of classes.  This is the key:

  • Green = Configuration Items
  • Pink = Work Items
  • Black = Collections like queues
  • Darker Blue = Supporting Items like action logs, comments, etc.
  • Purple = Information like file attachments
  • Lighter Blue = Amin Items like global settings, announcements, etc.

image

Relationships are indicated by colored lines between classes.  The relationship ID is shown next to the line.  In some cases class or relationship type names are too long to be displayed neatly in the diagram and will be shortened (MS = Microsoft, SC = SystemCenter, SM = ServiceManager, CM = ConfigurationManager, and so on).  Relationship types are color coded depending on their base type as follows:

  • Orange = System.Reference
  • Red = System.Containment
  • Green = System.Hosting
  • Blue = System.Membership

image

If you see an ‘(a)’ in the ID of a class that means it is abstract.

There are two places in the model diagram where you will see relationship type properties called out like this:

image

 

A few other notes:

  • Not all of the classes in the system are in the diagram. Only the most commonly used classes are represented.
  • This model diagram does not include the GRC classes or classes from any other solutions produced by Microsoft (like Exchange connector) or partners (like Provance, etc.)
  • Although I have meticulously validated this diagram against the actual model created by the product installation there may be some inaccuracies.  If you find any please leave a comment here and we’ll get it fixed.
  • A few hints about navigating a large Visio diagram like this:
    • Use the scroll wheel on your mouse to scroll up/down in the diagram.
    • If you have a Microsoft mouse with a tilt wheel you can pan left/right in the diagram by leaning on the scroll wheel to the right or left.
    • Hold down the CTRL key and mouse wheel up/down to zoom in/out
    • Hold down the CTRL + SHIFT key and drag-select a portion of the Visio diagram to zoom into that portion of the diagram.
    • Hold down SHIFT + arrow keys to quickly move around the diagram
    • Hold down CTRL + arrow keys to move to the top/bottom/right/left of the diagram

How to Get the Display Name of an Enumeration Value Programmatically

$
0
0

Awhile back I wrote a blog post about how to programmatically manipulate Enumerations (aka List Values.  See blog post – Programmatically Working with Enumerations.

One thing I didn’t really explain was how to get the DisplayString of an Enumeration value when you are coming at it from an object.  For example, let’s say you have an incident object and you want to display the display name of the current value of the Urgency impact property (which is an enum data type property).

What you need to keep in mind here is that you can’t treat it like other string, int, etc. data type properties.  Non-enum properties can be accessed like this:

emopIncident.Object[classIncident, “Title”].Value

If you want to you can explicitly cast the value to a string by slapping a .ToString() on the end.

emopIncident.Object[classIncident, “Title”].Value.ToString()

If you do that for an enum data type property you are going to get this kind of thing back: System.WorkItem.TroubleTicket.UrgencyEnum.High.  That’s the ID of the enum not the display name!

To get the display name of the enum you need to keep in mind that the value that is going to be coming back for an enum data type property is a ManagementPackEnumeration.  You just need to cast the .Value to ManagementPackEnumeration and then you can access the .DisplayName property.

Sample code – just a simple console app to demonstrate:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;

namespace GetEnumerationValueDisplayString
{
    class Program
    {
        static void Main(string[] args)
        {
            EnterpriseManagementGroup emg = new EnterpriseManagementGroup("localhost");
            ManagementPackClass classIncident = emg.EntityTypes.GetClass(new Guid("A604B942-4C7B-2FB2-28DC-61DC6F465C68")); //System.WorkItem.Incident
            ManagementPackTypeProjection mptpIncident = emg.EntityTypes.GetTypeProjection(new Guid("285CB0A2-F276-BCCB-563E-BB721DF7CDEC")); //System.WorkItem.Incident.ProjectionType
            ObjectProjectionCriteria opcAllIncidents = new ObjectProjectionCriteria(mptpIncident);
            IObjectProjectionReader<EnterpriseManagementObject> oprIncidents = emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(opcAllIncidents, ObjectQueryOptions.Default);
            foreach (EnterpriseManagementObjectProjection emopIncident in oprIncidents)
            {
                //This is how you handle string, int, etc. properties:
                Console.WriteLine(emopIncident.Object[classIncident, "Title"].Value.ToString());

                //DON'T do this for enum data type properties
                //Console.WriteLine(emopIncident.Object[classIncident,"Urgency"].Value.ToString());

                //Do this instead:
                ManagementPackEnumeration enumUrgency = (ManagementPackEnumeration)emopIncident.Object[classIncident, "Urgency"].Value;
                Console.WriteLine(enumUrgency.DisplayName);
            }
        }
    }
}

Sample VS project attached.


Service Manager Tools/Downloads Page Now Live on TechNet (Final Update on “Resource Kit”)

$
0
0

As I mentioned recently instead of having a “resource kit” we have set up a Tools/Donwloads page on TechNet.  From there we can link off to useful tools that Microsoft, partners, or the community has built.  We can then use different distribution channels and release things more fluidly, but still be able to find things easily.

That new Downloads page is now live on TechNet – please check it out!  As new tools become available we will post links to them up there.

http://technet.microsoft.com/en-US/systemcenter/sm/gg598223.aspx

Now that this page is live the “Resource Kit” project as originally announced is completed.  Big thanks to all those who helped make it possible.  Now that we have a Tools/Downloads page though this is really just the beginning.  Look for more things to come soon!

Breaking All the Rules Part 2: Forcing a Change Request Status from Closed to Completed

$
0
0

A while back I wrote a blog post called Breaking All the Rules: Reactivating Closed Incidents.  Although all the best practices say you shouldn’t do that kind of thing, there are just some cases where you need to break the rules.  There are similar cases for Change Management.  One of them which has been raised by customers a couple of times is when you need to be able to view the files attached to a Closed change request – usually for auditing purposes.  There really is no harm in allowing somebody to view the files in a closed change request, but due to a bug we have disabled the View button on a change request when it is closed:

image

Doh!

So – until we fix this bug – the only way to view those files after the change request status has been changed to Closed is to set the status back to Completed.  When you are done looking at the files you can change the status to Closed again.

Here is a way (similar to the approach I described for incidents) that you can change the status of a Change Request.

First download the smlets CodePlex project if you haven’t already.  Reminder: this project recently went to the Beta 2 stage so please download the latest if you haven’t already.

Then you just need to run some simple PowerShell cmdlets like this:

$CRClass = Get-SCSMClass System.WorkItem.ChangeRequest$

Get-SCSMObject -Class $CRClass –filter “Id -eq 'CR2080'” | Set-SCSMObject -Property Status -Value Completed

You can also use InProgress or Closed as the status values.

You can also create console tasks like I did for the incident example if you want to be able to have people do this action right from the console instead of in PowerShell.

Cumulative Update 1 for System Center Service Manager SP1 Released!

$
0
0

The first cumulative update for SP1 is now released.  This must be applied on top of a SP1 installation.  It fixes the following issues:

  • Extending a large-volume class hangs the console indefinitely
  • Adding 25th child item on a list results in an error
  • DW data loss for relationship fact tables with properties

You can download it from here:

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=82954fe2-2168-42cd-8456-762730ac37eb

There is also an Authoring Tool management pack library update with this so make sure you update the management packs in your library wherever you have the authoring tool installed.

Another Great SCSM Blog–SCSM.se!

$
0
0

Flag of Sweden

SCSM seems to be extra popular in Sweden and quite a few of our most knowledgeable experts in SCSM are up there.  It must be because it’s too cold to go outside so they just play around with SCSM all day! :)

Those of you on the SCSM forums have no doubt noticed how helpful Anders Asp and Stefan Allansson have been.  Now these SCSM experts from one of our SI partners, Lumagate, have started a blog on just SCSM – http://www.scsm.se .

Here are the really helpful topics that they have started with:

I’ve added their blog to the blog roll on the left over there.

Great work Anders and Stefan!  Thanks for sharing with all of us!

 

If you have a blog that you would like to have featured here please let me know – twright@YouKnowWhere.com.

New SCSM CodePlex Project: SCSM Facade

$
0
0

Gary Davidson, the Chief Software Architect at Interclick, has created a new SCSM CodePlex project called SCSM Façade.  The intention of the SCSM Façade project is to make programming against the SCSM SDK a little less abstract.  Because SCSM is a configuration driven platform all of the APIs are abstract.  For example – we don’t have a GetIncidents() method.  We only have a GetObjectReader() method which gets you objects that match the criteria you specify.  The criteria is what tells SCSM to return incidents instead of change requests.  So – in pseudocode you do something like this Incidents = GetObjectReader(Incident) instead of Incidents = GetIncidents().

The SCSM Façade CodePlex project tries to obscure some of the complexity of dealing with abstract APIs by exposing more concrete APIs.  This is a great example from Gary’s blog.

This is an example of how to write the code using the SCSM SDK APIs to get an incident by ID:

EnterpriseManagementGroup emg = new EnterpriseManagementGroup(Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\System Center\2010\Service Manager\Console\User Settings",

"SDKServiceMachine", "localhost").ToString());

// what guid is it?

ManagementPackTypeProjection typeProjection = emg.EntityTypes.GetTypeProjection(new Guid("285CB0A2-F276-BCCB-563E-BB721DF7CDEC"));

// try remembering all this

var criteriaXml = "<Criteria xmlns=\"http://Microsoft.EnterpriseManagement.Core.Criteria/\"> <Reference Id=\"System.WorkItem.Incident.Library\" Version=\"7.0.6555.0\" PublicKeyToken=\"31bf3856ad364e35\" Alias=\"IncidentMP\" /><Expression><SimpleExpression><ValueExpressionLeft><Property>$Target/Property[Type='IncidentMP!System.WorkItem.Incident']/Id/Property></ValueExpressionLeft><Operator>Equal</Operator><ValueExpressionRight><Value>IR201</Value></ValueExpressionRight></SimpleExpression></Expression></Criteria>";

ObjectProjectionCriteria criteria = new ObjectProjectionCriteria(criteriaXml, typeProjection, emg);

var incidentProjection = emg.EntityObjects.GetObjectProjectionReader<EnterpriseManagementObject>(criteria, ObjectQueryOptions.Default);

With SCSM Façade you just need to do this:

var incidentProjection = SCSMIncident.GetIncident("IR201");

Nice!

Thanks for starting up this project Gary!  Anyone who would like to contribute to the project can contact me or Gary via the CodePlex site.

http://scsmfacade.codeplex.com/

Viewing all 562 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>