# --------------------------------------------------------------------------- ### param([int]$count=1, [array]$inputObject=$null) BEGIN { if ($args -eq '-?') { @" Usage: Select-Random [[-Count] ] [-inputObject] (from pipeline) [-?] Parameters: -Count : The number of elements to select. -Collection : The collection from which to select a random element. -? : Display this usage information and exit Examples: PS> $arr = 1..5; Select-Random $arr PS> 1..10 | Select-Random -Count 2 "@ exit } elseif ($inputObject) { ### If you're accepting $args, you need to pass those in... # Write-Output $io | &($MyInvocation.InvocationName) $args; Write-Output $inputObject | &($MyInvocation.InvocationName) -Count $count break; } else { $seen = 0 $selected = new-object object[] $count $rand = new-object Random } } PROCESS { if($_) { $seen++ if($seen -lt $count) { $selected[$seen-1] = $_ } ## For each input element $n there is a $count/$n chance that it becomes part of the result. elseif($rand.NextDouble() -gt $count/$seen) { ## For the ones previously selected, there's a 1/$n chance of it being replaced $selected[$rand.Next(0,$count)] = $_ } } } END { if (-not $inputObject) { ## DO ONCE: (only on the re-invoke, not when using -inputObject) Write-Verbose "Selected $count of $seen elements" Write-Output $selected # foreach($el in $selected) { Write-Output $el } } }