Allowing Staff To Opt In To Emails

I remember when I first got involved in SDE or Magic, as it was known back in 2002, the ability to build business rules based on events that resulted in, amongst other things, emails being sent to support staff blew me away! I had a wail of a time the following month building LOTS of business rules that sent emails all over the place. Shortly after that, Support Staff fell into two categories: those that we pleased at the level of communication / audit that the service desk software could provide and those that hated my guts! Not everyone likes having their Inbox filled it would appear.

Recently I was asked to develop a way that Support Staff could opt in to receiving emails such that, in the event of a ticket being assigned to a group, only those staff in that group who have opted in, receive an email notification. This is one of those requests that when you know how to do it it is not too bad…figuring it out on your own if you don’t know what Service Desk Express is capable of is a whole different story. So let me walk you through how you would go about this based on some previous posts and then, in subsequent posts, I show you how you can use this to create an email driven service desk.

Identifying the opted in staff

So the first requirement is to identify the opted in staff. For that, the simplest solution is to create a new field in the Support Staff module as follows:

Setting Value
Name Send Email
Type Numeric – Boolean
Default False

Add this field to your Support Staff form and you now have a way to identify them…

A little SQL function…

The next issue is that we need a way to use this field in a normal business rule to build a list a of those support staff who want to receive notifications. For that we need a little SQL function created as described in this earlier post. This new function will be called GET_OPTED_IN_SUPPORT_STAFF:

USE SDE
GO

CREATE FUNCTION "_SMDBA_"."GET_OPTED_IN_SUPPORT_STAFF"
(
@GROUP int
)
RETURNS nvarchar(4000)
AS
BEGIN
DECLARE @ReturnString nvarchar(4000)
SET @ReturnString = ''
DECLARE @LoginID nvarchar(30)
DECLARE cur CURSOR
FOR 
SELECT DISTINCT P."CODE" 
FROM "_SMDBA_"."_PERSONNEL_" P 
JOIN "_SMDBA_"."_GROUPDET_" GD 
ON GD."_MEMBER_" = P."SEQUENCE" 
WHERE GD."_GROUP_" = @GROUP 
AND P."SEND_EMAIL" = 1 
AND P."_INACTIVE_:" = 0
OPEN cur
FETCH NEXT FROM cur INTO
@LoginID
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
SELECT @ReturnString = @ReturnString + @LoginID + ';'
END
FETCH NEXT FROM cur INTO
@LoginID
END
CLOSE cur
DEALLOCATE cur
IF LEN(@ReturnString) > 0
BEGIN
SELECT @ReturnString = SUBSTRING(@ReturnString,1,LEN(@ReturnString)-1)
END
RETURN @ReturnString
END

UPDATED: If you look in the comments you will see a comment from Raymond Beijerling with an updated version of the SQL function that will improve performance and resilience.

Once we have created this function, it is important that we grant execute permissions to it:

GRANT EXECUTE ON [_SMDBA_].[GET_OPTED_IN_SUPPORT_STAFF] TO PUBLIC

Finally we just need a simple business rule that, on change of group assignment for example, sends an email to all opted in support staff:

HD – Notify Opted In Group Members When Incident Assigned To Group

Conditions

when a Incident Create Update occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
{DB,Incident,Group Name,”Incident #” = {TR,Incident #}} NotEqual {CUR,Group Name} And
{DB,Incident,Group Name,”Incident #” = {TR,Incident #}} NotEqual   And
{MATH,(SELECT LEN(_SMDBA_.GET_OPTED_IN_SUPPORT_STAFF({TR,Seq.Group})))} GreaterThan 0  

Actions Action 1

Method Module Form
Create Notifications Multi-Notifications
Field Name Value
Subject Service Desk Notification – Incident Assigned To Your Group
Body <HTML><HEAD><TITLE>Service Desk Notification – Incident Assigned To Your Group</TITLE></HEAD><BODY><P>Add some nice text here</P></BODY></HTML>
Notification SMTP Email
Address Staff Multiple {MATH,(SELECT _SMDBA_.GET_OPTED_IN_SUPPORT_STAFF({TR,Seq.Group}))}

Summary

That’s pretty much it…Now no matter what group a support staff member is a member of, if they have their Send Email flag set then they will receive emails when an incident is assigned to their group. As always I hoped this post proved useful. Feedback, positive or negative, is always hugely appreciated.

Service Tree By Description Rather Than Name

As you will no doubt be aware, Service Desk Express (SDE) provides the ability to display the Category list (aka Support Subjects) and / or the Service list, in a treeview as opposed to the normal popup list. In case you weren’t aware of this functionality it is achieved by checking the Category Tree / Service Tree checkboxes for these appropriate fields in Form Customisation.

By design / default however, whilst the Category tree displays the Category Description, the Service tree displays the Service Name. Recently, I was asked if it was possible to display the Service tree by Service Description instead of Service Name. As with most things, it IS possible but does require a couple of code hacks as detailed below. As such, if you are going to do this, MAKE SURE YOU BACK UP EVERYTHING (DB and Application Server directories) FIRST!!!

To implement this change we need to alter two files. This first of these is ServiceTreeRender.aspx (located in C:Program FilesBMCService Desk ExpressApplication Server by default). Open the file in Notepad and change the lines:

string sColName = (Fields.GetFieldBySequence(6) as NAMMETADATALib.IMField).name; //Service Name
...
kidList[z] = new SDE.UI.TreeNode(objOneData.get_Item(1).ToString(), //id
objOneData.get_Item(6).ToString(), //name
Convert.ToInt32(objOneData.get_Item(14)) > 0, //Check for children
null,
((Convert.ToInt32(objOneData.get_Item(14)) > 0) ? "folder":""),
false); //Sudha, fix for bug#34382, adding customNodeData value

to be

string sColName = (Fields.GetFieldBySequence(7) as NAMMETADATALib.IMField).name; //Service Description
...
kidList[z] = new SDE.UI.TreeNode(objOneData.get_Item(1).ToString(), //id
objOneData.get_Item(7).ToString(), //description
Convert.ToInt32(objOneData.get_Item(14)) > 0, //Check for children
null,
((Convert.ToInt32(objOneData.get_Item(14)) > 0) ? "folder":""),
false); //Sudha, fix for bug#34382, adding customNodeData value

Save the file.

The other file is xml_generator.aspx located in the same directory. Open this in Notepad and find the GetServiceTree() function. Change the lines:

string sColName = (objFields.GetFieldBySequence(6) as NAMMETADATALib.IMField).name;
...
objFetchData.set_Item(6, "");
...
strxml.Append(SDE.Utility.encodeURIComponent(objOneData.get_Item(6).ToString() )); //name

to be

string sColName = (objFields.GetFieldBySequence(7) as NAMMETADATALib.IMField).name;
...
objFetchData.set_Item(7, "");
...
strxml.Append(SDE.Utility.encodeURIComponent(objOneData.get_Item(7).ToString() )); //description

Save the file.

IISRESET for good measure and you should be good to go. As always any feedback (positive or negative) is always welcome.

New Starter/Leaver Process – Part 3

In my previous posts in this series (New Starter/Leaver Process – Part 1 and New Starter/Leaver Process – Part 2) I described, diagrammatically, a new starter business process that could be implemented in Service Desk Express as shown below:

New Starter

In the final part of this series I am going to finish it off with the business rules that tie everything together. Before I do so I should mention that I have made some changes to the Function GET_STD_CONFIGS detailed in the previous post. So if you downloaded this before please go ahead and download it again and run it against your Service Desk Express database.

The first business rule we need is to create the new starter ticket (incident) when a client is created:

CL01 – Client Insert Create New Starter Ticket

Conditions

when a Client

Create occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
No Conditions

Actions

Action 1

Method Module Form
Create Incident Incident (base)
Field Name Value
Client ID {TR,Client ID}
Company ID {TR,Company ID}
Group Name HELPDESK
Subject ID ZZNS
Status ID OPEN
Description New Starter

Not very exciting but it does the job. Now we need a business rule that is going to send an email to the new starter’s supervisor (a new foreign key in the Client module referencing the Client module called Seq.Supervisor) and create a new work order for the SYSTEM ADMINS to create an Active Directory and Exchange account.

HD01 – New Starter Ticket Stage 01

Conditions

when a Incident

Create occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
{TR,Subject ID} Equals ZZNS None

Actions

Action 1

Method Module Form
Create Notifications Notifications
Field Name Value
Subject Service Desk Notification: New Starter Approval Required
Body {TEMPL,HD14}
Notification Module Descr SMTP Email
Client ID {DB,Clients,Supervisor Client ID,”Sequence” = {TR,Seq.Client}}

Action 2

Method Module Form
Create Work Orders Work Orders
Field Name Value
Incident # {TR,Incident #}
Client ID {TR,Client ID}
Company ID {TR,Company ID}
Group Name SYSADMINS
Subject ID ZZNSEX
Status ID OPEN
Description Please create a new Active Directory / Exchange account for this new starter. Once complete, please update the client’s email address by clicking the Faces icon near the Client Information at the top of this form and entering the email address created. Thank you.
Resolution AD/Email Account Created and Client Successfully Updated.

Notification Business Rules Template HD14 referenced in the above business rule makes use of a two other templates created in my HTML Email Template post. Make sure you create the _HTML_HEAD and _HTML_FOOT templates otherwise this business rule wont work properly.

HD14 – New Starter Email To Supervisor

Template Name HD14
Template Data {TEMPL,_HTML_HEAD}
<P>Dear {DB,Clients,Supervisor First Name,”Sequence” = {TR,Seq.Client}},</P>
<P>
A new starter request has been raised for {TR,First Name} {TR,Last Name}. As the supervisor of this new starter you are required to specify which equipment configuration they will require. Please click on one of the links below and then send the email generated.
</P>
<H2>Eqiupment Selection</H2>
<TABLE>
{MATH,(SELECT _SMDBA_.GET_STD_CONFIGS({TR,Incident #}))}
</TABLE>
<P>
Thank you for your assistance with this service request.
</P>
{TEMPL,_HTML_FOOT}

That’s half of our business process complete. The email that is sent will automatically list all the Standard CI Assemblies available complete with hyperlinks such that when the supervisor clicks on their choice it will create an email configured in a way that we can pick up the inbound email and continue the business process. To pick up the inbound email from the supervisor we need a Mail Listen type business rule.

ML01 – New Starter Approval Received

Conditions

when a Mail Listen

Create occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
{TR,Subject} Contains Service Desk Notification: New Starter Approval Given None

Actions

Action 1

Method Module Form
Create Work Orders Work Orders
Field Name Value
Incident # {EXTRACT,^^,{TR,Subject}}
Client ID {DB,Incident,Client ID,”Incident #” = {EXTRACT,^^,{TR,Subject}} }
Company ID {DB,Incident,Company ID,”Incident #” = {EXTRACT,^^,{TR,Subject}} }
Group Name DESKTOPS
Subject ID ZZNSWS
Status ID OPEN
Description Please build a {DB,Standard CI Assembly,Description,”Name” = ‘{EXTRACT,[],{TR,Subject}}’} for the above user.

Additional Comments:
{TR,Message}

The above business rule simply creates the new workstation work order for our DESKTOPS team advising them of the choice our supervisor has made. The final business rule is the one that assigns the parent Service Request to the HR team for them to complete the new user induction. The trick here though is how do you know which work order is going to be completed first and how to you know when both work orders have been completed. The answer to the first is that you don’t (although you could take a good guess) and as such you need to allow for the fact that either of the work orders could be the last to be closed and should thus trigger this final business rule.

WO01 – New Starter WOs Completed

Conditions

when a Work Orders

Update occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
{DB,Incident,Subject ID,”Incident #” = {TR,Seq.HD #}} Equals ZZNS And
{MATH,(SELECT COUNT(*) FROM _SMDBA_._WORKORD_ WHERE STATUS = ‘O’ AND HDNUM = {TR,Seq.HD #})} Equals 0 And
{MATH,(SELECT COUNT(*) FROM _SMDBA_._WORKORD_ WHERE HDNUM = {TR,Seq.HD #})} Equals 2 None

Actions

Action 1

Method Module Form
Update Incident Incident (base)
Field Name Value
Incident # {TR,Seq.HD #}
Group Name HR
Description Please provide a new user induction for the above user.

So essentially what we are doing here is checking that the parent Incident / Service Request is a New Starter one and that the total number of linked Work Orders is 2 and the total number of open linked Work Orders is 0 i.e. they have all been closed.

Summary

Whilst this business process could have been a lot more complicated (I once implemented one with 6 parallel work orders etc.) this series of posts have shown how it is possible to chain business rules together to deliver a real business process. Hope this helps. As always, any feedback, positive or negative is always welcome. Thanks for reading.

How To Send An Email To All Assessors For A Given Change

Ever wondered how to communicate with all assessors and/or approvers of a change request that the status of a change has changed? If the answer is “Yes” you will, probably before now, have realised that this is not as straightforward as it seems.

What I hope to achieve in this post is to walk you through how you would achieve this. The problem lies in Service Desk Express’s lack of functionality to “iterate” through a dataset and complete an action for each record it finds.

Solution

The solution is courtesy of a little SQL magic – we are going to create a user-defined function that iterates through each of the assessors and builds a string of their Login IDs such that we can give this to a Service Desk Express business rule to send an email:

CREATE FUNCTION [_SMDBA_].[GET_CHANGE_ASSESSORS]
(
@ChangeNo int
)
RETURNS nvarchar(4000)
AS
BEGIN
DECLARE @ReturnString nvarchar(4000)
SET @ReturnString = ''
DECLARE @LoginID nvarchar(30)
DECLARE cur CURSOR
FOR SELECT DISTINCT P.CODE FROM    _SMDBA_._CHANGEASMT_ CA JOIN _SMDBA_._PERSONNEL_ P ON P.SEQUENCE = CA.ASSESSOR WHERE CA.[_INACTIVE_:] = 0 AND P.[_INACTIVE_:] = 0 AND CA.[CHANGE] = @ChangeNo
OPEN cur
FETCH NEXT FROM cur INTO
@LoginID
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
SELECT @ReturnString = @ReturnString + @LoginID + ';'
END
FETCH NEXT FROM cur INTO
@LoginID
END
CLOSE cur
DEALLOCATE cur
RETURN SUBSTRING(@ReturnString,1,LEN(@ReturnString)-1)
END

It is important that we grant execute permissions to this function:

GRANT EXECUTE ON [_SMDBA_].[GET_CHANGE_ASSESSORS] TO PUBLIC

Then we just need a simple business rule that, on change of status for example, sends and email to all assessors:

Change Request -Notification of Change of Status To Assessors

Conditions

when a Change Request

Update occurs with

Expression 1 Comparison Operator Expression 2 Logical Operator
{CUR,Status ID} NotEqual {TR,Status ID} None

Actions

Action 1

Method Module Form
Create Notifications Multi-Notifications
Field Name Value
Subject Service Desk Notification – Change Request Status Update
Body <HTML>
<HEAD>
<TITLE>Service Desk Notification – Change Request Status Update</TITLE>
</HEAD>
<BODY>
<P>Add some nice text here</P>
</BODY>
</HTML>
Notification Module Descr SMTP Email
Address Staff Multiple {MATH,(SELECT _SMDBA_.GET_CHANGE_ASSESSORS({TR,Sequence}))}

Summary

User-defined functions can be a goldmine of pieces of functionality that is missing from Service Desk Express. So before you despair…think UDF! As always I hoped this post proved useful. Feedback, positive or negative, is always hugely appreciated.

New Starter/Leaver Process – Part 2

In my previous post (New Starter/Leaver Process – Part 1) I described, diagrammatically, a new starter business process that could be implemented in Service Desk Express as shown below:

New Starter

In this post we are going to lay the foundations to build this process (by populating some necessary data) and then in the final post in the series we will complete the business rules.

Categories/Support Subjects

We need to add a couple of Categories /Support Subjects as shown below:

Subject ID Description Parent Subject ID
ZZ zzBusinessRules
ZZNS New Starter Process ZZ
ZZNSEX AD/Exchange Account Request ZZNS
ZZNSWS Workstation Request ZZNS

Now obviously it goes without saying that you don’t have to have the same categories as me. The reason I name Business Rules as zzBusinessRules is to shove them down the bottom of the Category Tree out of the way.

Groups

In my example I am going to have a centralised System Admin Group (SYSADMINS), Desktop Team (DESKTOPS), and HR Team (HR) who will do my induction process. Again, if you are following this you can call your groups whatever you want

CI Types/Inventory Catalogue Items

Whenever I write these posts I am always keen to make the example something that has a reasonable degree of complexity about it. Many technical examples are based around the equivalent of the Hello World application, and from bitter experience this CAN be more frustrating than useful. So in my example here, I am going to assume that we are using the Asset Management modules as well. So we’ll need the following CITypes/Inventory Catalogue Items:

Part # Description
STDWS01 Standard Workstation
STDLT01 Standard Laptop
STDMB01 Standard Mobile Phone
STDBU01 Standard Operating System/Applications Build
STD3G01 Standard 3G Card

Standard Configurations

We are then going to create two standard configurations as shown below:

Name Description
STDST Standard Static Configuration
Consisting of…
STDWS01 Standard Workstation
STDBU01 Standard Operating System/Applications Build

and

Name Description
STDMB Standard Mobile Configuration
Consisting of…
STDLT01 Standard Laptop
STDMB01 Standard Mobile Phone
STDBU01 Standard Operating System/Applications Build
STD3G01 Standard 3G Card

Standard Configurations User Defined Function

As anyone will tell you, when, as a developer, you hardcode stuff you invariably come to regret it (unless you have already left the organisation that is). I want to be able to send my supervisors a dynamic list of Standard Configurations that he/she can select from such that if that business decides at a later date to have a Non-Standard Mobile Configuration we can cope with it without the need for any code changes.
Alas, out of the box Service Desk Express can’t send a list of anything to anyone. This is where we need a little SQL help in the form of a User-Defined Function (UDF). Below is a link to a function I want to use to send out part of my email which can either be run yourself against the SDE database or given to your SQL DBA to run against the SDE database:

Function GET_STD_CONFIGS

If you haven’t used user-defined functions in SDE then you might find this post helpful.

Summary

So that is all the preparation work done. Now all we have to do is build our business rules to use all this stuff and that is what I will document in the third and final post in this series.

How To Filter The Assign To Grids in Service Desk Express

A post in the MagicSolutions forum posed a challenge that I thought would be fun to try and solve, namely how to filter the Assign To grids in Service Desk Express. Unlike other popups that are accessed from a popup icon on the form these popups are accessed by clicking on the Assign To menu item. As such there is no out of the box facility within the application to filter this list as there is with other popups (see How to dynamically filter a popup list in Service Desk Express).

Solution

This is an unsupported hack of the ASP.NET code

The first thing to do is determine how you want to filter the popup as there is usually little point hardcoding something if it can be dynamic. For my example, I created a new field in the Support Staff module called Hide In Popups as shown below:

Hide In Popups

Now this field will be granted a unique number by Service Desk Express and it is important that you find out what this number is using the SQL statement below:

SELECT COLSEQ FROM dbo.SMSYSBASEVIEWDATA WHERE TBLSEQ = 18 AND VIEWCOLNAME = 'Hide In Popups'

In my case this returned a value of 1001.

To filter the popup we need to add some code in assignto_grid.aspx (located in C:Program FilesBMCService Desk ExpressApplication Server by default) just before the opening <HTML> tag:

<%
if (ViewName == "18" && sMode == "STAFF")
{
AddWhereClause += " + ||1001|| = 0";
}
else if (ViewName == "18" && sMode == "MYGROUP")
{
AddWhereClause += " AND ||1001|| = 0";
}
%>

Save the file and you should be good to go.

So how does this code work. Well the ViewName == “18” bit means that I only want to filter the Support Staff not the Groups (which incidentally would be ViewName == “13”). The sMode bit refers to which menu item this popup was called from e.g. Member of My Groups. The AddWhereClause bit simply says check if field 1001 (my new Hide in Popups field) is equal to 0. As to why the syntax is different for the two modes – PASS!

Summary

Anyway, seems to work. As always any feedback (positive or negative) is always welcome.

Services, Organisations, and Service Level Agreements – Part 2

In Part 1 of this series I discussed how to create the Services, Organisations and Service Level Agreements (SLAs) necessary for our example of an internal service desk servicing six departments with the Finance department requiring a tighter SLA on one of the services then any of the other departments during March each year.

In this post, I will cover SLA Criteria (such that we can finish our example); linking Services, Organisations and SLAs;  and of course how to turn SLA Management on in the first place including the biggest gotcha of all.

SLA Criteria

We said that we wanted to provide our Finance department with a tighter SLA during March each year. How do we go about doing that? Well the first thing we need to do is create the new Urgency/Priority and SLA that we want to offer as shown below:

24HR Priority 24HR SLA 01 24HR SLA 03 24HR SLA 04

Another Gotcha

We need to add a SLA Criteria that checks if the month the call was opened was March. Problem – SLA Criteria can only check the values of fields within the module they are configured for (i.e. in our case Incidents) and don’t allow for any expressions. Solution – Create a field to hold the month the call was opened and populate it on save using a CSBR as shown below:

Month Opened

Conditions
Expression 1 Comparison Operator Expression 2
{TR,Month Opened} Equals {NULL}
Actions
Field Value
Month Opened {MATH, DATEPART(MONTH,GETDATE()) MT}

You MUST add the field to the forms used otherwise you will get an error – Input string not in correct format. It CAN be hidden though.

Now in order that this SLA is only offered during March we need to configure an SLA Criteria as shown below:

24HR SLA 02

Notice that this criteria only considers the March clause NOT the Finance department clause. That comes later when we link Services, Organisations and SLAs. You could include the Finance department clause but then you would need to keep changing you SLA if, for example, another department wanted the same SLA.

In this example, given all the hassle of creating a field and CSBR, you could choose an alternative solution of selecting the 24HR_MARCH SLA and configuring the Start and End dates to only include March. The problem here of course is that you need to create one for every year which is a little painful. What is more, it wouldn’t have given me the opportunity to explain SLA Criteria 🙂

Service Organisation SLA Links

Now there’s a mouthful! Service Organisation SLA Links (LINK) are what they say on the tin – the way to assign a SLA to a service consumed by an organisation. They are accessible from the Service, Organization, and SLA forms via their respective tabs. In our example above we want each department to use our Standard 48HR SLA for the service of Application Support. Now we could create a separate LINK for each Organisation but we don’t need to. If we open the Service form, find our Application Support service and click Add on the SLA/Org tab we can create a LINK as shown below:

LINK 01

What the record above says is “Offer this SLA whenever the Application Support Service is selected.” This is fine for what we want at the moment. Now what we need to do is create another LINK for the Finance Organisation to provide the 24HR SLA against the Application Support Service as shown below:

LINK 02

Thus your Application Support service should look like this:

Service With LINKS 01

Now, when anyone logs a ticket against the Application Support Service between April and February inclusive, the only option will be the 48HR SLA as shown below:

Select from SLAs 01

However, when a member of the Finance department log a ticket against the Application Support Service during March, a choice of either the 24HR SLA or the 48HR SLA will appear as shown below:

Select from SLAs 02

…assuming you have turned the functionality on!

Service Level Agreement Rules

Yes that’s right – out of the box the SLA functionality is NOT turned on. To enable Service Level Agreements you need to click on the Service Level Agreement Rules item in the Service Level Management tab. Then from the Enable SLAs window that appears check the box to enable SLAs as shown below:

Enable SLAs 01

So here is the kicker and this is absolutely WOEFUL!

You have to manually enable the SLA functionality for each group by logging in as that group and turning it on by checking the box as described above! Imagine what that is like on 126 Groups! Scripts to the rescue…

SDE_SetDefaultSLARulesForAllGroups.sql

The above script will turn on SLA Management for every group!

One Final Issue!

SLA’s are NOT mandatory out of the box. What this means is that if one of your Service Desk Agents decides to close the Select From SLA popup that appears to select the SLA, no SLA is populated at all. If you want to enforce SLAs you MUST make your SLA ID field selectable (i.e. NOT readonly) and write a Client Side Business Rule (CSBR) as shown below:
When an Incident is Saved

Conditions
Expression 1 Comparison Operator Expression 2
{TR,SLA ID} Equals {NULL}
Actions
Method Module Form
Display Message Incident Current Form
Exit Rule if ‘OK’ clicked Checked

Summary

Hopefully, throughout these two posts I have given you an idea of what the art of the possible might be using the SLA modules available with Service Desk Express. As always, comments, positive or negative, are always welcome.

Services, Organisations, and Service Level Agreements – Part 1

In Service Desk Express 9.0 the new Services module was introduced which, in conjunction with the Organisations and Service Level Agreements modules, allows service delivery companies to manage the delivery of their service catalogue. These new modules are not for everyone – indeed there are a couple of performance issues with these modules that should not be overlooked – but for those looking to implement the functionality, this series of posts are hopefully for you.

I hope to cover all the aspects/features/functionality associated with these modules using examples. As always, I will try and make the examples as realistic as possible.

Services

The easiest module to get your head around is the Services module. The Services module should list the services you, as a service provider, are making available to organisations to consume. As a first pass I would suggest that you start very top-level – for example:

  • Account Support Service
  • Application Support Service
  • Email Support Service
  • Hardware Support Service
  • Mobile Support Service
  • Network/Connectivity Support Service
  • Printing/Scanning Support Service

The decision as to whether you need to go any lower than this depends primarily on whether different applications say, have a different SLA’s. It may also depend on how you have defined your Categories (Support Subjects).

The key fields within Services are:

  • Name – The name of the service.
  • Description – A general description of the service.
  • Activation Date – The date the service is first available.
  • Retirement Date – The date when the service will no longer be available.

Organisations

The way you set up Organisations depends entirely on how you have set up your Companies and Departments. Most Service Desk Express solutions I have seen have been internally focused. As such they will probably have a single Company as this makes reporting much much easier and in my opinion is an excellent idea unless you have a really really good reason not to. They also tend to have a lot of Departments. Service Desk Express allows your Organisations to be Company, Department or Company/Department based. The table below shows which solution is best suited to which criteria:

Situation Solution
1 More than one Company and within each Company Departments can have different SLA’s for a given Service. Organisations should be based on Companies and Departments.
2 More than one Company and within each Company all Departments have the same SLA for a given Service. Organisations should be based on Companies.
3 One Company and all Departments have the same SLA for a given Service. Single Organisation based on the single Company.
4 One Company but different departments can have different SLA’s for a given Service. Organisations should be based on Departments.

If you are in Situation 1 I feel for you as this is the same situation that I have to manage and it can get a little complicated. The more common situation is 3 or 4. So what I will cover in this post is Situation 4 which is the more complex of the two.

OK, so let’s say that we have Scenario 4 with an internal service desk servicing six departments: Sales; IT; Marketing; Facilities; Finance; and HR. Now, let’s say that Finance require a tighter SLA on the Applications Support Service then any of the other departments but only during March each year. We can create six appropriate Organisations each linked to their respective Department as per the screenshot below:

Organisation

Service Level Agreements (SLA’s)

SLA’s allow you to specify conditions under which they are applied, resulting in a given Due Date and Time, and appropriate milestones. They are actually quite straightforward but there are a couple of little gotchas that you just need to be aware of. Let’s walk through the creation of a SLA that would deliver a one-hour response, 24 hour recommended fix and a 48 hour absolute fix.

Urgencies…Priorities…ITIL…Argh!!!!

The first thing you need to be aware is that the SLA module does not contain the fix durations – another module does that. In days of old (i.e. pre Service Desk Express 9.6) this was the Urgency module. So if you are using Service Desk Express 9.2 or below then, to create the SLA mentioned above, you would need to create a new Urgency form that included the Duration, Recommended Fix Duration, and Response Duration fields similar to the one shown below and create the appropriate record as shown:

48HR Urgency

Now notice here that the duration fields are WORKING hours not literal hours. This is important. So, in the example above, our 48HR literal fix time equates to 20 working hours because our work schedule is 10 hours long (0800-1800).

When BMC released Service Desk Express 9.6 they bowed to significant customer pressure that the Priority should drive the fix durations and that Priority is derived based on the combination of Urgency and Impact. What this means is that if you are using Service Desk Express 9.6 or above then you would need to create a new Impact, Urgency, and Priority record to achieve the same effect. By the way, this is not a bad thing it is just that it makes life more complicated when trying to explain all this in a blog post! Anyway, piccy below:

48HR Priority

So now that we have our Urgency (or Priority depending on what version you are using), we can now go ahead and create our SLA as shown below:

48HR SLA 01 48HR SLA 02 48HR SLA 03

So notice a couple of things. In the first piccy we have the following fields:

  • SLA ID – A unique name for the SLA.
  • Description – A freetext description of the SLA.
  • Start Date – The first date this SLA can be selected. You will NOT get the option of selecting this SLA unless the current date and time is between the Start Date and End Date fields.
  • End Date – The date this SLA can be selected.
  • Type – You can select either Service Level Agreement, Operational Level Agreement, or Underpinning Contract. What matters is that this field is purely for reporting purposes.
  • Status – You can select either Active, Draft or Disabled. The record MUST be Active to allow you to select it for NEW tickets. Existing tickets CAN have an SLA with a status of Disabled and these will still process as normal.
  • IT Owner – The Support Staff member who owns this SLA. Again for reporting purposes only.
  • Module – You can select either Incident, Problem Management or Change Request. The SLA will only work in the module selected here.

The second piccy shows the Criteria. This SLA has no criteria which means it will be available for all circumstances. We will use this screen later when we want to check if the current month is March!  The third piccy shows the Goals. This is simply the selection of the appropriate Priority or Urgency that we created above. The final piccy shows the Milestones screen:

Milestones

Milestones is an interesting choice of title here. Normally, we strive to achieve milestones. In the case of BMC’s SLA Milestones these are events that you hope you DON’T achieve! Essentially they are how you monitor your tickets in real-time. A single SLA can have multiple milestones which once hit perform an specific action (usually sending an email or reassignment). One thing to bear in mind when creating these is that no two rules can have the same name and as such it is worth prefixing the rulename with the SLA ID. Below are screenshots of two you might create:

1) 48HR – Ticket Within 90% Due Date

48HR Milestone 01

2) 48HR – Ticket Passed Due Date

48HR Milestone 02

*** DO NOT GET CARRIED AWAY ***

It is really easy to create loads of milestones to monitor everything and depending on just how carried away you get one or two things are likely to occur:

  • Your staff will get information overload and receive so many emails that they will create rules in Outlook to ignore them!
  • Your system will come to a grinding halt as there are performance issues with creating too many milestones!

Next Post

OK, so enough for now – this post is more than long enough. Hopefully this will get you started on how to set up your Service Catalogue, Organisation structure and Service Level Agreements. In my next post in this series, I will cover SLA Criteria (such that we can finish our example); linking Services, Organisations and SLAs;  and of course how to turn SLA Management on in the first place including the biggest gotcha of all!

Service Desk Express QuickViews Don’t Return Any Data

Recently I came across an unusual experience with Service Desk Express 9.8 where my QuickViews suddenly stopped returning any records. So following typical fault finding principles I considered what I had changed and all I had done was install a web application at the root of the same website containing the SDE virtual directory. The rest of Service Desk Express (and for that matter, everything else on the server ) all worked absolutely fine but the QuickViews simply returned “Retrieving data, please wait…”

I would love to say that I identified the root cause and the resolution but alas a gifted colleague did all that. Suffice to say, the issue was caused by the fact that the Service Desk Express web.config file failed to contain a default section that specifies which version of which compiler the application should use. As my new application did provide this information, Service Desk Express tried to inherit it and, as a result of .NET Framework version issues, promptly fell over.

Solution

So to the solution. If you want to have an ASP.NET web application at the root of the same website where Service Desk Express is installed, open the Service Desk Express web.config file (found in C:Program FilesBMCService Desk ExpressApplication Server by default) in Notepad and add the following section just above the </configuration> tag as shown below:

...
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v2.0"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
</configuration>

Summary

Whilst this may be a somewhat isolated situation, hopefully it will save someone pulling their hair out as we did for a morning! As always, comments, positive or negative, are always welcome.

More Traffic Lights

In previous posts (http://www.joatit.com/wordpress/?p=96) and (http://www.joatit.com/wordpress/?p=69) I showed how to colour code the quick views in a traffic light style using the following query:

(CASE WHEN [CLK_STOPTIME:] IS NOT NULL THEN 'On Hold' WHEN GETDATE() > [RECOMMENDEDFIX_DATE:] AND GETDATE() < [DUE_DATE:] THEN 'Warning' WHEN GETDATE() > [DUE_DATE:] THEN 'Critical' ELSE 'Normal' END)

Recently I was talking to one of our users who, when using Service Desk Express 9.8, rather liked the ability to view closed incidents in the quick views. She commented however, that when you viewed closed incidents with the above query everything went red eventually. It would be much better if you could see if the call was inside or outside SLA as defined by Close Date vs. Due Date.

So without further ado; creating a calculated field with the query below will not only achieve the same results as the previous posts but additionally will show if the incident was closed in time (Normal) or not (Critical) when looking at closed incidents:

(CASE WHEN BASE.[CLK_STOPTIME:] IS NOT NULL AND BASE.[STATUS] = 'O' THEN 'On Hold' WHEN GETDATE() > BASE.[RECOMMENDEDFIX_DATE:] AND GETDATE() < BASE.[DUE_DATE:] AND BASE.[STATUS] = 'O' THEN 'Warning' WHEN GETDATE() > BASE.[DUE_DATE:] AND BASE.[STATUS] = 'O' THEN 'Critical' WHEN BASE.[CLOSED ON] > BASE.[DUE_DATE:] AND BASE.[STATUS] = 'C' THEN 'Critical' ELSE 'Normal' END)

Hope it helps. As always, please keep the feedback coming. It makes sure that what I am posting is of relevance and interest to the people reading.