The other day, while going through some of my old PowerShell scripts, I stumbled across something I had almost forgotten about: the Wild Tore leveling guide.

I had completely forgotten that I had documented this nonsense.

It made me laugh. Not just because of Wild Tore himself, but because I suddenly remembered how much fun that whole project had been. It might actually be one of the most fun things I’ve ever built.

The Wild Tore is what happens when gamification is left unsupervised. The idea was to make using the new user management tool a little more fun, and hopefully make the service desk a little happier too. By doing your job correctly and completing operations in the tool, you could earn points and level your own Wild Tore. Every 25 points, Wild Tore levelled up and acquired a new ability. At some point we had Transportation Wild Tore, AfterWork Wild Tore and Recruiter Wild Tore, complete with an actual leveling guide explaining his new abilities.

It was ridiculous.

It was also genuinely useful. Well, not Tore himself. He was just our manager.

And looking at it now made me realise that Wild Tore is probably a better representation of how I ended up in governance than any carefully constructed career story could ever be.

Because I never set out to become a developer. I never set out to work with governance either.

I just kept trying to solve the next problem.

So, if I’m going to explain how I ended up with a PowerShell-based user management tool, an integration, logging, diagnostics and a Pokémon-like version of my manager appearing inside the application, I need to go back to the beginning.

From service desk to PowerShell

When I got my first job at a service desk, I was honestly a little impressed with myself. I had been working with Office 365, mainly for smaller companies, and somehow I had managed to get myself a proper job in IT.

My new customer was a Nordic company. That meant Active Directory, among other things, and user creation was done manually according to a process that had been written down in a text file. There were several different versions of the process stored in the same OneDrive. I was never completely sure that I was using the right one.

This was where I learned a few things very quickly. For example, that userPrincipalName and SMTP addresses being the same does not mean that a human being will necessarily type them the same way every time.

I also learned that Bob did not particularly enjoy being named Bobb. He was also not impressed by the fact that he had to sign in with three Bs instead of two.

BOB → BOBB
When your fingers are slightly less precise than your intentions.

This was, of course, entirely my fault. I had simply typed his name wrong. Given how clumsy my fingers are, he should probably consider himself lucky I stopped at three Bs.

It was a small thing, but small things have a habit of becoming surprisingly annoying when the person on the other end is trying to start their first day at work.

I started thinking that there had to be a smarter way of creating users.

My husband suggested that I write a PowerShell script.

I thought this was a terrible idea.

Not because the problem wasn’t worth solving, but because I was obviously far too old to learn programming. Everyone knows that programming skills have to be supplied with the mother’s milk. There is apparently a critical developmental window for acquiring the ability to understand variables and curly brackets, and I had unfortunately missed it.

My explanations were ignored.

Instead, my husband started teaching me PowerShell.

Eventually I wrote my first function.

It was not particularly sophisticated, but it worked. That was enough to convince me that perhaps this whole programming thing was not completely impossible after all.

function New-UPN {
    param (
        [Parameter(mandatory = $true)]
        [String] $GivenName,
        [Parameter(Mandatory = $true)]
        [String] $Surname,
        [Parameter()]
        [String] $MiddleName,
        [Parameter(Mandatory = $true)]
        [String] $Server
    )
    $gname = $GivenName -split ' '
    $sname = $Surname -split ' '
    $mname = $Middlename -split ' '

    Write-LogDebug -Message @"
New-UPN called with
GivenName = '$GivenName'
MiddleName = '$MiddleName'
Surname = '$Surname'
Server = '$Server'
"@

    $UserPrincipalName = Get-EmailSafe($gname[0] + '.' + $sname[-1])
    Write-LogDebug -Message "Trying UPN '$UserPrincipalName'"
    if (Test-AvailableIdentity -Identity $UserPrincipalName -Server $Server) {
        return $UserPrincipalName
    }

    for ($i = 0; $i -le 5; $i++) {

        $names = @($gname[0])

....................

Automation has consequences

Then I had another brilliant idea. If I had written functions that made user creation easier and less prone to mistakes, perhaps my colleagues could use them too.

Some of them were perfectly capable of creating users manually, of course. That wasn’t really the point. Why should several people repeatedly perform the same steps manually if a little piece of code could do it for them?

So my functions multiplied.

And, as functions tend to do when they are being used by other people, they occasionally needed bug fixes.

This created a new problem.

I was now responsible for updating everyone’s PowerShell.

At first I did this the obvious way: by updating things when they needed updating. Then, being fundamentally lazy when it comes to repetitive work, I started wondering whether I could make the updates happen automatically.

The obvious solution was to turn it into a module.

So I did.

After some experimenting, I managed to create a module and set up automatic updating through NuGet and a private Azure DevOps feed, so the latest version would be pulled in when people started PowerShell.

I was convinced I had solved the problem.

Or so I thought.

Apparently, PowerShell needed a GUI

Instead, I started receiving increasingly subtle links from colleagues with titles such as “How to create a GUI from your PowerShell script.”

I ignored them for a while.

PowerShell was perfectly beautiful. It was obvious. It had a command line. What more could anyone possibly want?

Eventually I thought, fine. I’ll try it.

Since my programming knowledge was still approximately zero, I found a guide for creating a WinForms application. Looking back, I would probably not recommend that as a long term architectural strategy, but it was an easy enough way to get started.

The little application grew into an actual tool for the service desk.

It could create users and generate User Principal Names automatically based on first name, surname and country. It could assign the common distribution lists and groups needed for the user to end up with the right configuration, and it could handle things that were surprisingly easy to get wrong manually.

If an email address needed to be changed, the old primary address could be retained as an alias while the new address became primary.

You could assign groups, compare access between users and search for users without having to remember exactly where everything lived.

At this point I was reasonably happy.

I had started with a text file and some manual user creation, and I had ended up with a small application that removed a fair amount of repetitive work from the service desk.

When the script became a service

Naturally, this was when the customer decided that I should write an integration.

The reasoning was apparently very straightforward: I could do PowerShell and I created users, so obviously I could write an integration as well.

The project was supposed to be tested the following week.

I assumed this was probably a perfectly normal situation and that I was simply being a bit of a wimp.

So I built the first version.

I did need some help from my husband, mainly because logging was something I had not really considered properly before. But I was the service desk, so I already knew what information would actually be useful when something went wrong. I was going to be the person dealing with the problem afterwards.

Write-LogError -EmployeeID $EmployeeID -Message "..."

The integration ended up with logging for information, debugging and errors, tied to the employee ID. The user creation logic was already handling things like country specific UPN generation, managers, licenses, groups and various Active Directory attributes, so there were plenty of opportunities for something to go wrong.

The logs were stored in a location that not everyone on the service desk had access to. Rather than giving everyone access to the logs, I gave the service desk tool permission to read them and present the relevant information in the tool.

So a technician could search for a user and see what had happened, together with the information needed to resolve the problem, without having to know where the underlying logs were stored. Some types of errors were sent directly by email to the ticketing system.

It was a fairly simple principle: give people the information they need without necessarily giving them access to everything behind it.

Meet Wild Tore

Then came the summer.

I was on vacation, had stepped badly and ended up having to sit still for a few days. Since I couldn’t really move around much, I was getting bored and ended up joining a social Teams meeting.

At some point, the conversation turned to the application and the fact that it needed pictures.

Why it needed pictures was less clear.

What was clear was that we needed to decide what kind of pictures would add any value.

One of my colleagues was very into Pokémon Go at the time. Another immediately said that we needed “A Wild Tore has appeared.”

That made me laugh far more than it probably should have. Tore was my manager at the time, so Wild Tore was obviously based on him. If your manager suddenly appears in the middle of the working day, that is clearly the correct way to represent the situation.

Luckily, Tore had a sense of humor. Otherwise, my upcoming salary review might have become slightly uncomfortable.

So I built it.

Inspired by Pokémon and the idea of levelling, I added a simple reward system. When you performed an operation correctly, you got a point. Every 25 points, Wild Tore levelled up.

And because apparently points weren’t enough, Wild Tore needed abilities.

I don’t have any drawing skills, and this was before AI, which probably would have helped me create some basic pictures that wouldn’t even have been half as much fun. All credit goes to my former colleague Lene, who captured Tore’s inner soul perfectly. Thanks again for these pictures. They still make me laugh.

From there things became increasingly ridiculous in a very structured way.

Wild Tore gained Transportation, followed by AfterWork and eventually Recruiter.

Transportation Wild Tore appeared after Tore got his motorcycle licence. There were differing opinions about whether someone responsible for keeping parts of production running should voluntarily place himself in traffic.

AfterWork Wild Tore appeared because we liked afterworks and felt he should participate more frequently than he managed in real life.

Recruiter Wild Tore appeared because, like most operations teams, we were permanently convinced that life would improve if someone could just find us a few more colleagues.

To document these developments properly, I created an actual leveling guide. Somewhere along the way, Wild Tore stopped being a joke and became a feature.

I just didn’t know it was governance

Looking back, I can see something else in that story. I thought I was learning PowerShell and building a tool. In reality, I was running headfirst into all the things that happen when something stops being a script on your own computer and becomes something other people depend on.

And the more the tool grew, the less the problem was about automation itself.

It needs to be maintained. Someone needs to distribute updates. Someone needs to understand what happens when it fails. People need access to the information they need, but not necessarily access to everything behind the scenes. And when the process changes, the tool has to change with it.

None of that felt like governance at the time. I wasn’t thinking about governance at all. I was just trying to make the thing work.

Who should have access? Who is responsible for the solution? How are changes handled? What happens when something fails? What happens when the process changes?

Those were the questions I had gradually ended up dealing with without even realising where they were taking me.

I had a text file, a service desk, a growing collection of PowerShell functions and a very strong desire not to have to do the same thing twice.

And somewhere along the way, that turned into an application with its own logging, controlled access, integrations and an unexpectedly elaborate evolution path for a Pokémon version of my manager.

Which is probably as good an explanation as any for how I ended up in governance.

.

Author

  • I work with Microsoft's identity solutions at Epical, with a particular focus on Microsoft Entra ID Governance, identity lifecycle automation and PowerShell. I write about practical challenges, things I've learned, and solutions I've built along the way.

    Based in Sweden. Find me on LinkedIn and GitHub.

    View all posts

Discover more from Agder in the cloud

Subscribe to get the latest posts sent to your email.

By Sandra Saluti

I work with Microsoft's identity solutions at Epical, with a particular focus on Microsoft Entra ID Governance, identity lifecycle automation and PowerShell. I write about practical challenges, things I've learned, and solutions I've built along the way.

Based in Sweden. Find me on LinkedIn and GitHub.

Leave a Reply