Today Campers we're playing Bingo. Or at least getting ready to. This week I have some PowerShell code that will create a BINGO card. For those of you outside of North America you might need to take a crash course on this game. But even if you don't play, this article will demonstrate some useful PowerShell concepts and cmdlets like arrays. Get-Random and New-Object.
A standard BINGO card is a 5x5 matrix with BINGO spelled out across the top and a column of unique numbers for each letter.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The first thing we need is an array of 5 numbers for each letter. Again, I'm sticking with the tradition where B is a number between 1 and 15, I is a letter between 16 and 45 and so on. Here's my first PowerShell step.
[cc lang="PowerShell"]
#generate unique arrays of numbers for each letter
$B=1..15 | Get-Random -count 15 | select -first 5 -unique
$I=16..30 | Get-Random -count 15 | select -first 5 -unique
$N=31..45 | Get-Random -count 15 | select -first 5 -unique
$G=46..60 | Get-Random -count 15 | select -first 5 -unique
$O=61..75 | Get-Random -count 15 | select -first 5 -unique
[/cc]
The range operator (..) will return all numbers between 1 and 15 (and so on). I need 5 unique random numbers from this list. Piping the list to the Get-Random cmdlet would return a single value. Using the cmdlet's -Count parameter in essence takes all 15 numbers and generates a random order. Sort of like this:
[cc lang="PowerShell"]
PS S:\> 1..15 | get-random -count 5
15
9
5
13
10
[/cc]
To get 5 unique values, I pipe the collection of randomized numbers to Select-Object where I instruct the cmdlet to select the first 5 but only return unique values.
In Bingo there is also usually at least one free space. I grew up playing in church with a free space dead center so that's where I put it on my card. There are variations with different free spaces but I'll let you work that out. For my card I'm going to modify the 3rd number t of the $N array using the string "FS" to indicate free space. Remember, arrays start counting at 0.
[cc lang="PowerShell"]
#replace 3 element of N with "Free Space"
$N[2]="FS"
[/cc]
Now for the fun part. Instead of trying to manipulate and parse strings, we'll use objects. You'll see the benefit in a moment. We'll use a FOR loop to count through the number of items in the letter arrays, which is 5. For each number we'll use New-Object and create a custom object. The letters in BINGO will be the property names and the corresponding array value becomes the property value.
[cc lang="PowerShell"]
for ($x=0;$x -lt 5;$x++)
{
New-Object -TypeName PSObject -Property @{
B=$b[$x]
I=$i[$x]
N=$n[$x]
G=$g[$x]
O=$o[$x]
} | Select "B","I","N","G","O"
} #close FOR
[/cc]
New-Object doesn't write property names in the same order you define them, so I pipe the object to Select-Object and get them in the right order. When I run my final script I get output like this.
[cc lang="PowerShell"]
PS S:\> .\New-BingoCard.ps1
B : 5
I : 22
N : 45
G : 55
O : 72
B : 4
I : 23
N : 44
G : 51
O : 75
B : 6
I : 21
N : FS
G : 58
O : 68
...
[/cc]
But that's ok. I'm writing objects to the pipeline. Now I have options one what to do with them. For example, I can pipe my script to Format-Table and create a good looking grid.
[cc lang="PowerShell"]
PS S:\> .\New-BingoCard.ps1 | format-table -AutoSize
B I N G O
- - - - -
7 18 39 53 68
1 30 43 50 65
9 23 FS 54 63
6 25 38 60 74
11 21 41 51 66
[/cc]
I could pipe it to a file, open in Notepad, increase the font size and print it out.
[cc lang="PowerShell"]
PS S:\> .\New-BingoCard.ps1 | format-table -autosize | out-file c:\work\bingo.txt
[/cc]
Or I can create an HTML version.
[cc lang="PowerShell"]
PS S:\> .\New-BingoCard.ps1 |
>> convertto-html -title "Bingo" -css c:\work\bingo.css |
>> out-file c:\work\bingocard.htm
[/cc]
I use a CSS link to add some nice HTML formatting. Here's my HTML bingo card..
The point I'd like to drive home is to NOT include formatting in your script, otherwise you lock yourself in and miss out on all sorts of other possibilities.
Download a zip file with my PowerShell script and CSS file here.
Another way to build a nicely formatted card that came to mind but I forgot to note is to pipe to Out=Gridview.
.\new-bingocard | out-gridview
Look for more on this topic next Friday.