A new version of Service Market is here!

In 6.1.0 we’ve had a bit of a Product Question focus and added Generators, Validators and Product Question types to make it possible to handle more use cases with our generic services. Also we’ve added a unlock account functionality to the manager password service, and some consistency to how we display users in the Manage Group / List / Folder services (corresponding request services soon to follow).

We’re introducing a new concept building on Generators: the Populator. This is a generator that can be used on a dropdown, combo box, or the new listbox question types. It’s supposed to generate a JSON containing name/value pair objects in an array. This is then used to populate these kinds of lists. There’s also an option to pre-select one of the values using a specified input pattern, maybe with data from another question or with a fixed value that should be selected. This version ships with a Powershell populator (that runs a powershell that needs to supply the values) and an Employee populator that lists the employees for a specific approver.

Product Questions
There is now a File type question that can upload files to the server, this can be used for any file and will supply the file path as answer for it to be accessible to workflow activities. This can also be used to add attachments to a (hardware, software or service) order’s work item in SCSM. To do this, configure the product to create a work item, and add a File question with the reserved attribute key ‘SCSM_Attachment’.

A Listbox question that is either a multi-select box, or a list of objects where you can add or remove objects. With the add / remove you will have to add the new List add generator that connects the list to an other question whose value will be added when you click ‘Add’.

So, as a filler today we’re going through the promised set-up-a-product-as-a-service so get ready for some Service Market tuning! The case is a lightweight custom implementation of the Manage  – Organization – My Users Information, a service for managers wanting to change information for their employees.

First we’re going to need a couple of Product Questions:

  • A User question, called ‘User’, with no particular properties –
  • A Name/Value (drop down) question without any values – let’s call it Employee, leave it in ‘General’ Area and give it the attribute key ‘targetEmployee’
  • For the sake of demonstration we can any number of AD-attributes question, for the sake of demonstration we’ll have one called Email, with the ‘ActiveDirectory’ area and ‘mail’ attribute key
  • Let’s reuse the standard First Name, Last Name and Manager AD questions
  • Finally the standard NITO area Department and CountryCodeNumeric questions, to show that part of the setup.

Now this will need a couple of Generators:

  • A DepartmentEmployeePopulator that will take the (logged in) User input and generate a list of all employees in his/her Department(s). Give it an input parameter of your choice e.g. ‘input’ and add it to the PrimaryApproverPattern config, like so: ‘{input}’. The selector pattern is not applicable in this case.
  • A JSONAttributes generator with a necessary named input called ‘objectId’. Also enter an asterisk in the ValidAttributes configuration.
  • An EmployeeAttributes generator with a necessary named input called ‘objectId’. Also enter an asterisk in the ValidAttributes configuration.

Finally let’s tie it together in a Product:

  • In Product Administration, create a new product of the type Service with the Manage operation. This will make sure we can only see it in if we really want to. Make it active and add the Product Questions as above.
  • Set the User Question to default to logged in user, and make it invisible and ineditable. For tidyness you can also hide it from summary.
  • Add the DepartmentEmployeePopulator generator to the Employee question, and connect the User as input.
  • Add the JSONAttributes generator to one (only one) of the AD questions, eg. First Name, use Employee as the ‘objectId’ input.
  • Add the EmployeeAttributes generator to one (only one) of the NITO questions, eg. Department, use Employee as the ‘objectId’ input.
  • Save it and note the product ID.
  • Try it out by going to the Report Incident service and add a ‘&d=X‘ to the end of the address in your browser where X is the product ID from above, you should now see the questions in all it’s glory – try it out by selecting an employee (if you’re the approver of a department, otherwise you will need to set that up first) and it should look somewhat like this:


Isn’t it great? Endless possibilities! Now to actually do something you need to set up a custom workflow to do something with this information, and much of that is covered in the blog post from a while back (Service Market 6.0.8) about how to set user image (it’s perfectly fine to have an image question in this setup too), only you need to set the GetIdentityForUser activity read the Employee question instead – here’s a brief overview:

  1. Take the WF_Request_Service workflow files (3 of them) in Workflow manager’s wfworkflow folder (default ‘C:\Program Files (x86)\Atea\Workflow Manager\Workflows\Standard Workflows’) and copy them to the custom workflow folder with a new name, eg. WF_Custom_UserInformation. It’s important that you base it on the service workflow since all product-question based services expect the same properties as this has.
  2. In the .xoml and .xoml.cs files, replace all occurrences of ‘WF_Request_Service’ with your name, eg. ‘WF_Custom_UserInformation’.
  3. Open Workflow manager and open your workflow
  4. In a suitable location in the workflow – eg. between standard activities AddUsersToGroups and runPowershellFromOrder1 add the following five activities (all are in AteaSpintop.Activites, listed below with last differing namespace):
    1. Question.SortQuestion, map ‘Order’ property to the workflow Order property: ‘Activity=WF_Custom_UserInformation, Path=Order’
    2. Question.ReadQuestion, set ‘AnswerFormat’ to ‘{0}’, AttributeKeys to ‘targetEmployee’ as only string in the array (recognize this from somewhere?), ‘Order’ as above, QuestionAreaType should be ‘General’ if that’s what you used in the question.
    3. AD.GetUserADIdentity, set ‘ADServerName’ to the workflow ADServerName property, and ‘UserId’ to the ‘Answer’ property from the ReadQuestion activity.
    4. Question.SetADAttributesFromQuestions, set ‘ADServerName’ to the workflow ADServerName property, ‘ObjectSID’ to the ‘SID’ property from the GetUserADIdentity activity, and ‘QuestionAnswer’ to ‘QuestionAnswer’ from the ‘SortQuestion’ activity.
    5. NITO.CreateOrUpdateUserFromQuestions, set ‘UserID’ to the ‘sAMAccountName’ property of the GetUserADIdentity activity, and ‘QuestionAnswer’ to ‘QuestionAnswer’ from the ‘SortQuestion’ activity.
  5. Save and compile the workflow

Pheeew! That took some doing, right? Now however, if you go to Product Administration again and set the Custom Workflow checkbox and workflow to ‘WF_Custom_UserInformation’, you should be able to mess around with the data of your employees! Go ahead and change their names to something funny!

The last but not least bit is how to set this up as a service. You might have realized that you could go directly to this product with the little addition to the browser web address – the end part of this is called the query string, by the way, and in Service Market’s case, the weird data there is what really does all the navigation. Now, if we could just set up the menu to have such a link for us… could it be possible? Let’s find out!

In your SQL table editor of choice add a line in the NITO Service table with:

  • ServiceID, Name and Description of your choice
  • AllowAZGroup set to a suitable group (eg. ‘Users’)
  • ControlName should be ‘RequestGenericService.ascx’
  • you can set ParentID to a suitable other service’s ID (this is how the menu tree is constructed)
  • ImageName to something nice that resides in the Service Market Images directory
  • Finally the QueryString, guess what should go there? You guessed it: ‘d=X’ as above (drop the first ampersand &, it’ll look nicer even though it should work anyway).

To (optionally) translate the Service name:

  • Service name translations reside in the file <webroot>/ServiceMarket/AppData/Resources/GlobalResources/Services.xx-XX.resx where xx-XX is the culture code for the language you wish to use.
  • This file is however managed in the Service Market and will be overwritten in an upgrade. However a file named Services.xx-XX.override.resx will represent changes made by you in the translations service and will persist. For this reason, it’s best to put your custom service names in that file.
  • If there is no such file, create one by changing the name and description of a service in the ‘Service’ category in Settings – Language – Global Translations service for your language.
  • Edit the file and change the Guid in the data elements of the changed service in the last step to your custom service ID, and write the translated name of your custom service.

Restart the web application and you’re done – the product should be in the menu as a service…!

TL;DR: Do a lot of weird stuff to your Service Market to automate stuff.

Enjoy and tell us of your experiences!