The Surly Admin

Father, husband, IT Pro, cancer survivor

More Advanced Functions

Want to add some more functionality to our scripts and functions?  Want your scripts to operate like the standard Powershell cmdlet’s, with the same Common Parameters?  Well you can, and it’s not difficult at all.  Read on to add these abilities to your scripts!

What Are Common Parameters?

Any time you look at the help of a cmdlet you’ll almost always see at the end [<CommonParameters>].  Which is great, but if you don’t actually know what those are it’s a bit useless.  Luckily, Powershell help is pretty good and you can find very detailed information about what they are by typing:

Get-Help About_CommonParameters

The most important part of these, in my humble opinion of course, are the actual parameters available:

-Verbose
-Debug
-WarningAction
-WarningVariable
-ErrorAction
-ErrorVariable
-OutVariable
-OutBuffer

and

-WhatIf
-Confirm

Some of the most common ones you’ll use are -Verbose, -ErrorAction, -WhatIf and -Confirm.  What I want to talk about today is turning on the -WhatIf and -Confirm functionality.

ShouldProcess

The key to turning on Common Parameters is the [CmdletBinding()] statement.  You’ll often see scripts putting this statement on the first line to activate these advanced settings.  Both the -Whatif and -Confirm parameters use ShouldProcess, but we have to do one additional thing to [CmdletBinding()] so we can use those parameters.

[CmdletBinding(SupportsShouldProcess=$true)]

Now we can start using these parameters!

In Action

So let’s put it to the test and see what we get.  Here’s a very simple script that needs a UserName as a parameter and will set that user’s password to never expire.  TSA stands for The Surly Admin, of course!

[CmdletBinding(SupportsShouldProcess=$true)]
Param (
   [string]$User
)
Set-ADUser $User -PasswordNeverExpires $true

And when we run this script with the -WhatIf parameter, here’s what we see.

cmdletsample3

Nothing actually done, but we get the standard What If text with our custom information in it.  Notice how target is now our $User variable, and the standard action text actually comes first in the message.  But we can’t stop here, we have to see what running this with -Confirm looks like.

cmdletsample2

That’s all there is to it, Powershell will take care of everything for you.  But what if you want to generate you’re own messages?  That’s where ShouldProcess comes into play.  Here’s the code you can use.

$PSCmdlet.ShouldProcess(target,action)

We use the above in an If() statement to execute our code.  The statement will return a $true unless -WhatIf has been specified, in which case it will display our message–action being performed on target–and then move on.  If you have -Confirm specified it will show you the action to target and then prompt you if you want to actually perform the action.

[CmdletBinding(SupportsShouldProcess=$true)]
Param (
   [string]$User
)
If ($PSCmdlet.ShouldProcess($User,"Set password to never expire"))
{  Set-ADUser $User -PasswordNeverExpires $true
}

This works great in our -WhatIf scenario, as you can see.

cmdletsample1

But falls down a little when using it with -Confirm.

cmdletsample4

As you can see, we’re now getting prompted twice!  This is because -Confirm tells Powershell to ask for a confirmation anytime you want to use a cmdlet that changes the state of something, like a set* cmdlet.  So not only do you get prompted when use the PSCmdlet.ShouldProcess method you then get prompted when changing state.  No good solution for this that I’ve found, so if you know one please let me know!

One nice addition this is when you use the -Verbose parameter you will now get feedback from your cmdlet.

cmdletsample5And the feedback is using your custom text, which is really nice.  So I guess 2 out of 3 ain’t bad?!

Advertisements

February 11, 2013 - Posted by | PowerShell | , , ,

3 Comments »

  1. […] Before we can move direct reports we need a way to set them in the first place. You can always use ADUC, of course, but we need a way to do this quickly and easily. Especially for testing! Hence Set-SAADManager was born. This function takes user input from the pipeline–from multiple sources–and assigns these users to whatever manager you assign with the -NewManager parameter. I also wanted to give the function the same range of options that any cmdlet has, so that meant support -WhatIf, -Verbose and -Confirm.  This took advantage of the techniques I’ve built up here and here. […]

    Pingback by Setting the Manager Field in Active Directory « The Surly Admin | February 18, 2013 | Reply

  2. My best workaround for the “double confirm” is to pass a -Confirm:$false to the cmdlet itself in code. This keeps your custom confirm text, but if you confirm that it silently does the actual operation.

    So your example function would be like:

    [CmdletBinding(SupportsShouldProcess=$true)]
    Param (
    [string]$User
    )
    If ($PSCmdlet.ShouldProcess($User,”Set password to never expire”))
    { Set-ADUser $User -PasswordNeverExpires $true -Confirm:$false
    }

    Comment by Steve Bernard Jr | August 4, 2013 | Reply

  3. I had a similar problem, this, “-Confirm:$false” worked like a charm. Thanks Steve Bernard Jr.

    Comment by Andy | August 5, 2013 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: