Friday Fun Learning from Spam

Today’s article is definitely on the amusing side, although hopefully it will make for an interesting learning opportunity. Earlier this week I was clearing out spam on my blog and found a comment that looked like the spammer’s template file. The comment contained a number of short entries like this:

Sample spam templateSample spam template (Image Credit: Jeff Hicks)

The poor English aside, I thought it was kind of funny. First off, it is clear that whatever code he (making an assumption, sorry) was using failed to properly run. Then I thought that I could use this text and do the same thing in PowerShell. It is pretty clear to me that to create a proper spam comment, I need to select a choice from each option enclosed in curly braces. So let’s do that. Let’s build some spam with PowerShell. I’ll use the text file from above.

The trickiest part, at least for me, was coming up with a regular expression pattern to select everything in the curly braces. Eventually I came up with this:

To start with, I’ll test with a single line of text.

Which gives me these matches:

My spam matches
My spam matches (Image Credit: Jeff Hicks)

I’ll focus on the first match. I don’t need the {} characters so I can replace them with empty strings and then split what remains on the | character.

This gives me an array of choices which I can select with Get-Random.

With this, I can use the replace method to replace the matching value that is, the text with the curly braces, with my randomly selected choice.

Inserting the replacementInserting the replacement (Image Credit: Jeff Hicks)

I can repeat this process for the other values. Here’s how I might do this for a single line:

The complete line
The complete line (Image Credit: Jeff Hicks)

I never promised elegant poetry.

Now that I have the technique, I can apply it to the entire file looping through each line.

And here is the glorious, delicious spammy result:

PowerShell generated spam!PowerShell generated spam! (Image Credit: Jeff Hicks)

Yes, this is absolutely silly and borderline ridiculous. But this serves as a nice tool for learning about regular expressions, replacements and splitting. If you want some spam samples to play with you can download a zip file here.

Have a great weekend.

Friday Fun: Holiday Shopping with PowerShell

Once again, the holiday shopping season is upon us. But perhaps PowerShell can make it a little easier or at least a bit more fun. I’m sure many of you have shopped at Perhaps you plan to do so again this year for friends, family or even yourself. So why not let PowerShell make this a bit easier.

NewEgg is savvy enough to publish RSS feeds for a number of their sales categories. You can find a master list at  Let’s take their Deal of the Day feed.

Using Invoke-RestMethod, it is very easy to retrieve items.

But it is still a bit of a jumble, so let’s get a bit more selective.

I also created a new property called Published which takes the original PubDate and treats it as a date which makes the data easier to sort or filter.

Here’s a sample of what I retrieved.

A NewEgg Deal of Day itemA NewEgg Deal of Day item (Image Credit: Jeff Hicks)

With this data, I can use Out-Gridview as an object-picker.

Links in Out-GridviewLinks in Out-Gridview (Image Credit: Jeff Hicks)

I can select multiple entries, click OK and each link should open up in my browser.

The online dealThe online deal (Image Credit: Jeff Hicks)

But let’s make things a bit more interesting. The Title property includes the price and description. I have no idea what these links look like in other parts of the world so you may have to adjust the following examples.

First, I’m going to define a regular expression pattern to use named captures to get the currency, in my case $, the price and the item description.

I’m going to re-download the data skipping any entry that doesn’t have what looks like a price in the title field.

My goal is to use Out-Gridview again with separate properties for the currency and price. I need the price to be numeric so that I can sort on it. I next get the currency symbol using the regex expression.

Then I can process the rest of the RSS data, using the regex object to parse out the price and description.

If you notice, I used the Currency value as a property name. Now when I use Out-Gridview I have a more flexible display.

Reformatted DealsReformatted Deals (Image Credit: Jeff Hicks)

If I’m shopping for a new laptop, I can select multiple entries, click OK and review them in my browser.

Viewing my choicesViewing my choices (Image Credit: Jeff Hicks)

I can repeat the process by changing the RSS feed, say to their Shell Shocker

If I repeat the previous steps, this will fail, which brings up something to keep in mind with regular expressions: know your data. You have to know what you are processing and that it follows a predictable pattern. At least if you want to keep your regular expression patterns relatively simple. The problem here is that there is only a single item. So my code to get the currency figure fails, because I don’t have an array. In this situation I could do this:

Although it might make more sense to come up with code that I can re-use.

But from here the code is the same.

Shell Shocker itemShell Shocker item (Image Credit: Jeff Hicks)

That might be something I want to look into, although sometimes the RSS feeds are bit behind the site. Sadly, in this case, the link works, but the product is something else. But you get the idea.

Enjoy your holiday weekend and be careful out there!

PowerShell Friday Fun: Capture the Command

This week’s Friday Fun actually has a purpose, at least for me. But I always hope you’ll pick up a tip or two that you can use in your own PowerShell work.

Because I write a lot about PowerShell, I am constantly copying pasting between my PowerShell session and usually Microsoft Word. Although the same is true when I am writing help examples for my functions. I can save command output to the clipboard with this trick:

But I never know if the command was successful until I paste and then I need to copy the command again. Over the years I’ve come up with a number of tools to make this process easier but now I think I finally have it.

My new command is called Out-Copy. It is designed to accept any PowerShell command. The function will essentially pass the results back to the pipeline, so it is like Tee-Object in that respect. It also sends a copy of the output to the clipboard. But wait there’s more! The clipboard output will include the prompt and the command you ran.

At a PowerShell prompt I can run something like this:

Using Out-CopyUsing Out-Copy (Image Credit: Jeff Hicks)

And I can then paste into another application

Pasted resultsPasted results (Image Credit: Jeff Hicks)

I also included a parameter to only copy the command to the clipboard. This command runs as expected:

Copying command onlyCopying command only (Image Credit: Jeff Hicks)

With this result:

Command only resultCommand only result (Image Credit: Jeff Hicks)

This version of my function will only copy what is sent to the success pipeline. It will not capture anything from the other streams such as Verbose, Warning or Error. Normally I do screen shots of that anyway. But this might be something I’ll look into later.

Here’s the complete function which includes an alias.

The only other parameter is Width. I have given this a default value of 80 which works best when pasting into a Word or text document. You can adjust this, typically up to the width of your PowerShell host. Anything beyond will be truncated.

I spent a few hours polishing this up, but it will save me time and frustration from here on out and maybe you will need to use it to. Plus it puts a smile on my face when I use it because I feel like I’m performing magic.


Friday Fun: Tickle Me PowerShell!

I work at home for myself which means I have to act as my own assistant, reminding me of important events and tasks. And sometimes I need a little help. So why not use PowerShell? In the past I’ve used and written about using a background job to wait until a certain number of minutes have passed and then display a popup message using the MSG.EXE command line utility. The drawback to my previous approach is that if I close my PowerShell session I lose the background job. For reminders in the next 10-30 minutes perhaps that’s ok. But for longer term reminders, I need a better solution.

I don’t know why I didn’t go this route from the beginning, but I can accomplish the same result using a PowerShell scheduled job. A PowerShell scheduled job runs via the task scheduler which means it persists outside of PowerShell. All I really need are three things:

  1. The time to kick off the task
  2. The command to run
  3. A registered scheduled job object

The time to kick off is the Job Trigger. Here’s how I can create a trigger for 30 minutes from now. My reminder only needs to run once.

The command will be the MSG.EXE command.

This needs to be in the form of a script block.

In my scriptblock I’m also going to delete the scheduled job. Finally I need to register it.

When the time arrives I get a popup message on my screen.

sample popup reminder
sample popup reminder

You can configure how long the message will be displayed before it is automatically dismissed. That’s the essential part of the process. Here is the complete script to define the function, including an optional alias.

Now I can easily set reminders for myself, even something tomorrow, next week or next month. I can use the scheduled job cmdlets to manage my reminders. I wrote this with the assumption that you are setting popup reminders for yourself.

Let me know what you think.

Friday Fun: A Better PSEdit

In the PowerShell ISE, there is a built-in function called PSEdit. You can use this function to easily load a file in to the ISE directly from the ISE command prompt.

You can also load multiple files, but not as easily as you might like. I find myself wanting to do this:

As you can see isn’t what I’m expecting. I can get PSEdit to open multiple files, but I need to use a command like this:

I finally tired of this so I looked at the code for the PSEdit function.

I am assuming based on what I see that this was written a long time ago. So I decided to update it. Here’s my version:

The major difference is that my version works in the pipeline making it easier, for me at least, to open multiple files at once.

I also added some verbose messages for troubleshooting. This is my common practice when creating new PowerShell tools. You’ll also notice that I replaced the aliases in the original function with complete cmdlet and parameter names.

The last “feature” is my customized ValidateScript attribute. I wanted to verify that any path pointed to a legitimate file. I could have simply used this:

But if the path failed the test, PowerShell displays a long error message that isn’t always helpful. So I added some logic. Validation tests have to return either True or False. When it is false, PowerShell throws the exception. So I wrote my own exception message.

I get a similar error with the original psedit.

So perhaps I haven’t improved on it that much. But I could have written an even longer message and I wanted to demonstrate this technique in case you wanted to use it.

One last word on my version of PSEdit. I didn’t use a standard name, I guess because the original function doesn’t use one. And I’m ok with that. This is one of the situations where the function is a “cheater” command with a simple, alias-like, name. If you want to replace the original PSEdit function, add mine to your ISE profile script and rename it to PSEdit.