{"id":13471,"date":"2011-06-30T00:01:00","date_gmt":"2011-06-30T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/06\/30\/use-parameter-sets-to-simplify-powershell-commands\/"},"modified":"2011-06-30T00:01:00","modified_gmt":"2011-06-30T00:01:00","slug":"use-parameter-sets-to-simplify-powershell-commands","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-parameter-sets-to-simplify-powershell-commands\/","title":{"rendered":"Use Parameter Sets to Simplify PowerShell Commands"},"content":{"rendered":"<p><b>Summary<\/b>: In this article, Microsoft Scripting Guy Ed Wilson talks about using parameter sets to simplify Windows PowerShell commands.\n&nbsp;\nMicrosoft Scripting Guy Ed Wilson here. I had a great time the other night talking to Windows PowerShell MVP Shane Hoey before <a href=\"http:\/\/www.psugau.org\/events\">my presentation to the PowerShell Users Group of Australia (PSUGAU)<\/a>. 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 <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/05\/26\/use-powershell-to-data-mine-your-outlook-inbox.aspx\">Tim Tams he had sent to the Scripting Wife and&nbsp;me via The Molk<\/a> at TechEd. In addition, we chatted a bit about <a href=\"http:\/\/blogs.technet.com\/search\/searchresults.aspx?q=sean%20kearney&amp;sections=7618\">Windows PowerShell MVP Sean Kearney <\/a>&nbsp;and the <a href=\"http:\/\/drscripto.tv\/\">Dr. Scripto TV efforts<\/a>.&nbsp; 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.&nbsp;I am really hoping to make it for 2012.\nAll of my community events (such as talking to various users groups) are listed on the <a href=\"http:\/\/technet.microsoft.com\/en-us\/scriptcenter\/hh182567\">Scripting Community page of the TechNet Script Center<\/a>. I keep that pretty well up to date, so you can always see where I will be speaking and plan accordingly.\nAnyway, 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:<\/p>\n<ul>\n<li>New-LocalGroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>New-LocalUser&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Remove-LocalGroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Remove-LocalUser&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Set-LocalGroup&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Set-LocalUser&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Set-LocalUserPassword&nbsp;&nbsp;&nbsp;&nbsp;<\/li>\n<li>Test-IsAdministrator<\/li>\n<\/ul>\n<p>Each function is complete with help and therefore to find out how to use <strong>New-LocalGroup<\/strong>, you would use one of the commands seen here.<\/p>\n<p style=\"padding-left: 30px\">Help New-LocalGroup<\/p>\n<p style=\"padding-left: 30px\">Help New-LocalGroup &ndash;full<\/p>\n<p style=\"padding-left: 30px\">Help New-LocalGroup &ndash;examples<\/p>\n<p style=\"padding-left: 30px\">Help New-LocalGroup -detailed&nbsp;\nThe first command provides basic help. The <i>full <\/i>parameter causes all of the help information to display. The <i>examples <\/i>parameter causes help to return only example information. The difference between <i>detailed <\/i>and <i>full <\/i>is subtle&#8212;complete parameter information is returned when <i>full<\/i> is specified, but only partial parameter information is returned when using the <i>detailed <\/i>parameter.&nbsp;\nOne 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.\nIn the <strong>Set-LocalGroup<\/strong> function, I wanted to be able to either add or remove a local user to a local group. I wanted to have both <i>add <\/i>and <i>remove <\/i>switches. Obviously I do not want to include both <i>add <\/i>and <i>remove<\/i> on the same command line. However, to be a valid command, either <i>add <\/i>or <i>remove <\/i>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 <strong>[Parameter(ParameterSetName=&#8217;<i>somename<\/i>&#8216;)]<\/strong> syntax. Keep in mind that&nbsp;there are no spaces allowed between <strong>Parameter<\/strong> and <strong>(ParameterSetName &hellip;)<\/strong>. Here is the parameter declaration for the function.<\/p>\n<p style=\"padding-left: 30px\">Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=0,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueFromPipeline=$True)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$userName,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=1,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueFromPipeline=$True)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$GroupName,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$computerName = $env:ComputerName,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(ParameterSetName=&#8217;addUser&#8217;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$add,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(ParameterSetName=&#8217;removeuser&#8217;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$remove<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)\nIf I attempt to call the <strong>Set-LocalGroup<\/strong> function without using either <i>add <\/i>or <i>remove<\/i>, 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&nbsp;are shown here:&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:Windowssystem32&gt; Set-LocalGroup -userName test -GroupName testgroup<\/p>\n<p style=\"padding-left: 30px\">Set-LocalGroup : Parameter set cannot be resolved using the specified named parameters.<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:15<\/p>\n<p style=\"padding-left: 30px\">+ Set-LocalGroup &lt;&lt;&lt;&lt;&nbsp; -userName test -GroupName testgroup<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidArgument: (:) [Set-LocalGroup], ParameterBindingException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : AmbiguousParameterSet,Set-LocalGroup\n<br \/>If I supply both, <i>add <\/i>and <i>remove <\/i>at the same time, Windows PowerShell will generate the same error. The command and associated error are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:Windowssystem32&gt; Set-LocalGroup -userName test -GroupName testgroup -add -remove<\/p>\n<p style=\"padding-left: 30px\">Set-LocalGroup : Parameter set cannot be resolved using the specified named parameters.<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:15<\/p>\n<p style=\"padding-left: 30px\">+ Set-LocalGroup &lt;&lt;&lt;&lt;&nbsp; -userName test -GroupName testgroup -add -remove<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidArgument: (:) [Set-LocalGroup], ParameterBindingException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : AmbiguousParameterSet,Set-LocalGroup\nA similar but more complicated scenario occurs in the <strong>Set-LocalUser<\/strong> function. In addition to having an <i>enable <\/i>and a <i>disable <\/i>parameter, I also have a <i>password <\/i>parameter that is only needed if I also use the <i>enable<\/i> parameter. The scenario is similar to the one I had with <strong>Set-LocalGroup<\/strong>, except that one of the command will also appear with an additional parameter. Once again I chose to resolve the situation by using the <strong>[Parameter(ParameterSetName=&#8217;<i>somename<\/i>&#8216;)]<\/strong> 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:<\/p>\n<p style=\"padding-left: 30px\">Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=0,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueFromPipeline=$True)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$userName,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(Position=1,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ParameterSetName=&#8217;EnableUser&#8217;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$password,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(ParameterSetName=&#8217;EnableUser&#8217;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$enable,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [Parameter(ParameterSetName=&#8217;DisableUser&#8217;)]<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$disable,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$computerName = $env:ComputerName,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$description = &#8220;modified via powershell&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;)\nI uploaded the complete module to the Scripting Guys Script Repository. You can download it from the <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/f75801e7-169a-4737-952c-1341abea5823?SRC=Home\">Local User Management Module page<\/a>.\n&nbsp;\nJoin me tomorrow when I will go over using the Local User Management Module. In the meantime, if you have questions about <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/windows+powershell\/modules\/\">how to use modules<\/a>, check out these Hey, Scripting Guy! Blog posts that deal with modules.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n&nbsp;\n<b>Ed Wilson, Microsoft Scripting Guy<\/b>\n&nbsp;\n&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: In this article, Microsoft Scripting Guy Ed Wilson talks about using parameter sets to simplify Windows PowerShell commands. &nbsp; 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 [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,44,23,270,52,24,3,4,198,45],"class_list":["post-13471","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-groups","tag-local-accounts-and-windows-nt-4-0-accounts","tag-local-user-account-management","tag-modules","tag-other-directory-services","tag-scripting-guy","tag-scripting-techniques","tag-users","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: In this article, Microsoft Scripting Guy Ed Wilson talks about using parameter sets to simplify Windows PowerShell commands. &nbsp; 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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13471","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=13471"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13471\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=13471"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=13471"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=13471"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}