Tag Archives: functions

Updated PowerShell Formatting Functions

Last year I posted an article and a set of PowerShell functions to make it easier to format values. For some reason, I decided to revisit the functions and ended up revising and extending them. I modified Format-Value so that you can format a number as a currency or a number.

Format-Value help (Image Credit: Jeff Hicks)

The function is assuming you will pipe values to it.

Format-Value examples (Image Credit: Jeff Hicks)

I also wrote a new function called Format-String.

Format-String help (Image Credit: Jeff Hicks)

The nice thing is that you can apply as many or all of the formatting transformations as you want.

Format-String examples (Image Credit: Jeff Hicks)

The Replace option works by taking a hashtable and replacing each matching key with its value.

Using the Replace parameter in Format-String (Image Credit: Jeff Hicks)

One task that comes to mind where Format-String might come in handy is in building passwords.

The function contains the following aliases:

  • fp = Format-Percent
  • fv = Format-Value
  • fs = Format-String

I’m also trying something different, at least for me. Instead of posting the code here, I’ve started to use GitHub since that seems to be what all the cool kids are doing. You can find the FormatFunctions module at https://github.com/jdhitsolutions/FormatFunctions. This should also make it easier for me to post revisions, address bugs and make it easier for you to take my code and run with it. You’re still welcome to post comments here, but use GitHub for anything specific to the PowerShell code.



Teeing Up to the Clipboard

Because I spend a great part of my day creating PowerShell related content, I often need to copy command output from a PowerShell session. The quick and dirty solution is to pipe my expression to the Clip.exe command line utility.

This works in both the console and PowerShell ISE. But there are situations where I’d like to see the result so that I know it is worth pasting into whatever I’m working on. In other words I want to send the results of the command to the pipeline and the clipboard at the same time. PowerShell can already do something similar with the Tee-Object cmdlet. With that cmdlet you can tee output to a variable or a file. So I decided to build a wrapper around Tee-Object and add functionality to send tee output to the clipboard.

I created a copy of Tee-Object and started modifying. I didn’t want to reverse-engineer the cmdlet. I simply wanted to add a new parameter. In some ways, my new command is like a proxy function.

I use Tee-MyObject much the same way as Tee-Object, even with the same parameters. Those are splatted through $PSBoundParameters. There are a few items I want to point out, more as a matter of scripting technique than anything.

First, because my function is wrapping around Tee-Object, which typically has input piped to it, I needed to temporarily store piped in objects to my function. That’s why I initialize a variable, $data and add each input object to it. After everything has been piped to my function, I can pass the data to Tee-Object, assuming I’m using one of its parameters.

However, because I am running Tee-Object inside of a function, scope becomes an issue. When I use the –Variable parameter, Tee-Object creates the variable with no problem. But when the function ends, the variable is destroyed. My solution is to create a new copy of the variable and specify the parent scope.

I needed this “tricks” in order to pass on full functionality between my wrapper function and Tee-Object.

For the clipboard part, I originally used code to simply pipe data to Clip.exe. However, this can temporary flash a console window and depending on the command I also end up with lots of extra white space at the end of each line. So I decided to use the .NET framework to add content to the clipboard. The tricky part was converting the output to text and cleaning it up. I ended up using the Trim() method to remove leading and trailing spaces after piping the data to Out-String. This leaves me with one long string. To clean up the extra space at the end of some lines, I use the –Replace operator to find anything that matches a bunch of spaces followed by the new line marker and replace it with just the new line marker. This has the effect of trimming away all those spaces.

And that’s it! My version even has a modified copy of the help for Tee-Object.

Modified help

I can use my command in place of Tee-Object. I even defined my own alias.

Using Tee-MyObject

To be clear, I have not modified, overwritten or removed Tee-Object. I have simply created a new version of the command with some additional functionality. If you have any questions on my process or some scripting element, please post a comment.


PowerShell Blogging Week: Supporting WhatIf and Confirm

We hope you are enjoying this experiment in community blogging. In today’s contribution I want to demonstrate how you can add support for WhatIf and Confirm to your advanced PowerShell functions. It is actually quite easy, especially if your function is simply calling other PowerShell commands that already support –Whatif and –Confirm. The recommended best practice is that if your function will do anything that changes something, it should support these parameters. Here’s how.

In your function you will need to use the cmdletbinding attribute and specify SupportsShouldProcess.

Beginning with PowerShell 3.0 this is all you need but you will see scripters explicitly setting this to $True.

That’s fine, although personally I find it redundant. If SupportsShouldProcess is listed then by default it is True. There is no need to explicitly set this to $False. Simply omit it. When you add this attribute, you will automatically get the –WhatIf and –Confirm parameters. The best part is that if your function is simply calling PowerShell cmdlets that already support –WhatIf, they will automatically inherit this setting. Here’s a sample function.

The function deletes all files from the %TEMP% folder that have a last modified time older than the last boot up time. As you can see in the help, PowerShell added the necessary parameters.

When I run the function with –Whatif it is passed on to Remove-Item.

It is really that easy. I also automatically get support for –Confirm.

Things gets a little trickier when you want to support WhatIf for a function where your commands don’t natively recognize SupportsShouldProcess. This would be true of any .NET static method or even a command line tool you might be running, to name a few examples. To add your own support you need to invoke the built-in $PSCmdlet object and its ShouldProcess() method. Here’s a simple example.

This function hypothetically is going to perform some action on a folder and I’m simply displaying the folder name in upper case. The important part is the If statement. This is the bare minimum that you need. If you specify –WhatIf you’ll be prompted.

The operation will be the name of your script or function. The target is the ShouldProcess parameter value which in my example is the path. But you can provide more specific information by specifying ShouldProcess parameters for the target and action. Here’s a revised function.

You must have the code for ShouldProcess otherwise even if you set the cmdletbinding attribute, PowerShell won’t know which commands need WhatIf. You can also have as many ShouldProcess statements as you need.

When it comes to confirmation, things get a little trickier and it might depend on what you really need. As you saw above, any cmdlet that supports –Confirm should automatically inherit the setting. This works because there is another cmdletbinding attribute called ConfirmImpact which has a default value of Medium. Other options are Low and High. My first function could also have been written like this:

Confirmation happens by comparing the value of ConfirmImpact with the built-in $ConfirmPreference variable which has a default value of High. If the value of $ConfirmPreference is equal to or greater than ConfirmImpact, PowerShell will prompt for confirmation. Let’s test this out.

Notice that I am also using for WhatIf. In this function the ConfirmImpact is set to high which means PowerShell will always prompt.

If I edit the function and change to ConfirmImpact to Medium or Low, then PowerShell will only confirm if I ask.

You don’t have to specify anything for cmdletbinding. If you know you always want confirmation you can do something like this:

Notice the use of the ShouldContinue method. When I run this function, PowerShell will always prompt for confirmation.

I also added a switch parameter called Force so that if it is specified, the user is not prompted for confirmation.

The downside to this approach is that help doesn’t show anything.

Perhaps in special cases this is what you want. Personally, I think you are better off using the cmdletbinding attributes as I did for my Set-Folder6 example.

Adding support for WhatIf and Confirm doesn’t take much effort and it will take your advanced function to the next level.

This post is part of the PowerShell Blogging Week series on Windows PowerShell Advanced Functions, a series of coordinated posts designed to provide a comprehensive view of a particular topic.

Other articles in this series:

We hope you found our work worth your time.