December 6th, 2013

Solving Office Holiday Gift-Giving Conundrums with PowerShell

Doctor Scripto
Scripter

Summary: Microsoft Scripting Guy, Ed Wilson, talks about a project to assign secret pals at work. He ropes one of the managers into the project.

During my one-on-one last week with my manager, Adina, she mentioned doing something to help people who work from remote locations feel more like part of the team. Because I work remotely, I was all ears. She had a great idea: Assign random secret pals. You have to find out all you can about the secret pal, and then send them something that is unique to them—their interests, hobbies, or tastes. Of course, the present is something small, which also makes it a bit of a challenge. Although, maybe not. I mean, anyone who reads the Hey, Scripting Guy! Blog for very long knows that I enjoy different kinds of teas, and I am especially partial to Anzac biscuits—neither of which need be especially expensive.

So it is that kind of thing. And of course, I was in. Then Adina came up with a real kicker, “I wonder if you could write a Windows PowerShell script to do that?”

So I opened my big mouth and said, “Of course, I could write it. But with Windows PowerShell, the task would be so easy, that even a manager could write it.”

Now I had Adina’s attention. We discussed it a bit, and decided that Michel would be perfect for the task because as he has nearly no experience with Windows PowerShell. I offered, of course, to help with pointers. But before I got too involved, Michel had already solved the task at hand. I now turn you over to Michel LaFantano, a senior managing editor on our team, and I will let him tell you about his experience. Take it away Michel…

Our team at Microsoft includes many remote workers—some who work in non-Redmond Microsoft offices, and some who work from their homes around the country. This helps make for a diverse team, and it also lends a certain “open 24 hours” feeling to our group because there is pretty much always someone awake and online.

But it also means that remote workers rarely get the chance to hang-out in person, and we usually miss the morale events held on the Redmond campus. To help remedy that a bit this year, our director decided to hold a remote worker gift exchange. But how do we pick names from the fish bowl when people are dispersed across ten time zones?

Well, we figured a little Windows PowerShell script might help solve the issue. Being a resourceful kind of guy, I figured I would take a look in the Script Repository (or scriptorium, as I like to call it) and see if I could find something similar to leverage in creating our own “remote-gift-giver-partner-picker” script.

What I found was beyond all expectations, because I found a script that one of our awesome users had written for this exact purpose. Our scripter, who goes by the handle “CathersalCathersalCathersal,” wrote it for his family’s Secret Santa event, and it is called the “Virtual Hat.” Take a look:

Virtual Hat Windows PowerShell script

# This script will randomly draw a name out of a virtual “hat.”

#

# This script selects two names from an array in a random fashion.

# Because the people will exchange gifts, it is important that no

# person is assigned to themselves.

#

# Instructions: Just change the names below to the names you want and run it.

 

$NameArray = New-Object System.Collections.ArrayList

 

$NameArray.Add(“Syed”)

$NameArray.Add(“Kim”)

$NameArray.Add(“Sam”)

$NameArray.Add(“Hazem”)

$NameArray.Add(“Pilar”)

$NameArray.Add(“Terry”)

$NameArray.Add(“Amy”)

$NameArray.Add(“Pamela”)

$NameArray.Add(“Julie”)

$NameArray.Add(“David”)

$NameArray.Add(“Robert”)

$NameArray.Add(“Shai”)

$NameArray.Add(“Ann”)

$NameArray.Add(“Mason”)

$NameArray.Add(“Sharon”)

 

$numberOfNames = $namearray.count

$ArrayCopy = $namearray.clone()

 

for($i=0; $i -lt $numberOfNames; $i++)

{

    $NameToRemove = get-random -input $NameArray

    While ( $NameToRemove -eq $ArrayCopy[$i])  # make sure people don’t pick themselves.

    {

        $NameToRemove = get-random -input $NameArray

    }

    Write-host $ArrayCopy[$i]”picks $NameToRemove”

    $NameArray.Remove($NameToRemove)  # Remove the name so it doesn’t get picked again.

}

When I run the script, the output in the following image appears in the Windows PowerShell ISE:

Image of command output

Simple, yet elegant, don’t you think? And all we had to do to use it was add the names of our remote team members and we were good to go.

We all know that Windows PowerShell is an awesome tool in datacenters and at home, but who knew that it could also save the holidays? Issue solved. Back to you, Ed…

Turn an array into a hash table

While Michel was busy finding a script to use, I had also begun to tackle the issue. I figured it would be pretty simple because the Get-Random cmdlet is a powerful tool. In fact, we use the Get-Random cmdlet when handing out prizes at PowerShell Saturday and at Windows PowerShell User Group meetings. So I am familiar with this tool.

If all I wanted to do was randomize a list of names, that is two lines of code (it could even be one if I do not store the array of names in its own variable). But I wanted a two-column output. At first I thought I could use Format-Wide and specify two columns. But after messing around with it for about a minute, I saw that for some reason, Format-Wide does not like to convert an array into two-column output.

So I decided to convert my array of names into a hash table. Here is the script I wrote to do this:

# ArrayNamesToHashTable.ps1

# ed wilson, msft

# Secret Pals blog posting

# HSG-12-6-13-b

# —————————————————————————–

$names = ‘Syed’, ‘Kim’, ‘Sam’, ‘Hazem’, ‘Pilar’, ‘Terry’, ‘Amy’, ‘Greg’,

    ‘Pamela’, ‘Julie’, ‘David’, ‘Robert’, ‘Shai’, ‘Ann’, ‘Mason’, ‘Sharon’

 

$rndNames = Get-Random -InputObject $names -Count ($names.count)

$hash = @{} ; $i = 0

Do {

 $hash.Add($rndNames[$i],$rndNames[($i+1)])

 if($i -le $names.count){$i+=2}}

 While ($i -le $names.count-1)

 $hash

When I run it, I get a nice two-column output, as shown in the following image:

Image of command output

So in the end, it took me more time than it did for a manager to “write a script.” All told, I spent about an hour messing around with this script. But I imagine that I had more fun writing my script than Michel did. After all, I used the Windows PowerShell ISE and he used Bing.

You can find the script in the Script Repository: Randomly draw names out of a virtual “hat.”

Join me tomorrow when I will have more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.