Use a Simple PowerShell Technique to Create Random Numbers

Summary: Microsoft Scripting Guy, Ed Wilson, teaches you how to use a simple Windows PowerShell cmdlet to create random numbers.

Microsoft Scripting Guy, Ed Wilson, is here. One of the questions I received when I was speaking at the SQL Rally in Orlando, Florida was whether I prefer working in the Windows PowerShell console, or practise I prefer to use the Windows PowerShell ISE and write a script.

The answer, for me, is both. On whatsoever given mean solar day, I will start Windows PowerShell more than than a dozen times. How do I know this? Well, I employ Windows PowerShell to tell me. The following control queries the Windows PowerShell log for instances of effect 400 that have been generated since April 1, 2011. Effect 400 is generated each time Windows PowerShell starts upward.

To get the Windows PowerShell result log, I utilize the Become-EventLog Windows PowerShell cmdlet. Because I do non like typing, I use wild cards to specify the PowerShell log. The results of the query return every event in the event log. I pipe that to the Where-Object cmdlet to filter everything except the result ID 400 and dates after Apr 1, 2011. The Measure-Object cmdlet counts the number of events that make it through the filter.

Go-EventLog -LogName *power* |

Where-Object { $_.instanceID -eq 400 -AND $_.timewritten -gt "4/i/2011"} |

measure-object

The Windows PowerShell event 400 is generated when the Windows PowerShell engine transitions to running. An case of this event is shown here.

Image of event

Anyway, during the 2011 Scripting Games, I needed to generate 10 random numbers that began with the number 2 and were a maximum of 20. This tin can be accomplished by using the following command line:

1..x | % {Get-Random -Minimum 2 -Maximum 20 }

In the command, I create a range of numbers, one through 10. I pipe them to the Foreach-Object cmdlet (% is an alias). Within the Foreach-Object cmdlet, I procedure the Become-Random cmdlet and utilise the minimum of ii and the maximum of 20. The command and its associated output are shown hither:

PS C:\> 1..10 | % {Get-Random -Minimum 2 -Maximum twenty }

xviii

2

3

9

19

9

13

10

4

viii

18

ii

3

9

xix

9

13

ten

iv

8

The problem with this output is that there are duplicate numbers in the output. Ane matter that can be washed is to pipe the output to the Become-Unique cmdlet. The problem with this is that the output must be sorted. To sort the output, I tin can apply the Sort-Object cmdlet. The cool thing is that the Sort-Object cmdlet has a Unique parameter, which makes using Go-Unique redundant. The revised control is shown here:

PS C:\> 1..10 | % {Get-Random -Minimum ii -Maximum twenty } | Sort -Unique

3

5

6

x

12

sixteen

17

18

19

At present I have another problem. I exercise not have ten random numbers. I just take 9 because a duplicate number was removed from the output.

I might be able to squirrel effectually and figure something out, but at this point, I more often than not give up and write a script. I will re-create the commands from my command history into the Windows PowerShell ISE so I at least take something with which to begin working.

The showtime matter I did was create an empty hash table. I gave it the rather unimaginative name of $hash. Next I used a Exercise … While loop to allow me to loop through the random numbers. I used my lawmaking snippet tool to insert the Practice … While loop because I exercise not write Do … While loops all that often when writing Windows PowerShell code. The empty hash table, Do statement and opening curly bracket are shown here.

$Hash = @{}

Do

{

I used the aforementioned Get-Random command, simply this time I assign information technology to the $a variable. Because I desire a drove of random numbers that are unique, I needed a style to go a specific number of unique numbers. To do this, I add the number to both the key and the value of the hash table. This generates an error if the primal previously has been used (the non-unique random number example); and therefore, I utilise Endeavour / Take hold of. I am not interested in actually doing anything when I catch the fault, so I supply empty curly brackets. This portion of the script is shown here:

$a = Get-Random -Minimum ii -Maximum 20

Attempt { $hash.add together($a,$a) } Take hold of {}

Now I get rid of the number that is stored in the $a variable, and I add my while status. I will keep looping around while the count contained in the hash table is less than or equal to 9. This is because the status volition e'er exist one less than my desired number. The terminal thing I do is display the collection of keys from the hash tabular array, as shown here:

$a = $zero

} While ( $hash.count -le nine )

$hash.Keys

The complete Get-UniqueRandomNumbers.ps1 script appears here.

Get-UniqueRandomNumbers.ps1

$Hash = @{}

Do

{

$a = Go-Random -Minimum 2 -Maximum 20

Endeavour { $hash.add($a,$a) } Catch {}

$a = $naught

} While ( $hash.count -le nine )

$hash.Keys

Interestingly plenty, there is a count belongings that I can employ to specify a specific number of objects to return from a collection. By using this command set, I tin simplify my previous script down to a unmarried command. This one line command is shown hither:

PS C:\> Get-Random -Count ten -InputObject (2..20)

15

9

6

2

17

nineteen

10

18

xiv

iii

Well, that is about it. Every bit you can encounter, when I am working in the Windows PowerShell console, I oft migrate to the Windows PowerShell ISE, and so vice versa. There are two things I really like about the Windows PowerShell console—it loads actually fast, much faster than the Windows PowerShell ISE. And information technology allows me to page through my output. I can pipe a command to the more command, and the information is displayed ane page at a time. This is useful because the pager in the Windows PowerShell ISE command output window does non work.

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

Ed Wilson, Microsoft Scripting Guy