Making the SDE Knowledge Base work for you

For me, out of the box, the Knowledge Base / Knowledge Search function in Service Desk Express (SDE) doesn’t work! In fairness, the reason for this is not entirely an issue with the software but more about how organisations, or more specifically support staff, use SDE. Let me explain:

Most organisations I have worked with have a simple business rule that sends a notification to the client when an incident is resolved. Frequently, that notification includes the Incident Resolution and as such, the words that go into that Incident Resolution are more like “User able to print again” as opposed to “Stopped the Print Spooler service, deleted the stuck print job, and restarted the Print Spooler service on HOMPR01.” Unfortunately, the text you want to see in your Knowledge Base as a newbie support staff member trying to fix their first stuck print queue is the latter NOT the former.

So what’s the solution…For me the easiest solution is to create a new field in the Incident module as follows:

Setting Value
Name Work Instructions
Type Text – Variable Length

With this field added to the form, you can now advise your support staff to populate the appropriate fields e.g.

  • Incident Description: User unable to print to printer Q1000111.
  • Work Instructions: Stopped the Print Spooler service, deleted the stuck print job, and restarted the Print Spooler service on HOMPR01.
  • Incident Resolution: User able to print again.

Now to get the real benefit from this you need to reconfigure the Knowledge Search settings available from System Administration > Knowledge Search Settings.

Search Fields:

Module Name Field Name
Incident Incident Description
Incident Incident Resolution
Problem Management Problem Description
Problem Management Problem Resolution
Incident Work Instructions

Display Fields:

Module Name Field Name Solution
Incident Incident Description  
Incident Incident Resolution Yes
Problem Management Problem Description  
Problem Management Problem Resolution Yes
Incident Work Instructions  

 

“Not entirely an issue with the software…”

There is however one issue with the software that is truly pants! By default, when your support staff (or employee for that matter) uses the Knowledge Base they will only get 50 results returned. This would be reasonably logical if it wasn’t for the fact that it is 50 total results as opposed to what is should be: 50 results from Incidents; 50 results from Problems; 50 results from Changes; 50 results from FAQs. So you have a choice: Educate your users OR Hack! I prefer the latter as I want the functionality used. As such, if you are going to do this, MAKE SURE YOU BACK UP EVERYTHING (DB and Application Server directories) FIRST!!!

Open SirSearchPage.htm (C:Program FilesBMCService Desk ExpressApplication Serverhtml by default) in Notepad and find the line 39:

<INPUT TITLE=MGC_PL_LABEL_4057 Value="50" CLASS…>

Replace with:

<INPUT TITLE=MGC_PL_LABEL_4057 Value="5000" CLASS…>

Save the file.

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

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 Restrict A Custom Self Service Module By Client

BMC Service Desk Express has awesome customisation tools that allow you create complete new tables (modules) for storing custom information in your Service Desk Express database. These custom modules can be presented in Self Service as well for end-users but here is the catch…

Out of the box you can’t restrict entries created by one client from another client.

Thankfully, with a little (well quite a lot actually) custom scripting it is possible. I should stress however, that if you are going to do this, MAKE SURE YOU BACK UP EVERYTHING (DB and Self-Service directories) FIRST!!!

Example

So let’s say that you want to create a new custom module to record feedback such that your clients can log Complaints, Compliments and Observations. The design of our custom module is as follows:

Table Name View Name Display Name
TBL_FEEDBACK Feedback Feedback
Alias Name Column Name Details
Sequence SEQUENCE INT, Primary Key, Created by Default
Last Modified LASTMODIFIED DATETIME, Created by Default
Last User LASTUSER STRING(30), Created by Default
Seq.Group _GROUP_ INT, Created by Default
InActive: _INACTIVE_: SMALLINT, Created by Default
Seq.Client SEQ_CLIENT INT, Foreign Key to Clients, NOT NULL
Feedback Type FEEDBACK_TYPE Validated Field (Compliment, Complaint, Observation), NOT NULL
Statement STATEMENT STRING(Unlimited), NOT NULL
Seq.Incident SEQ_INCIDENT INT, Foreign Key to Incidents, NULL
Status STATUS Validated Field (O,C), NOT NULL
Response RESPONSE STRING(Unlimited), NULL

We then create a form in for Self-Service, an appropriate popup, and modify the navigation bar such that the new custom module can be accessed as shown below:

Feedback Form 01

Issue

If Client ABARBER (that’s me by the way) submits a feedback record all appears to work perfectly. However, when SBARBER (that’s Sarah my wife) logs in, she can see my feedback and if she were to submit feedback, I would be able to see her’s as shown below:

Unfiltered Feedback 01

Solution

First run the following SQL command against your SDE DB and store the results somewhere:

SELECT BVD.TBLSEQ, COLSEQ, VIEWCOLNAME FROM dbo.SMSYSBASEVIEWDATA BVD JOIN dbo.SMSYSTABLES T ON T.TBLSEQ =
BVD.TBLSEQ WHERE T.VIEWNAME = ‘Feedback’ ORDER BY COLSEQ

My result looks like the table shown below but yours will look different depending on what you named your fields and how many custom modules you already have:

TBLSEQ COLSEQ VIEWCOLNAME
1002 1001 Sequence
1002 1002 Last Modified
1002 1003 Last User
1002 1004 Seq.Group
1002 1005 InActive:
1002 1006 Seq.Client
1002 1007 First Name
1002 1008 Last Name
1002 1009 Email Address
1002 1010 Feedback Type
1002 1011 Statement
1002 1012 Seq.Incident
1002 1013 Status
1002 1014 Response

Download RestrictingCustomSelfServiceModuleByClient.zip containing the files that need to replace the existing BMC files.

In the recurring_hd.asp and recurring_hd.htm files you need to do a find/replace replacing:

  • All occurrences of JOATIT_TBLSEQ with the  TBLSEQ number returned in the table above (so in my case 1002).
  • All occurrences of JOATIT_SEQ_CLIENT with the  SEQ_CLIENT number returned in the table above (so in my case 1006).
  • All occurrences of JOATIT_STATUS with the  STATUS number returned in the table above (so in my case 1013).

In the 1_common_label_message.js file you need to scroll right down the bottom and replace the “My Whatever Your Custom Module Is Called” with in my case “My Feedback”

Save the files and use them to overwrite the existing files in their appropriate directories.

Run the following script against your SDE DB…

INSERT INTO dbo.NAMSYSCSMESSAGES ([SEQUENCE], [LANGSEQ], [MESGNO], [MESGTYPE], [MESG]) VALUES (3224, 1, 1597, 2, ‘My Feedback’)

…and IISRESET you application server.

Summary

Hope this helps. Remember to backup everything as it is very easy to make a typo. Also remember, as this is custom code you may well have to reapply it after every patch release from BMC. Who knows, perhaps Service Desk Express 10 will make this post obselete…

As always, comments (positive or negative) are always very welcome and very much appreciated. I do try and answer every single one.

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.

New Starter/Leaver Process – Part 1

Synchronising with Active Directory is NOT the best approach

This is a deliberately argumentative statement that, throughout this series of posts, I want to explore and explain my reasoning behind. The other aim of this series is to provide a real-world example of a new starter/leaver process that can be implemented in Service Desk Express.

For many years architects have been pushing for Active Directory synchronisation from every enterprise application vendor with, in most cases, very good reasons. AD synchonisation provides the business with a single directory source that can be used for everything from authentication/authorisation services to location and reporting structure data depending on how well it is populated. No one, not even argumentative me, would argue that a single directory source is a bad thing, nor that single sign on wouldn’t be welcomed by every enterprise user. My argument is NOT with AD. My objection to AD/Service Desk synchronisation is from a business process perspective – namely I believe that the source of HR data (which is what is being synchronised here) is better suited to the HR/Payroll system within an enterprise rather than AD. I can’t imagine that there are many organisations who add their new employees to AD before they are added to payroll and, in my opinion, the system admins should be tasked properly with creating an AD/Exchange account such that OLA/SLAs can be managed and customer satisfaction monitored.  So what, in my humble opinion, is the correct solution:

Data Flow Solution

Data Flow Diagram

As you can see from the diagram above, my solution would be to put the Service Desk in the centre acting as the hub through which human business processes are transacted. The initial employee record is created in the HR/Payroll system which then creates a client/customer record in Service Desk Express (using the Integration Engine). This in turn kicks off the New Starter business process that includes, amongst other tasks, an action to create an AD/Exchange account for the new employee. By updating the WinUserID field in the Client record with the user’s AD domainusername, the link between AD and Service Desk Express is then made and Self-Service Single Sign On can be provided. When employee records are updated (either through a request through the Service Desk or directly with the HR/Payroll system) the employee details are updated in Service Desk Express and then in AD.

New Starter Business Process

I am not going to discuss the initial synchronisation with the HR/Payroll system as this was discussed in a previous post (Using the Integration Engine to Manage Clients) and there is an appropriate Integration Engine package that can be downloaded and tweaked for your requirements. The key point to mention is that of “datakeys:”

Data Keys Diagram

As you can see Service Desk Express holds the datakey for both the HR/Payroll system (EmployeeID –> CLIENT) and AD (sAMAccountName –> WINUSERID). This is crucial to the solution.

New Starter

In my example business process above, the employee is going to be provided with the following:

  • Workstation (either static or mobile) with a standard operating system/applications build.
  • Active Directory and Exchange account for the domain.
  • Induction.

The important point to note about my example process is that activities happen both in parallel and sequentially and I want to demonstrate how this can be accommodated within business rules in Service Desk Express.

In the next post I will walk through the creation of the New Starter Process in Service Desk Express based on the output of the Using the Integration Engine to Manage Clients post I mentioned earlier.

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.