Sending email notifications regarding a working item in Service Manager is a common requirement that doesn’t really exist out of the box. Travis had published, a while ago, a plug-in called “SCSM SendEmail”. This plug-in though filling that gap, still was missing some of the common requirements:

  • Supporting only Incident – you cannot send email notifications about a service request.
  • Adding new email template required a new workflow and manual updates to the management pack XML, which means the end user cannot do it alone.
  • There is no way to send notifications to email addresses that do not exist in the SCSM user list. In my environment, for example, I needed to send the notifications to all the email addresses in a specific field of the work item.
  • Does not provide a way to “Set First Response” or change the work item status to “Pending”
  • It has some multi users/messages reliability issues:
    • When you are trying to send the same message content again, even if you are changing the template, it will not send it and there will be no indication that the message was not sent.
    • When you are trying to send a second message while the work item is open in the console, the first message will not be sent and there will be no indication as well.
    • When you are trying to send a second message while the work item is not open in the console and before the previous sending workflow has been started, it will send two emails but both with the content of the second message.

All these issues forced me to develop a custom solution…

Read more in my company blog …

The Problem:
There are many blog posts and discussions about sending email notifications from Service Manager. Although Out-of-the-box, Service Manager has strong capabilities for notifications such as:

  • Template editor that allow the end user to insert relevant entity fields into the mail body
  • The ability to allow the end user to specify events conditions that will trigger specific notification, using a simple wizard.

What is missing is the capability to use this functionality from inside a SCSM Workflow.
There are some solutions provided by Travis (SendEmail) and German (http://scsmsource.blogspot.co.uk/2011/04/work-item-assignmentreassignment.html), however both these solutions do not allow customization to the workflow in the Authoring Tool.
In my SCSM environment I needed the capability to send notifications as part of more complex workflows and was also required to send the notification to external emails not defined in the SCSM users DB.

Read more in my company blog …

The problem:
SharePoint workflows, which are based on Microsoft WF, are a great way to automate processes that require human interaction and can be easily managed through SharePoint designer, without any custom development. But when it comes to automating IT processes, Microsoft provides us with another workflows engine called Orchestrator (part of System center). The Orchestrator has a variety of activities and integration packs that make him a powerful tool for implementing IT runbooks.
I needed a solution for users who design SharePoint’s workflows, using the SharePoint designer, to easily create workflows that will include execution of Orchestrator’s runbook. Using the SharePoint OIP (Orchestrator Integration Packs) you can monitor a SharePoint list for a change and execute a runbook as a result (as described here). However, this monitoring approach is based on pooling, so for example, if I’m using the default 30 seconds for pooling interval with the above approach for a task that is usually required once a week, it will generate more than 20,000 unnecessary queries against the SharePoint. Then, when the user will update the list’s item it will take up to 30 seconds before the workflow will start.
And so, it would seem that triggering the runbook from SharePoint will be a much better solution.

Read more in my company blog …


The Problem:
System Center Orchestrator 2012 exposes a data service that enables to query and execute runbooks.  But working directly with the data service is like executing a WCF service by manually composing the SOAP messages. There are no type-safe parameters, no intellisense and you need to type the exact path of the runbook or even worse, specify GUIDs . Developing and testing a code that is involved with runbooks execution quickly becomes a cumbersome and tedious task.

Read more in my company blog …


You can probably find several blog posts out there about remotely executing simple commands and scripts against Exchange servers, but trying to implement these examples on a “real” functional script, can introduce some annoying problems that nobody seems to mention. This was the case when I tried to develop a web page that was supposed to assist with managing a multi-tenant exchange 2010 SP2 environment. I got some startup scripts from Jacob Dixon’s blog and after some minor modifications I was able to execute them locally on the Exchange server without any problems, it was only when I tried to call these scripts from my web page that problems started:

Read more in my company blog …

The problem:
As a global company that has customers/partners all around the world, especially one that put on her flag community and sharing, inter-language communication and understanding of foreign content soon became a barrier. The company’s community site enables users to post and comment in any language and it is very common to see content in foreign languages, thus we needed to enable communications between staff and customers, partners, and suppliers from around the globe regardless of their preferred language.
There are quick and free solutions, such as Google Translator, that will only require inserting some code lines to your web pages and it will display a language combo that will enable the end user to translate all page content to their preferred language. The problem with this approach is:

  1. You will not have control over what part of your site will be translated.
  2. You will not have control over the combo language design and list of supported languages.
  3. The provider will take space on the top of the page and can include ads.
  4. You can’t set as default or automatically translate to the language a user selected on their community account as preferred language.
  5. You rely on the provider’s availability. If the provider is not responding or is busy your site will suffer.
  6. You are limited to one provider, although different providers have different strength for different languages.

The other option is to use a translator provider API; there are a couple of providers like Google, Microsoft Bing and WorldLingo that enable you to send the text over the web and get in return the translated text. This gives you a full control on the interface and enables you to take into considerations the user preferred language. The downside is that these providers cost money and/or limit the amount of text you can translate with them.
We needed a solution that will minimize the amount of text sent to these providers, will enable monitoring each provider usage and dynamically alternate providers or the language each provider handles all that in a fast and reliable manor that will require minimum change to the existing site.

The solution:
Using Telligent 6.0 new extended capabilities, I developed a plug-in and 2 widgets that tackled all the above issues and gave the site admin a lot of options to deploy and use the translator. Although the above were developed specifically for the Telligent community platform, they are a good example of how to use the Google and Bing API in production scenarios and can be applied with some minor changes to any web site.

The Translator Widget: the widget works with the Translator plug-in to translate any HTML element’s content with a specific CSS class. The content of the selected element will be sent for the original language to be detected and to be translated. If the original language is different from the required language the content will be replaced with the translated version and the user will be able to switch between the versions by pressing a keyboard shortcut key. The widget configuration also enables to show/hide a language combo and/or a quick translate button that will go back and forth between the original text and the last translated text (initialized to the user preferred language). Configuration will also determine if translation is done automatically or on demand. Another configuration will allow to display notification to detect translated text and/or add a tool-tip to the translated section.
All the widget activity happens after the page is completely loaded and in an asynchronies way so the loading time of the page is not influenced by placing the widget on the page.

Step-By-Step Configuration (as mentioned above)Translator- Widget Configuration

Translate all elements returned from this JQuery selector. A JQuery selector string is used to specify which HTML elements should be translated. The default value “.post-name, .post-content” will translate all elements that have CSS class “post-name” or “post-content”
Show languages combo. Show/Hide the languages combo. The combo contains all supported languages from all translator providers, as defined in the Translator plug-in.
Show quick translate button. Show/Hide quick translate button. This button enables quick switching between original and translated text (a keyboard shortcut, ALT-Shift-T, is always available regardless of this button display).
Get user language preference from: The user’s preferred language affects the behavior of the “On page load” options. The available values are:

  • User’s profile –default language will be the language the user set as their preferred language in the community account profile (only if this language is enabled by one of the translator providers in the Translator plug-in’s configuration).
  • Browser accepted language (auto detect) – the default language will be the language configured on the web browser (using the Accept-Language header).
On page load: Configure what will happen when page is loaded. The options are:

  • None – best for minimizing the use of the translator providers. Only if the user will require a translated version, the page will be translated.
  • Preload user preferred language – if you prefer to always show the original text version, but maintain in the background the translated version to the user preferred language. When the user will click on the “quick translate” or the keyboard shortcut, the translated content will be already available on the client and the switch will be instant.
  • Translate to user preferred language – the selected elements content will be translated automatically to the user preferred language.
Show notification when content was translated Show message at the widget location indicating that some of the content of the page was translated. The message will shown only if at least one of the HTML elements that are supposed to be translated contains text in language different from the user’s preferred language. The message text and style can be set via the widget-resource/widget-CSS respectively.
Show notification when translation service was not available Show a message if the translation failed (in case no translation was found in the cache and the translator provider is not available). The message text and style can be set via the widget-resource/widget-CSS respectively.

All the widget’s visible messages have a translated version in the widget’s resource for the following languages:  English, Danish, German, Spanish, French, Italian, Dutch and Swedish. The CSS style of the widget can be configured in the translator.css file that is included with the widget (using the widget studio).

The “SyncProfileWithBrowserPreferredLanguage” Widget: this widget is used to make sure that the user profile is synchronized with the user’s preferred languages as provided from the browser. On the first visit to a page that contains this widget, the widget will check if there is a difference between the current profile preferred language and the browser preferred language. The action to take when a difference is found can be configured as such:

SyncProfileWithBrowserPreferredLanguage- Widget Configuration

  • Update the user profile quietly – The user’s profile will be updated to prefer the same language as the browser without any notification.
  • Update the user profile and show alert message. – The user’s profile will be updated and alert message will notify the user about the change.
  • Show confirmation message and update profile if user confirms – A confirmation message will be displayed and only if confirmed by the user, an update to the profile will occur.

The Translator plug-in:  Manages the translation process. There are some configurations you will need to set before you are able to start using the translation widget. The plug-in dynamically detects any implementation of the translator provider interface under the site bin’s folder and enables their configuration.  The plug-in will try to send the entire element’s content in one big request but in case of a failure result, the provider will split the content to smaller pieces and will try again until succeeding or the content is not split-able.
General configuration:

Translator Plug-in Configuration

Keep in memory sliding expiration cache Minutes to keep in memory cache. The cache works in a “sliding way” so while a specific translation was accessed in the last x minutes; the cached record will stay in the memory cache.
Enable Database Cache This check box is not enabled by default but it is recommended to activate it. When first enabled, the plug-in will create in the database a new schema called “translator” including a table and some stored procedures. The plug-in supports SQL 2008 or later versions. Make sure the SQL user, configured in the connectionString.config file, has a db_owner permission when you first save this configuration, after the creation of the schema you can remove the db_owner permission.
Enable synchronization check between the browser’s language preference and user’s profile Define if the synchronization between the browser’s preferred language and the user’s profile is enabled. Used by the SyncProfileWithBrowserPreferredLanguage widget. When first enabled the plug-in will create a new Boolean profile field called “NeedToCheckSyncPreferredLanguage” that will keep a record of the synchronization process performance for specific user.
Show statistics for This read-only field show usage statistics for each provider for different periods: last day, last month and last year. This information can be used to monitor the amount of translation each provider actually translated as some provider can charge based on activity amount.

Each provider can have a specific configuration but usually will include authentication ID and a list of supported languages. The plug-in enables to configure which provider will translate which language. If the same language is marked on more than one provider the provider with the highest ID will be responsible for the translation. Specifying authentication ID for at least one of the providers is mandatory.

Google Provider - Configuration

Deployment steps:

  1. Download the binary and code from the link at the bottom of this post.
  2. Copy the Telligent.Extensions.Translator.dll and one/both providers assembly: Telligent.Extensions.Translator.Bing.dll , Telligent.Extensions.Translator.Google.dll to the Telligent website’s Bin folder.
  3. Obtain providers Application ID
    1. Google Translator from here.
    2. Bing Translator from here.
  4. Go to the “Manage Plug-in” page on the control panel (http://yourSite/controlpanel/Settings/ManagePlugins.aspx). You should see the “Translator Service Plug-in” on the plugins list.
  5. Click on “configure” beside the translator plug-in and setup the application ID you got in step 3.
  6. Enable database cache – optional.
  7. Go to the “Manage Widgets” page on the control panel (http://yoursite/controlpanel/tools/ManageWidgets/ListWidgets.aspx). Click on “Import Widgets” and select the TranslatorWidgets.xml as the widget file.
  8. Include the Translator widget on the page you like to translate. Configure the widget, make sure to choose the required elements to translate (by configuring the “Translate all elements returned from this JQuery selector” on the Translator widget.
  9. Browse the page…..

The source code and binaries for this article are available here


Get every new post delivered to your Inbox.