Use PowerShell to Choose a Specific Number of Random Letters

Use PowerShell to Choose a Specific Number of Random Letters

  • Comments 1
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use the Windows PowerShell Get-Random cmdlet to choose a specific number of random letters.

Microsoft Scripting Guy, Ed Wilson, is here. With the advent of the New Year, I am hard at work on the 2012 Scripting Games. This year there will be several improvements. I always learn from each year’s games, and I am a firm believer in continuous improvement. Right now, I am busy working on selecting the ten domains that I will emphasize in this year’s games. Two things will not change: the areas tested will relate to real world problems, and the beginner division will be for true beginners. Make no mistake about it—this is your chance to learn Windows PowerShell; to quote the title of my five-part webcast, “Learn it now—before it is an emergency!”

Creating random numbers

One of my favorite cmdlets is the Get-Random cmdlet; there are just so many times that I need to have a random number. Now I want to combine two things—letters and numbers. By using a trick from my recent blog, Use PowerShell and ASCII to Create Folders with Letters, I can create random letters.

There are two main ways that I use the Get-Random cmdlet. The first is to call the cmdlet and to let things fly. This is the default way of using the cmdlet, and it can be helpful in certain circumstances. For me, however, I generally need to provide some limits on the numbers that are returned by the Get-Random cmdlet. In these cases, I use the Minimum and the Maximum parameters to specify the range of numbers that are available to select. These two methods of utilizing the Get-Random cmdlet are shown here with the associated output from those two commands.

PS C:\> Get-Random

465457929

PS C:\> Get-Random -Minimum 1 -Maximum 10

3

When I was choosing the daily prize winners during the 2011 Scripting Games, I needed to have more than one random number selected, and I needed to specify the range of input. This is when I started experimenting with the InputObject parameter for the cmdlet. This second parameter set for the cmdlet combines a Count parameter with the InputObject. The InputObject parameter accepts an array of objects (and integers are objects) for input. Sweet! I now get to combine one of my favorite cmdlets with one of my favorite Windows PowerShell tricks (the range operator). This means that I can select three random numbers from an array of numbers that range from 1 to 100. The command to choose three random numbers from the numbers ranging from 1 to 100 is shown here.

Get-Random -InputObject (1..100) -Count 3

The big trick in the previous command is to use the parentheses to force the creation of the array prior to the selection of the three random numbers. The command that chooses three random numbers along with the associated output is shown in the image that follows.

Image of command output

Combining random numbers and ASCII values

I want to be able to select random two letter combinations (it could be 1 or 100 random letters; it really does not matter). To do this, I want to use the way cool Get-Random cmdlet. The secret? Use the ASCII character values. In the previously mentioned blog, I needed to be able to increment letter values so I could add letters to automatically created folders, and I pointed out how to use the ASCII character values (numbers) and convert them to letters by using the [char] type accelerator.

Instead of incrementing numbers in a certain range, I can just as easily randomly select the numbers. The ASCII values in the range of 65–90 are the capital letters A–Z. ASCII values 97–122 are the lower case letters a–z. To choose two random letters that will translate to ASCII capital letters in the range A–Z, I use the Get-Random cmdlet, specify a Count of 2, and provide a range operator to the InputObject parameter. The code to accomplish this is shown here, along with the associated output.

PS C:\> Get-Random -Count 2 -InputObject (65..90)

80

89

To convert the two randomly selected numbers to letters, I use the Foreach-Object cmdlet, and inside the script block, I use the [char] class to make the conversion. This command is shown here (I use the % alias for the Foreach-Object cmdlet).

Get-Random -Count 2 -InputObject (65..90) | % {[char]$_}

The preceding commands, along the output associated with those commands are shown in the image that follows.

Image of command output

Use Begin, Process, and End to collect and display

So I am half-way there. I can get random letters, but the letters are coming one at a time…and I need to create random letter combinations of varying lengths. To do this, I am going to use the Begin, Process, and End parameters of the Foreach-Object cmdlet. I create a variable ($aa) and set its initial value to $null. I create and initialize the $aa variable in the Begin block, and the Begin block runs once at the beginning of the command. I now add the code that uses [char] to convert the random numbers into ASCII letters. In addition, I use the += operator to store each letter back to the $aa variable.

I place this code in the Process block where it will operate once for each item that comes across the pipeline (in this example, it runs twice because I am only choosing to generate two random numbers). If I left the code with only a Begin and a Process parameter, I would need to manually retrieve the value of the $aa variable. Here is the code as it currently stands:

Get-Random -Count 2 -InputObject (65..90) | % -begin {$aa=$null} -process {$aa += [char]$_}

I do not want to manually retrieve the value of $aa. Instead, I want to automatically display the value that is contained in the variable. To do this, I add the End parameter. Inside the script block that is associated with the End parameter, I display the contents of the $aa variable. Here is the revised code with the added End parameter:

Get-Random -Count 2 -InputObject (65..90) | % -begin {$aa=$null} -process {$aa += [char]$_} -end {$aa}

WooHoo! This is cool. I can add this code, and use it to create a sort of guess-the-letter game. I already wrote the engine to do this when I wrote the Windows PowerShell cmdlet quiz.

The command that chooses two random numbers converts the numbers to their ASCII value and displays the results that are shown in the image that follows.

Image of command output

That is about all there is to choosing a couple of random numbers and using their ASCII value to convert them to letters. Join me tomorrow for more cool stuff using Windows PowerShell. It will be fun.

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

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Ed,

    a short but intuitive example of how to use a begin-process-end block in a foreach-statement!

    there are other alternatives of course to produce a concatenated output, like

    Get-Random -Count 2 -InputObject (65..90) | % {Write-Host -NoNewline $([char]$_)}

    or

    (Get-Random -Count 2 -InputObject (65..90) | % {[char]$_}) -join ''

    but these are not that interesting like using the process block inside the foreach statement!

    Klaus (Schulte)