Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.
If you own the book already, login here to get free, online, searchable access to the entire book's content.
If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".
You want to generate a random number or pick a random element from a set of objects.
Call the Get-Random
cmdlet to generate a random positive integer:
Get-Random
Use the -Minimum
and -Maximum
parameters to generate a number between Minimum
and up to (but not including) Maximum
:
Get-Random
-Minimum
1
-Maximum
21
Use simple pipeline input to pick a random element from a list:
PS > $suits = "Hearts","Clubs","Spades","Diamonds" PS > $faces = (2..10)+"A","J","Q","K" PS > $cards = foreach($suit in $suits) { foreach($face in $faces) { "$face of $suit" } } PS > $cards | Get-Random A of Spades PS > $cards | Get-Random 2 of Clubs
The Get-Random
cmdlet solves the problems usually associated with picking random numbers or random elements from a collection: scaling and seeding.
Most random number generators only generate numbers between 0 and 1. If you need a number from a different range, you have to go through a separate scaling step to map those numbers to the appropriate range. Although not terribly difficult, it’s a usability hurdle that requires more than trivial knowledge to do properly.
Ensuring that the random number generator picks good random numbers is a different problem entirely. Most general-purpose random number generators use a mathematical equation to generate their values. These are called pseudo-random number generators, or PRNGs. They make new values by incorporating the number they generated just before that—a feedback process that guarantees evenly distributed sequences of numbers. Maintaining this internal state is critical, as restarting from a specific point will always generate the same number, which is not very random at all!
To create their first value, these generators need a random number seed that they usually derive from the system time.
So unless you reuse the same random number generator, this last point usually leads to the downfall of realistically random numbers. When you generate them quickly, you create new random number generators that are likely to have the same seed. This tends to create runs of duplicate random numbers:
PS > 1..10 | ForEach-Object { (New-Object System.Random).Next(1, 21) } 20 7 7 15 15 11 11 18 18 18
The Get-Random
cmdlet saves you from this issue in two ways. Early versions of PowerShell’s Get-Random
cmdlet implemented a PRNG. The first way that it saved you from this issue was by internally maintaining a random number generator and its state to vastly improve randomness:
PS > 1..10 | ForEach-Object { Get-Random -Min 1 -Max 21 } 20 18 7 12 16 10 9 13 16 14
However, even as good as this pseudo-randomness was, administrators who didn’t realize it wasn’t truly random also used this cmdlet to generate passwords and other sensitive things. That is dangerous: if the only two things that went into the generation of a password were the time it was generated and the well-known formula that the random number generator used, that password isn’t very secure.
Despite that, assuming that you could use the Get-Random
cmdlet to generate random passwords is realistically an assumption that anybody should be allowed to make. So, the second way that PowerShell saves you from this issue is by using a cryptographic random number generator. Numbers that Get-Random
generates are suitable for use in passwords, cryptographic keys, and more.
For scenarios where you want reproducible results, you can use the -SetSeed
parameter of the Get-Random
cmdlet to supply a seed directly for testing purposes.
For more information about working with classes from the .NET Framework, see Recipe 3.8.
Recipe 3.8, “Work with .NET Objects”