Use Parameter Sets to Simplify PowerShell Commands

Use Parameter Sets to Simplify PowerShell Commands

  • Comments 6
  • Likes

Summary: In this article, Microsoft Scripting Guy Ed Wilson talks about using parameter sets to simplify Windows PowerShell commands.

 

Microsoft Scripting Guy Ed Wilson here. I had a great time the other night talking to Windows PowerShell MVP Shane Hoey before my presentation to the PowerShell Users Group of Australia (PSUGAU). After we had chatted for about a half an hour or so, it was time to get ready for my presentation to the group. I had not seen Shane since the MVP summit in Seattle, and I needed to thank him in person (virtually) for the Tim Tams he had sent to the Scripting Wife and me via The Molk at TechEd. In addition, we chatted a bit about Windows PowerShell MVP Sean Kearney  and the Dr. Scripto TV efforts.  As much as I hated to do so, I also informed him that it looks like the Scripting Wife and I will not be able to make it to TechEd 2011 in Australia and in New Zealand this year. I am really hoping to make it for 2012.

All of my community events (such as talking to various users groups) are listed on the Scripting Community page of the TechNet Script Center. I keep that pretty well up to date, so you can always see where I will be speaking and plan accordingly.

Anyway, after I rang off the Live Meeting, I got back to work on a module I needed for my desktop automation project. I came up with a pretty good Local User Management Module. The Local User Management Module is a Windows PowerShell module that contains a number of functions that enable, disable, create, delete, and modify users and groups. The following functions are contained in the module:

  • New-LocalGroup                         
  • New-LocalUser                     
  • Remove-LocalGroup                   
  • Remove-LocalUser                     
  • Set-LocalGroup                         
  • Set-LocalUser                 
  • Set-LocalUserPassword    
  • Test-IsAdministrator

Each function is complete with help and therefore to find out how to use New-LocalGroup, you would use one of the commands seen here.

Help New-LocalGroup

Help New-LocalGroup –full

Help New-LocalGroup –examples

Help New-LocalGroup -detailed 

The first command provides basic help. The full parameter causes all of the help information to display. The examples parameter causes help to return only example information. The difference between detailed and full is subtle---complete parameter information is returned when full is specified, but only partial parameter information is returned when using the detailed parameter. 

One thing I did, which I have not done before in a Hey, Scripting Guy! Blog post, is I created a couple of named parameter sets. By doing this, I was able to simplify my code. Let me explain.

In the Set-LocalGroup function, I wanted to be able to either add or remove a local user to a local group. I wanted to have both add and remove switches. Obviously I do not want to include both add and remove on the same command line. However, to be a valid command, either add or remove must be specified. If I tried to do manual command-line checking, it could be a bit complicated, but by using two parameter sets, it is easy. To create a parameter set, I use the [Parameter(ParameterSetName='somename')] syntax. Keep in mind that there are no spaces allowed between Parameter and (ParameterSetName …). Here is the parameter declaration for the function.

Param(

  [Parameter(Position=0,

      Mandatory=$True,

      ValueFromPipeline=$True)]

  [string]$userName,

  [Parameter(Position=1,

      Mandatory=$True,

      ValueFromPipeline=$True)]

  [string]$GroupName,

  [string]$computerName = $env:ComputerName,

  [Parameter(ParameterSetName='addUser')]

  [switch]$add,

  [Parameter(ParameterSetName='removeuser')]

  [switch]$remove

 )

If I attempt to call the Set-LocalGroup function without using either add or remove, an error appears that states that the parameter set cannot be resolved. The error is essentially stating that Windows PowerShell cannot tell how to call the command. The command and associated error are shown here: 

PS C:\Windows\system32> Set-LocalGroup -userName test -GroupName testgroup

Set-LocalGroup : Parameter set cannot be resolved using the specified named parameters.

At line:1 char:15

+ Set-LocalGroup <<<<  -userName test -GroupName testgroup

    + CategoryInfo          : InvalidArgument: (:) [Set-LocalGroup], ParameterBindingException

    + FullyQualifiedErrorId : AmbiguousParameterSet,Set-LocalGroup


If I supply both, add and remove at the same time, Windows PowerShell will generate the same error. The command and associated error are shown here:

PS C:\Windows\system32> Set-LocalGroup -userName test -GroupName testgroup -add -remove

Set-LocalGroup : Parameter set cannot be resolved using the specified named parameters.

At line:1 char:15

+ Set-LocalGroup <<<<  -userName test -GroupName testgroup -add -remove

    + CategoryInfo          : InvalidArgument: (:) [Set-LocalGroup], ParameterBindingException

    + FullyQualifiedErrorId : AmbiguousParameterSet,Set-LocalGroup

A similar but more complicated scenario occurs in the Set-LocalUser function. In addition to having an enable and a disable parameter, I also have a password parameter that is only needed if I also use the enable parameter. The scenario is similar to the one I had with Set-LocalGroup, except that one of the command will also appear with an additional parameter. Once again I chose to resolve the situation by using the [Parameter(ParameterSetName='somename')] syntax. The difference is that two of the parameters use the same parameter set name because they will be used together. The complete param declaration appears here:

Param(

  [Parameter(Position=0,

      Mandatory=$True,

      ValueFromPipeline=$True)]

  [string]$userName,

  [Parameter(Position=1,

      Mandatory=$True,

      ValueFromPipeline=$True,

      ParameterSetName='EnableUser')]

  [string]$password,

  [Parameter(ParameterSetName='EnableUser')]

  [switch]$enable,

  [Parameter(ParameterSetName='DisableUser')]

  [switch]$disable,

  [string]$computerName = $env:ComputerName,

  [string]$description = "modified via powershell"

 )

I uploaded the complete module to the Scripting Guys Script Repository. You can download it from the Local User Management Module page.

 

Join me tomorrow when I will go over using the Local User Management Module. In the meantime, if you have questions about how to use modules, check out these Hey, Scripting Guy! Blog posts that deal with modules.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • It would be great to have -Credential parameter for Local User Management Module. It can be implemented using System.DirectoryServices.AccountManagement.

  • Nice article Ed.

  • Dear Ed,

    it's great to know more about parameters and the use of parametersets!

    The idea behind parametersets looks like the concept of overloading functions in high

    level programming languages like Java, C++, C#, VB.Net e.g. which is not implemented

    in powershell :-(

    More or less this concept seems to be introduced to resolve parameter set ambiguities

    but sometimes it is not straight forward, at least in my opinion.

    Klaus.

  • Thanks for this post. At last. A proper, clear explanation with perfect examples.

  • Great article as usual Ed.  I've posted an article on how to make sure using your parameter set parameters are still compatible with PowerShell v2.0, as if you try and access them directly you may get a "The variable ‘$[VariableName]’ cannot be retrieved because it has not been set." error, which doesn't happen in PowerShell v3.0: blog.danskingdom.com/always-explicitly-set-your-parameter-set-variables-for-powershell-v2-0-compatibility

  • Good stuff. Trying to get a grip on defining parameters