Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly select command to execute?

Idea: I want to change the time randomly using set-date's three options, .AddHours(), .AddMinutes(), .AddSeconds(). My first thought was storing them in an array and referencing them randomly but it's not executing. It's just storing the string printing instead of executing it.

Code so far:

$test = "Set-Date -Date (Get-Date).AddHours($\(Get-Random -Maximum 25))", "Set-Date -Date (Get-Date).AddSeconds($\(Get-Random -Maximum 61))", "Set-Date -Date (Get-Date).AddMinutes($\(Get-Random -Maximum 61))"

Output:

$Test 
Set-Date -Date (Get-Date).AddHours(22)
Set-Date -Date (Get-Date).AddSeconds($\(Get-Random -Maximum 61))
Set-Date -Date (Get-Date).AddMinutes($\(Get-Random -Maximum 61))
$test[0]
Set-Date -Date (Get-Date).AddHours(22)
$(Get-Random -InputObject $test) 
Set-Date -Date (Get-Date).AddMinutes($\(Get-Random -Maximum 61))

If there is another way to do this, if you need further explanation, or if there are any other questions, feel free to ask :) THANK YOU!

like image 429
Simonhawk Avatar asked Sep 14 '25 20:09

Simonhawk


1 Answers

  • Use script blocks ({ ... }) to store arbitrary commands in variables. Invoke script blocks on demand with &, the call operator.

  • A few asides:

    • Don't use \ as the escape character - PowerShell expects ` instead.

    • To execute full commands stored in strings, you need Invoke-Expression; however, Invoke-Expression is rarely the right tool, and is a security risk - avoid it whenever possible.

  • $(...), the subexpression operator is only needed (a) inside expandable strings ("...") and generally to enclose multiple statements; outside of an expandable string, as part of an expression, you do not need it for single commands such as Get-Random -Maximum 25 - enclosing the command in (...)` is enough.

  • &, the call operator, executes a command name/path stored in a string, not a whole command line (a command plus arguments). It is also used to invoke script blocks.

Note: I've replaced Set-Date with Get-Date in the commands below so that experimenting with them doesn't cause side effects.

# Store the commands in an array of script blocks.
$test = { Get-Date -Date (Get-Date).AddHours((Get-Random -Maximum 25)) }, 
        { Get-Date -Date (Get-Date).AddSeconds((Get-Random -Maximum 61)) }, 
        { Get-Date -Date (Get-Date).AddMinutes((Get-Random -Maximum 61)) }

# Select a random command and execute it using &
& (Get-Random $test)  

Performance note: For better performance, the array of input objects to randomly select an element from, $test, is passed as a direct argument here (implicitly binds to the -InputObject parameter) rather than via the pipeline ($test | Get-Random). For small arrays, the difference will be negligible, but with larger ones it matters. Do note, however, that cmdlets often do not accept arrays as a whole as arguments, in which case the pipeline must be used - see GitHub issue #4242.

like image 118
mklement0 Avatar answered Sep 16 '25 23:09

mklement0