Saturday, May 13, 2017

Self-referencing formula in PowerShell

A formula in PowerShell can have a reference to another part of the same formula.

I saw a script that calculated a start time at the next quarter hour from the current time. The code used was cumbersome, so I naturally felt challenged to do better.

My first attempt was to do this. We get the current datetime with the seconds and milliseconds chopped off. (Normally I always use full parameter names, but I may make an exception here to declutter the code. I haven’t decided yet.) Then we add 15 minutes minus the current minutes modulus (remainder) 15.

$Date = Get-Date -S 0 -Mil 0
$Start = $Date.AddMinutes( 15 - $Date.Minute % 15 )

Not bad. But can we do it in one line? And not just a one-liner for the sake of a one-liner. That would be stupid and useless. We’re not willing to sacrifice readability here. Clarity is important. Can we do it elegantly in on line? Yes. we can.

One way is to use a pipeline to first create the date, which we can then reference twice in the ForEach scriptblock.

$Start = Get-Date -S 0 -Mil 0 | ForEach { $_.AddMinutes( 15 - $_.Minute % 15 ) }

Not a bad solution, but I like to avoid pipelines when they aren’t strictly necessary, and creating a pipeline to handle a single object instead of a collection would seem to fit the definition of an unnecessary pipeline.

There is another way.

If the setting of a variable is wrapped in parenthesis, the value of the variable is set, and then the value is returned.

This just sets the $Date.

$Date = Get-Date -S 0 -Mil 0

But this sets the $Date and returns the new value of $Date.

$Date = Get-Date -S 0 -Mil 0 )

So now we can do things to the returned value, and reference the value of $Date in the process. Like this:

$Start = ( $Date = Get-Date -S 0 -Mil 0 ).AddMinutes( 15 - $Date.Minute % 15 )

No comments:

Post a Comment