Being a consultant at CTG for 17,5 years…

Being a consultant at CTG for 17,5 years…

Yesterday, we had a team meeting at work and Jochen, our unit manager, had a great idea. Why not tell the public how much you like your company. This is indeed something we should do more often.  He put his money where his mouth was, and did it live on LinkedIn.

I’m going to do it my way… this will end up on LinkedIn anyway 🙂

What does CTG mean to me? Well, obviously a lot, because I have been working there for the last 17,5 years. I have seen many colleagues come and go but I always stayed put and believed in them. Why? There are a lot of reasons, but the main reason is the way they treat their people.
A lot of organizations show off with fancy certifications and awards and you can (and should) be sceptical about these things. CTG also has some… we have been part of The Best Workplaces in Belgium for many years. We have been Investor in People for a long time.

Every year, on my career appraisal, my manager asks the same question… Are you still happy at CTG? And I always respond with the same thing:
If I get to a point where I go to work unhappy, I quit. It’s a simple as that. And this is something I literally mean.

So, what makes me so happy at CTG? It’s a combination of things.
The culture is one thing. We have a very open culture.
In my long career as a consultant, I talked to a lot of people and it amazes me how many organizations are out there that have a culture where people work against each other as part of internal politics and internal competition. I can’t imagine myself working in such an environment. And this is what I like about CTG. People are not working for their customers and their personal gain. They are working for OUR customers and to grow on a personal level but also to grow and mature the company.
Most of the time, I’m working on site with customers. But when I have a day where I’m going to the office, it feels like coming home. You immediately feel the positive vibe. People enjoy what they are doing. It’s difficult to describe this feeling… you need to experience it to understand it.

Another thing is that everybody is trying to help each other. When I started at CTG, there was a thing they called a SIG (Special Interest Group). These SIGs were groups of people getting together occasionally to share knowledge on topics they were passionate about. Fast-forward 17 years and these SIGs have evolved in Centres of Excellence (CoE). But at the core, it’s basically the same thing. Beside these centers we also encourage knowledge sharing by organizing Masterclasses en learning on the job by hosting regular Lunch & Learns where people get together during lunch to discuss specific topics of interest or have a small workshop. These L&L sessions are short, to the point and they work. They enhance the interaction in the different teams and encourages people to share their knowledge. The internal communities are like small ecosystems that live independent from each other but regularly bond and interact to join forces when needed. Not only on a professional level but also after work, these small communities get together to have some fun.

On a personal note, CTG meant a lot to me during one of the most difficult periods of my life. In 2015, after 9 years of trying, we were finally expecting our first child. But we lost our little boy during labour. After the initial shock, I notified my manager and unit manager that I was taking all of my vacation and that I needed time to process this. They immediately acted and relieved me from all administrative burdens. Family comes first. My customers were notified, and colleagues took over some my most urgent assignments without any hesitation. The sheer number of messages I received the first day from colleagues, office staff and management was so overwhelming, it took me 2 days and a lot of courage and tears to get through them. It took me 2 months to find enough courage and energy to go back to work. I was a bit worried I would see a lot of people trying to comfort me and I was not looking forward to those awkward moments. I didn’t feel like talking about it very much at that time. But to my surprise, none of my customers confronted me with this… which meant that CTG handled my absence with the upmost discretion. And I respect that. Says a lot about a company and how much they care about the wellbeing of their employees. They understand it’s the people that make your company, not just numbers and figures.

I currently have the role of Service & Technical Owner (STO) of the Business Productivity Solutions team. This team focuses on Office 365 and SharePoint and assists our customers in setting up modern workplaces or assist customers in transforming their traditional collaboration environments in modern collaboration workplaces. This is a very challenging role because Office 365 is a constantly changing platform where services come and go. Being an STO involves me on a higher level in decisions which are made to grow the company. Our management believes firmly in the importance of having senior consultants in these roles as they have a solid knowledge of their area of expertise and can be a bridge between the management and the people who are doing their best every day to build and expand the services we offer to our customers. This emphasizes the efforts the management do to involve the people in decisions which might affect their professional lives.

No bad memories, no times where the dark side tried to lure me away? Sure, there have been times. I’m not going to lie about it. Everybody has those moments of frustration and irritation. But then I think back to those past 17 years, what are the chances I’m going to find another great company like that? Lots of colleagues left, but a lot of them also came back because they missed CTG and its unique culture. That says it all.

If you want to be part of this family, don’t hesitate to drop a line. Our doors are always open, and we are always on the lookout for people who fit in the organization and are talented in what they do.

The Importance of Completing Tasks in Workflows

When you use workflows in your organization to automate business processes, you have to deal with the fact that people are lazy. They don’t like work. One of the things you do a lot in workflows, is create tasks. Somewhere in a process, somebody needs to complete a task before the next step in the process can be completed. So, the task is created and your workflow waits until someone completes it. The importance of completing tasks in the context of workflows is often underestimated. Completing a task in the context of a workflow is a 2-step process and this is a concept which lots of people don’t seem to understand and this leads to a lot of problems.

  • Step 1: Executing the action in the task
  • Step 2: Mark the task completed

Let me give you an example on how this might lead to issues.

You have an onboarding workflow for new employees. This workflow initiates several other workflows.
One of those other workflows is the creation of an Exchange mailbox. This “Exchange Mailbox Creation” workflow creates a task for the Exchange admins which instructs them to create a mailbox for the new employee.

Meanwhile, the main workflow handles some other stuff which is important for onboarding the new employee. Somewhere at the end of the process, the main workflow is going to check if the mailbox has been created. As long as the mailbox is not created, the onboarding process cannot be completed.
To do this, the workflow contains a loop which checks if the Exchange Mailbox Creation workflow is completed. If it’s not, It’s going to pause for 1 hour and check again. This repeats itself until the Exchange Mailbox Creation workflow is completed.

The problem is… that workflow will NEVER end because the people who are responsible for creating Exchange mailboxes do understand the importance of creating a mailbox for a new employee, but don’t understand the importance of marking the task completed in the system. They don’t know that the overall onboarding process relies on the completion of those tasks.

Direct results :

  • The Exchange Mailbox creation workflow will be waiting indefinetely unless someone sets that task to completed
  • The onboarding process for this employee will never finish because of the Exchange Mailbox Creation workflow will never finish

Indirect results:

  • The history list will grow constantly because of the loop which generated 2 list items every hour (for the pause action). Read this post to understand the importance of maintaining a history list.
  • The workflowprogress data table will grow constantly because of the same loop. Read this post to understand the importance of workflowprogress data.

A workflow designer has the responsibility of covering this by :

  • including reminder notifications in the tasks
  • Have some kind of escalation procedure in the case nobody bothers to complete those tasks. Escalating to a manager often helps
  • Make sure that the task notifications stress the importance of completing the tasks for a proper process termination. This should also be emphasized in the reminder notifications or escalations as well

For the example of the onboarding process, I had 91 running instances which have been running for months up until a year because of these incompleted tasks. These 91 instances are responsible for a history list that grows with almost 4400 list items every single day.

You can avoid all of this by thinking through your process and include logic in your workflow and tasks to avoid these situations. But if you are tasked with cleaning up an environment where these kind of issues exist for a while, you might have an environment which has thousands of running workflows that keep filling your history lists and workflowprogress tables with useless information and you need a way to stop this madness.

If you are using Nintex Workflow, you can use the below which allows you to terminate Nintex Workflows in batch. You specify your Nintex content database and a date and the script will terminate all running instances that didn’t have any activity since the specified date.

Keep in mind that terminating workflows might result in notification emails being sent by the system.


Maintaining Nintex Workflow Progress Data

In my last post I talked about maintaining the workflow history lists throughout SharePoint. This post is about maintaining Nintex workflow progress data. This data is found in the WorkflowProgress table in a Nintex content database.

When a Nintex Workflow is executed, each action is recorded in the WorkflowProgress table. This gives the system the opportunity to show a graphical representation of the workflow history for a specific instance. You can imagine that this table can contain a lot of information. Nintex recommends to keep this table below 15 million rows to avoid performance issues.

To maintain this table, you can use the PurgeWorkflowData operation of nwadmin.

The PurgeWorkflowData operation has a lot of parameters to specify which records it needs to purge. These parameters might not be enough to limit the records you want to purge. There’s a little catch in purging workflow progress data. To allow proper maintenance of the workflow history data, you need to make sure that you only purge workflow progress data for workflow instances where NO workflow history exists anymore. This means that there’s an order in how to maintain both the history lists and the workflowprogress table:

  1. Workflow History Lists
  2. WorkflowProgress table

If you purge the WorkflowProgress table before you clean the workflow history, you will end up with history list items which cannot be purged anymore in a selective way (using the ‘PurgeHistoryListData’ operation of nwadmin). You can only purge them by clearing the list completely.

Read more

Manage Office 365 using PowerShell

As someone who’s primary job is being a SharePoint administrator, the Rise of the Cloud (Office 365) was something which scared me in the beginning. Was my job doomed? Well, not exactly. You see, Office 365 is complex and it evolves constantly. Yes, a lot of stuff you do as an administrator on-premise is taken off your hands by Microsoft engineers at the datacenters but there’s plenty of stuff to “administer” in a cloud environment. You still need to manage users and their habits of losing passwords. You still need to create site collections, manage mailboxes, set up retention policies, and so on. Microsoft did a great job of providing a nice administration portal for all of these tasks but they also provide PowerShell management modules for all of the services in Office 365 to allow administrators to manage their tenant locally from their machine. This post gives an overview of the things you need to manage the different areas (services) in your Office 365 tenant.


A few weeks ago, the Azure AD PowerShell v2.0 module hit general availability and is now the recommended module to use when you want to do Azure AD management using PowerShell. At the time of this update, the latest stable version is The old module (msonline) will be deprecated in the near future.

To use this new module, you need to install it from the PowerShell Gallery. To install a module from the PS Gallery, you need to install PowerShellGet on your machine. If you have a Windows 10 machine, this will already be installed and you can proceed with the installation of the module itself. If you have Windows 7 or 8.x, you have to install PowerShellGet first. You can find a link to the .MSI on the link below.

Once this package is installed, you can proceed with the installation of the AzureAD module.

The first line will set the PowerShell Gallery as a trusted repository. If you don’t set it as a trusted repository, you will see a warning when you run the Install-Module command.
If you have already an earlier version of this module (ex., you can update it to a newer version by specifying the -Force parameter with the Install-Module command.

After the module has been installed, you can use it to manage your users, groups, licenses, and so on.

Skype for Business Online

To manage Skype for Business Online, you need to install the following package:

Once the package is installed, you can open a PowerShell console and connect to Skype for Business Online.

SharePoint Online

To manage SharePoint Online, you need to install the following package:

Once the package is installed, you can open a PowerShell console and connect to SharePoint Online.

The URL you need to provide to connect to SharePoint Online, is the URL of the SharePoint admin center in the Office 365 portal. For instance:

Exchange Online

To manage Exchange Online, you don’t need to install additional packages. You can execute the lines of PowerShell below to get started. When these lines are executed, the Exchange Online cmdlets are imported in your session. When you change Management Roles in Exchange Online however, you need to relaunch the session because changing roles also means that the cmdlets you CAN use, will change.

Rights Management

To manage Azure RMS in your Office 365 tenant, you need to install the following package:

When this package is installed, the PowerShell module will be installed on your machine.


Add a SQL Alias using PowerShell

Setting a SQL alias on every SharePoint server is a common task when you are installing SharePoint. You use the SQL Server Client Network Utility (cliconfg.exe) for this. This tool is available on every SharePoint server because it’s part of the SQL Server Native Client prerequisite.

Setting a SQL alias is a best practice because it makes your life a whole lot easier when you want to change the actual database server in some point of time. If you use an alias, the only thing you need to do at that moment, is change the target of your alias and you’re good to go. If you install SharePoint and you reference the database server directly, your only way of pointing SharePoint to the new database server painlessly, is to create an alias at that time, set the name of the alias to the name of the old database server and have it point to the new server. Definately not cool because when someone looks at the Servers in Central Administration, it will list the old name and it’s not clear that this is not a server anymore but an alias.

When you want to set an alias, you run cliconfg.exe on each SharePoint server. In this tool, you have an “Alias” tab, where you can set it. You provide a name, the type of connection (Named Pipes, TCP/IP) and a server name. You can also select a custom port if you use TCP/IP or keep the default.

sql alias - 01

If you don’t want to do this manually, there’s also a way of doing this with PowerShell. The only thing this tool does, is create a string value in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo

sql alias - 01

So, doing this using PowerShell is easy.

You can find this script in my PowerShell Repository on GitHub.

TFS Build agent running but still displayed as offline

A colleague of mine notified me today that there was a problem with the TFS build agent on our TFS server. When he tried to queue a build, the following message popped up:

There are issues with the request or definition that may prevent the build from running:
There are agents that are capable of running the build, but they are not online. If the agent is configured to run as a service, ensure that the “VSO Agent ({agent name})” service is running.


This looked like a no-brainer. Probably the service which was not started. When I looked at the service, I noticed that it was running.


I checked the Agent pools in the TFS Control Panel and this was showing a red status while it should be green. Not good.


To see what was going on, I went to the folder where the agent was installed. In that folder, a _diag folder exists with logging. After opening one of the log files, I noticed this error:

System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.Net.WebException: Unable to connect to the remote server —> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it

(IP is replaced with xxx in the message above).

The IP which was listed, was the IP of the TFS server. What got me thinking in the right direction for a solution, is a part of the logfile above the message where the settings are loaded:

VsoAgent.exe was run with the following command line: “C:\BuildAgent\agent\vsoagent.exe” /runningAsService
12:04:06.109768 SettingsFileHelper.Load – settings[AutoUpdate]=True
12:04:06.109768 SettingsFileHelper.Load – settings[RootFolder]=C:\BuildAgent
12:04:06.109768 SettingsFileHelper.Load – settings[WorkFolder]=c:\BuildAgent\_work
12:04:06.109768 SettingsFileHelper.Load – settings[ServerUrl]=
12:04:06.109768 SettingsFileHelper.Load – settings[AgentName]=xxxxx
12:04:06.109768 SettingsFileHelper.Load – settings[PoolId]=1
12:04:06.109768 SettingsFileHelper.Load – settings[PoolName]=default
12:04:06.109768 SettingsFileHelper.Load – settings[AgentId]=2
12:04:06.109768 SettingsFileHelper.Load – settings[RunAsWindowsService]=True
12:04:06.109768 SettingsFileHelper.Load – settings[WindowsServiceName]=vsoagent.tfs.xxxxx
12:04:06.109768 SettingsFileHelper.Load – settings[WindowsServiceDisplayName]=VSO Agent (xxxxx)

The “ServerUrl” setting listed the default URL for TFS. Which is HTTP on port 8080. But I remembered that we changed our configuration to run on HTTPS. So, our TFS was not at 8080, but 443 and then it hit me… I configured the buildagent before we changed to HTTPS.

The solution to this issue was pretty clear, I needed to update the “settings.json” file in the buildagent folder and replace the old URL with the new one.
After changing this file, I restarted the buildagent service, went back to the Agent Pools, refreshed the page and noticed the status changed to green.


Good to go!

Change UPN Suffix using PowerShell

A few weeks ago, I was implementing AD synchronization between an on-prem Active Directory and Office 365. One of the prerequisites is that the UPN (User Principal Name) suffix for the users which are synchronized to Office 365, has to be a public domain name. The domain I was working with, was a local domain (.local). So, I had to change the UPN suffixes for all users to the public domain name. Because I had to change thousands of users, I created a PowerShell script which does it for me. The script does a few checks before it actually tries to update the UPN:

  • It checks if the “ActiveDirectory” module is installed. We need this to interact with the objects in Active Directory. If it’s installed, it’s loaded automatically if not already loaded.
  • It checks if the new UPN suffix, which needs to be provided by means of a parameter, is registered as a UPN suffix in the domain.

The script has 4 parameters:

  • OldUPNSuffix : This is UPN Suffix which is going to be replaced with the new one.
  • NewUPNSuffix : This is the new UPN suffix
  • Filter : This is a filter which is used in the Get-ADUser cmdLet and is used to retrieve all user objects we are working with. For more information on the filters which can be specified, check the documentation for the Get-ADUser cmdLet.
  • Mode : I made the script to run in a “List” and “Modify” mode. When you specify “List” as value for this parameter, the actual change is not done but it’s only logged in a file. Comes in handy when you want to see the results before you actually unleash it with the “Modify” value. And yes, I know… you can do this with the -whatif also. But then again, I prefer my logfile output over a scrolling command console with a massive amount of output.

Now, for the script… here it is. Nothing to fancy really.


SharePoint 2013 Trial License – License Upgrade FAIL

I consider myself as someone who knows a lot of SharePoint. I don’t know everything and I’m learning new things every day. Which is good because this motivates me. One of those things I learned (the hard way) in the last couple of weeks is about licensing and the consequence of using a SharePoint TRIAL license. Let me elaborate a bit on this.

Last year, I installed 2 SharePoint farms at a client. When you install SharePoint, the first thing you need to provide, is the license key. Because nobody was able to provide me the key at that time, I used a trial key which is valid for 180 days. You can get this key over here.

A few weeks ago, I was notified that a Microsoft audit was on the way concerning licensing and they ran the Microsoft Assessment and Planning Toolkit to have an overview of the licenses. The result was that all involved SharePoint servers were identified as ENTERPRISE servers. This was a problem since they don’t have Enterprise licenses and were expecting Standard servers.

I was convinced I never activated any Enterprise features in both environments and ran some PowerShell scripts to see on all kind of levels if Enterprise features were active and to my surprise, they were activated on all sites. Since none of those features are used, I proceeded to deactivate all of them.

The report was created again… still Enterprise servers.

Then I remembered that I used a trial key and the Upgrade License page in Central Administration allows you to see the current license and replace that license with a different license.

And there was the culprit… the Trial key for SharePoint 2013 is a “SharePoint Server Trial with Enterprise Client Access License

My first reaction was: “I never saw an option to choose between a Standard and Enterprise Trial”. And that’s correct… there’s only 1 trial and that’s Enterprise!

I checked the page where you can find the evaluation version and you won’t find any reference or notification of the fact that the trial version is an Enterprise license!!!! Come on!? Why not? The only possible hint of this being an Enterprise version is the mentioning of “full-featured” in the Preinstall Information section. But that’s interpretation, right?

One would think that you could simply put in your Standard license key and “upgrade” that Enterprise trial to a Standard server license, right? Well, I wish it was that simple. enterprisetrial

It’s simply not possible. You cannot replace the Trial license with a Standard Server license. It expects an Enterprise server license key. Somehow this makes sense. When you look at SQL Server, the same thing applies. You can’t downgrade an Enterprise Edition to a Standard Edition either.


Well, not many I’m afraid. The only viable option I found was to uninstall SharePoint completely. And by uninstalling, I’m referring to this. That’s removing the binaries from the servers and reinstalling them. Upon installation, provide the Standard Server License key and get that show on the road. Luckily, you can hook up the databases from the old trial environment without issues.
This is such a situation where having a detailed installation/configuration documentation pays off. I make a habit of documenting everything in full detail with screenshots in OneNote, with the scripts I use and the parameters which are used for them. This makes it very easy to redo it if needed. So, doing this reinstallation was a breeze for me.

But I can imagine that if you don’t have such documentation or you have it but some wannabe professionals came in and started modifying things manually, not documenting a thing… you might be in a world of hurt.

As a seasoned SharePoint professional, I have to admit that I was a bit shocked of the fact I didn’t know this. This seems like a “Duh! Basic knowledge!” kind of thing. Definitely not my best day when I found out about this. 😳


OneDrive Sync Engine Host Crash on Win 8.1 solved at last

For a while now, I have been experiencing issues with OneDrive on my Windows 8.1 machine. I don’t know when it started but it’s at least going on for a month or 2. Everytime my Windows is started, the OneDrive synchronization service (SkyDrive Sync Engine Host) is started and after a short period of time, it just stops working. It restarts after a while but it crashes again… this goes on and on… really annoying because I have to sync everything manually by going to OneDrive and upload it there.

When you use Google and Bing, you get tons of people experiencing the same issue. What really annoys me about it is the fact that there’s NO fix from Microsoft for this. Really! If you post your issue, they just tell you to run a diagnostic tool to “fix” OneDrive. For some people this works, for others it doesn’t.

Well, I’m one of those people where it doesn’t work and who clicked like every link on Google and Bing and tried everything.

The only thing which works TEMPORARILY is to move my local  OneDrive folder to another location. This works UNTIL my PC is rebooted. Then it just starts crashing again.

Now, Since a few days, my issue is solved. I found a link where somebody (from Microsoft?) hinted about OneDrive needing access to “some” place in the registry. If it can’t access it, it crashes.

Because I was sick and tired of this crashing, I started disabling services which were running… starting with the things which were sitting in my system tray. After each service, I waited until the OneDrive service was started again and checked if it crashed.

And yes, I found the nasty bugger who is responsible for the crashing !!!!!

It’s the SDTray.exe service from Spybot – Search and Destroy. This is started when my PC is booted. When I exit this application in the system tray, my OneDrive start and will not crash anymore.. I guess it blocks access to resources which are needed by OneDrive (registry?).

This worked for me. But if you don’t have this SDTray application and you are experiencing the same issue, checking for running services which might have the same behaviour might be a solution for you.

Close disconnected remote sessions using PowerShell

Do you know this situation? You are responsible for some servers and you planned to do some patching during the weekend. You open a remote desktop to the server with the administrator user and you see that the session is still active. Visual Studio is open with unsaved source code, some config files are open, even somebody’s Facebook is nicely ready for you…
Or you start to install some critical updates and when you want to reboot, Windows tells you that there are other users logged on… you check the users tab in the task manager and you see some “disconnected” sessions. Arggh! 👿

I grew tired of reminding people to log off instead of just closing the session. Some people listened, some are too lazy and won’t listen.

So, I wrote myself a little script which runs every evening and terminates all disconnected sessions, regardless of unsaved shizzle that’s happening in them. Really, people only learn to follow the rules when you hit them where it hurts. Sad, but true.

So, here’s the script…

I created a task in the task scheduler to run this every evening at 9PM.

You can find this script in my GitHub PowerShell repository.