Tag Archives: Scripting

Friday Fun: Improved PowerShell Napping

So I had some fun with my post last week on taking a nap with PowerShell. I got some great feedback on Twitter and a new comments on the blog. My initial effort was a relatively simple PowerShell script which certainly got the job done. But I there were a number of areas where I could expand and improve the script and they would be terrific teaching aids. So I did.

The function is defined in a script you can find in Github.

Let’s look at some of the changes I made. First off, I turned this into a function complete with comment based help. You’ll need to dot source the script file into your PowerShell session or profile script to make the command available.

I made just about every option a parameter and added a few parameter aliases as well. So even though I made the Minutes parameter positional so that you don’t need to use the parameter name, you could use –Nap or –Time. You’ll notice I also made the wakeup message a parameter.  Feel free to set your own default value. Otherwise, you can set a different message at different times.

I also realized that if you are napping, someone might still drop by your desk. So I included an option to display a progress bar using Write-Progress. This is a cmdlet that doesn’t get the love it should.

I defined an array of messages:

The messages will be used as the Status property for Write-Progress. I like using a hashtable of parameters to splat when using Write-Progress.

If I use the Progress bar, it is displayed using the seconds remaining.

And every 10 seconds I set the status to another randomly selected message. The result is something like this:

image

The last major change I made per a suggestion was to use the text to speech feature to have a Windows voice “say” the wake up message. I added a parameter for you to specify a voice name which in the US will most likely be David or Zira.  If you don’t know the names, you can specify a bogus value like ‘foo’ and the function will display the available names. This works because I added a validation script to the Voice parameter.

This is probably a bit more involved than most validation scripts.  The main takeaway is that if you use a validation script it has to return either True or False, or throw an exception as I’m doing here. But it works.

image

By adding a voice option I decided the function could either display the message using Write-Host or speak it. The chime happens in either event.

What this meant was that I had to differentiate the parameters which I did with parameter sets.  I specified the default in the cmdletbinding attribute.

Then I needed to specify a parameter set name for each parameter.  If you don’t specify parameter set name, then the parameter will belong to all sets.  Or you can do as I did and be explicit. If you do it properly it should be reflected in the help.

image

You can see that there are 2 ways to use this command. I’ll let you grab a copy and try out the new additions.

Certainly this isn’t a production oriented script but I hope it serves up some interesting examples of different scripting techniques and cmdlets.

As always, comments sincerely welcomed.

Enjoy!

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.

Testing PowerShell HashTables

So I’ve been watching the PowerShell Toolmaking Fundamentals course on Pluralsight authored by Adam Bertram.  You may be surprised that I watch other PowerShell related courses, but I always pick up something I didn’t know about, find a new teaching technique or something else that makes me say, “that was cool.” I have found a few of these in Adam’s course so far.

One of the tricks he demonstrated was using a hashtable as a parameter value for an advanced function that could then be splatted to Set-ADuser.  For the sake of what I want to demonstrate here’s my simplified version of such a function.

The function gets the specified user and then updates the user with hashtable of parameters from Set-ADUser.  If you know all the parameter names this works just fine.

image

I’ve easily updated the user account.

image

But what if I make a mistake with the hashtable of settings?

image

There is no parameter called FirstName for Set-ADUser. It should be GivenName. One thing you could do, and this is the point of this article,  is to  validate the hashtable keys against parameter names from Set-ADuser.

You can use Get-Command to list all of the parameter names.

image

What we need to do is make sure that all of the keys in the settings hashtable are in this list. Here’s a quick test.

image

I can use code like this to test if the keys from $s are also in $p:

image

Although I may be more interested in the cases where they don’t match.

This won’t give any results because nothing matches the filter. But if I modify the hashtable with a bogus entry it will.

image

With this concept in mind I can revise the function.

image

Certainly you could add other code to list the available parameters, suggest corrections or whatever. But now the function won’t attempt to run and gracefully handles bad keys.

Once corrected, the function works as expected.

image

And please don’t take any of this as an indication that Adam missed something in his course. Far from it.  No course can teach you absolutely everything you need to know to build effective PowerShell tools. You need to build what works for you and add error handling that you feel is appropriate. In this case I thought this would offer a nice learning opportunity for you to learn about hashtable keys and a few operators.