{"id":17828,"date":"2008-12-23T07:49:08","date_gmt":"2008-12-23T15:49:08","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/powershell\/?p=17828"},"modified":"2019-06-07T07:50:13","modified_gmt":"2019-06-07T15:50:13","slug":"powershell-v2-parametersets","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/powershell-v2-parametersets\/","title":{"rendered":"PowerShell V2: ParameterSets"},"content":{"rendered":"<p><P>One of the great benefits of PowerShell V2 Advanced Functions is the ease in which you can support parametersets.&nbsp; ParameterSets are, well, different SETS of valid parameters.&nbsp; For instance you can say: <BR>Get-Process -id 0<\/P>\n<P>Get-Process -Name *ss<\/P>\n<P>Those are 2 different parametersets for the Get-Process cmdlet.&nbsp; Here is an example of how you would code parametersets using advanced functions:<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>function test-param <BR>{ <BR>param( <BR>[Parameter(<STRONG><FONT color=#ff8000 size=3>ParameterSetName=&#8221;p1&#8243;,<\/FONT><\/STRONG>Position=0)] <BR>[DateTime] <BR>$d, <\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>[Parameter(<FONT color=#ff8000 size=3><STRONG>ParameterSetName=&#8221;p2&#8243;,<\/STRONG><\/FONT> Position=0)] <BR>[int] <BR>$i <BR>) <BR>&nbsp;&nbsp;&nbsp; switch (<FONT color=#ff8000 size=3><STRONG>$PsCmdlet.ParameterSetName<\/STRONG><\/FONT>) <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp; &#8220;p1&#8221;&nbsp; { Write-Host $d; break} <BR>&nbsp;&nbsp;&nbsp; &#8220;p2&#8221;&nbsp; { Write-Host $i; break} <BR>&nbsp;&nbsp;&nbsp; } <BR>}<\/FONT><\/P>\n<P>Now the question becomes &#8211; which Parameterset is used?&nbsp; Let&#8217;s experiment.&nbsp; Clearly you can specify which parameter you want and the right thing will happen:<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param -d (get-Date) <BR>12\/23\/2008 3:25:25 PM <BR>PS&gt; test-param -i 42 <BR>42<\/FONT><\/P>\n<P>But what happens when it is ambiguous?&nbsp; Where this is where the magic of PowerShell kicks in.&nbsp; PowerShell uses the types of the input to determine which one you want.&nbsp; If you specified a DateTime you probably want the p1 parameterset and if you specified a INT you probably want the p2 parameterset.<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param (get-Date) <BR>12\/23\/2008 3:37:01 PM <BR>PS&gt; test-param 42 <BR>42<\/FONT><\/P>\n<P>This almost always does exactly what you want but if it doesn&#8217;t, you can always say what you want and you&#8217;ll get it (it is just a mechanism to relieve you of work!).<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param -d 42 <BR>1\/1\/0001 12:00:00 AM<\/FONT><\/P>\n<P>(That is the DATETIME corresponding to 42 TICKs of the clock!&nbsp; Was that really what you wanted? \ud83d\ude42 )<\/P>\n<P>So now comes the interesting part.&nbsp; What if the parametersets are ambiguous.&nbsp; Let&#8217;s redo the script and make both parameters be STRINGs and then convert to DATETIME and INT in the script and see what happens.<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>function test-param <BR>{ <BR>param( <BR>[Parameter(ParameterSetName=&#8221;p1&#8243;,Position=0)] <BR><STRONG><FONT color=#ff8000>[String] <BR>$d,<\/FONT><\/STRONG> <\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>[Parameter(ParameterSetName=&#8221;p2&#8243;, Position=0)] <BR><STRONG><FONT color=#ff8000>[String] <BR><\/FONT><\/STRONG><\/FONT><FONT color=#0000ff size=2 face=Consolas><STRONG><FONT color=#ff8000>$i<\/FONT><\/STRONG> <BR>) <BR>&nbsp;&nbsp;&nbsp; switch ($PsCmdlet.ParameterSetName) <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp; &#8220;p1&#8221;&nbsp; { Write-Host <STRONG><FONT color=#ff8000>([DateTime]$d);<\/FONT><\/STRONG> break} <BR>&nbsp;&nbsp;&nbsp; &#8220;p2&#8221;&nbsp; { Write-Host <STRONG><FONT color=#ff8000>([INT]$i);<\/FONT><\/STRONG> break} <BR>&nbsp;&nbsp;&nbsp; } <BR>}<\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas><\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas><\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param -i &#8220;42&#8221; <BR>42<\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param &#8220;42&#8221; <BR><FONT color=#ff0000>test-param : Parameter set cannot be resolved using the specified named par <BR>ameters. <BR>At line:1 char:11 <BR>+ test-param &lt;&lt;&lt;&lt;&nbsp; &#8220;42&#8221; <BR>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidArgument: (:) [test-param], Parameter <BR>&nbsp;&nbsp; BindingException <BR>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : AmbiguousParameterSet,test-param<\/FONT> <\/FONT><\/P>\n<P>If you don&#8217;t specify which one you want, it is ambiguous.&nbsp; But let&#8217;s say that as the script author, you know that 9 out of 10 times people are going to want the p2 parameterset.&nbsp; Do you really want to make people type in the parametername every time just to get around this ambiguity?&nbsp; Wouldn&#8217;t it be great if the PowerShell team thought about such a circumstance and give you a mechanism to specify which parameterset to pick if things were ambiguous?<\/P>\n<P>OH WAIT &#8211; they did!<\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>function test-param <BR>{ <BR><STRONG><FONT color=#ff8000 size=3>[CmdletBinding(DefaultParametersetName=&#8221;p2&#8243;)]<\/FONT><\/STRONG> <BR>param( <BR>[Parameter(ParameterSetName=&#8221;p1&#8243;,Position=0)] <BR>[String] <BR>$d, <\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>[Parameter(ParameterSetName=&#8221;p2&#8243;, Position=0)] <BR>[String]$i <BR>) <BR>&nbsp;&nbsp;&nbsp; switch ($PsCmdlet.ParameterSetName) <BR>&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp; &#8220;p1&#8221;&nbsp; { Write-Host ([DateTime]$d); break} <BR>&nbsp;&nbsp;&nbsp; &#8220;p2&#8221;&nbsp; { Write-Host ([INT]$i); break} <BR>&nbsp;&nbsp;&nbsp; } <BR>}<\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas><\/FONT><\/P>\n<P><FONT color=#0000ff size=2 face=Consolas>PS&gt; test-param 42 <BR>42<\/FONT><\/P>\n<P>Party on!<\/P>\n<P>Jeffrey Snover [MSFT] <BR>Windows Management Partner Architect <BR>Visit the Windows PowerShell Team blog at:&nbsp;&nbsp;&nbsp; <A href=\"http:\/\/blogs.msdn.com\/PowerShell\" mce_href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/A> <BR>Visit the Windows PowerShell ScriptCenter at:&nbsp; <A href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\" mce_href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/A><\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the great benefits of PowerShell V2 Advanced Functions is the ease in which you can support parametersets.&nbsp; ParameterSets are, well, different SETS of valid parameters.&nbsp; For instance you can say: Get-Process -id 0 Get-Process -Name *ss Those are 2 different parametersets for the Get-Process cmdlet.&nbsp; Here is an example of how you would [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[97,137],"class_list":["post-17828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-advanced-functions","tag-ctp3"],"acf":[],"blog_post_summary":"<p>One of the great benefits of PowerShell V2 Advanced Functions is the ease in which you can support parametersets.&nbsp; ParameterSets are, well, different SETS of valid parameters.&nbsp; For instance you can say: Get-Process -id 0 Get-Process -Name *ss Those are 2 different parametersets for the Get-Process cmdlet.&nbsp; Here is an example of how you would [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/17828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=17828"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/17828\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=17828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=17828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=17828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}