Friday Fun: Number Crunching

Earlier this week I was looking at the GoFundMe website in the midst of debating a new project. One of the considerations I have for sites like this is the expense involved. Certainly I don’t expect this type of service to be free. But I started wondering about what net donations might look like. According to GoFundMe, assuming I am interpreting this correctly, the site takes 5% of the donation right off the top. In addition to that there is a processing fee of 2.9% of the donation plus 30 cents. At least for the US. So for a $10 donation the net donation would be $8.91.

10 – (10*.05) – (10*.029 +.30)

Alright then.  This should be simple enough to turn into a PowerShell function.

This also should make for a fun learning opportunity.

The function takes a parameter for the donation amount. I cast it as a [double] in the event someone might donate $10.25. If used [int] PowerShell would turn it into $10.  I’ll come back to the other parameter in a bit.

I define the rates from GoFundMe as variables.  This makes it easier to calculate some values.

You’ll note that I’m using the Round() method of the .NET Math class. This is so that the result is formatted to 2 decimal points.  This is what I want to see, not necessarily how the site operates. With these values I can create a custom object.

Here’s a simple demonstration, and yes I know I’m not using a standard function name but this is for fun.

image

I also wrote the function as an advanced function so that I can pipe values into it. If you look at the parameter definition for $Donation you’ll see that I have a setting for ValueFromPipeline.

image

This makes it pretty clear about what happens with each donation.  But what did I end up with?  My function writes objects to the pipeline so that I can use other cmdlets, like Measure-Object.

image

Here’s the fun part: I can measure multiple properties.

image

I thought that was pretty handy.

I know that the values are in dollars.  But let’s say I was creating a report and I wanted to make it pretty and include the $ sign, or whatever my currency symbol might be.

If you recall, I included a switch parameter called UseCurrency along with a parameter alias of currency.

If I run the function with –UseCurrency, then this parameter will have a value of $True. That is how a Switch parameter works. In my function I can test the parameter value and it it is true, then I’ll create the same custom object, except that I will use the –F operator to format the value as a string using the currency symbol.

This operator is used to format strings in the .NET Framework. You can read more about this online at http://go.microsoft.com/fwlink/?LinkID=166450. But in short, the {0} on the left side of the operator is a numbered place holder. The c is the modifier which in this case indicates to use a currency format string and I’m limiting it to 2 places.  I probably don’t need that since I’m already rounding but I left it in for the sake of education.  On the right side of the –f operator is a comma separated list of values that will “plug in” to the place holders. The net result is this:

image

That looks pretty, but be aware that these values are strings.

image

This means my previous method of getting a sum will fail.  Instead I need to use numbers and then format the result.

image

Now I have the best of everything. Although if I truly want to make a pretty report, I can use Format-Table so that I can specify an alignment on the custom property.

image

I hope you found this fun and informative.  If you have any questions about what I did or why, please drop them in the comments.

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 NewEgg.com. 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 http://www.newegg.com/RSS/Index.aspx.  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.

Enjoy!

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.