Friday Fun PowerShell Valentines Day

With Valentine’s Day just around the corner, I thought I should help you out with your gift giving. Remember those bags of candy with the cute sayings like “Be Mine”? Here’s how you can create a “bag” of them using Windows PowerShell; perfect for that extra geeky significant other. Or maybe you’ll just have fun playing with this.

The first part of the script changes the console title. Nothing extra special there, in terms of PowerShell. Next, I’m defining an array of strings that will be “printed” on the “candy”. I’m also defining an array of colors that you can use with Write-Host. Some colors like Gray hardly seem romantic so I’m limiting my array to the “pretty” colors. Finally, the script prompts you for the number of candies to create.

The main part of the script is a Foreach-Object expression. I’m using the range operator (..) as a counter. Each number is piped to ForEach, but I’m not doing anything with it. What I am doing though is using other cmdlet parameters that you may not be used to seeing. Most of the time when we use ForEach-Object, the scriptblock is the -Process parameter value, which runs once for every object piped in. But in my script I’m also using the -Begin parameter. This scriptblockk executes once before any pipelined objects are processed. In my script I’m simply clearing the screen. In the process script block I’m using Write-Host to write a random string from the $Print array using a random foreground color from the $color array. I’m also using -NoNewLine because I want to fill the screen, (or bag in keeping with my analogy). If I didn’t, I’d get a list. But because I’m not writing a new line, when I’ve reached the maximum number of candies, the -End scriptblock runs which simply adds the necessary return.

Download Valentines.ps1

Happy Valentine’s Day.

ForEach or ForEach-Object

I came across a post the other day that explained differences when using the ForEach enumerator and the ForEach-Object cmdlet. They both essentially do the same thing but as the post mentions there are potential performance differences. One other difference I want to highlight is that the ForEach enumerator doesn’t write to the pipeline at the end.

By that, I mean a command like this will fail:

[cc lang=”DOS”]
PS C:\> foreach ($i in (1..10)) {$i*2} | out-file $env:temp\data.txt
An empty pipe element is not allowed.
At line:1 char:33
+ foreach ($i in (1..10)) {$i*2} | <<<< $env:temp\out-file data.txt + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : EmptyPipeElement [/cc] Of course there are workarounds but you have to apply them to every pipelined object in the {}. Compare that to using ForEach-Object. [cc lang="DOS"] PS C:\> 1..10 | foreach-object {$_*2} | out-file $env:temp\data.txt
[/cc]

With the enumerator you get to name your own variable. With ForEach-Object you use the $_ placeholder. Personally, I think of the ForEach enumerator as a legacy construct from the VBScript days. That’s not to say you should never use it, but you need to look at the bigger picture of what you are attempting to accomplish and make sure you are doing it the “PowerShell” way.

The PowerShell Day Care: Building ScriptBlocks

Good morning kids and welcome to the PowerShell Day Care center. We offer a creative and nurturing environment for PowerShell professionals of all ages. Later there might even be juice and cookies. But first let’s get out our blocks, our scriptblocks, and start building. I’ve written a number of posts on script blocks and today have a script to offer, that even if you don’t need it as is, it might offer a few insights into PowerShell. Continue reading