{"id":4871,"date":"2012-10-04T00:01:00","date_gmt":"2012-10-04T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/10\/04\/build-your-own-powershell-cmdlet-part-6-of-9\/"},"modified":"2012-10-04T00:01:00","modified_gmt":"2012-10-04T00:01:00","slug":"build-your-own-powershell-cmdlet-part-6-of-9","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/build-your-own-powershell-cmdlet-part-6-of-9\/","title":{"rendered":"Build Your Own PowerShell Cmdlet: Part 6 of 9"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Windows PowerShell MVP, Sean Kearney, continues a series of guest blogs detailing building your own cmdlet.<\/p>\n<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Guest blogger and Windows PowerShell MVP, Sean Kearney, has written a series about building cmdlets. For more about Sean, see <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/sean+kearney\/\" target=\"_blank\">his previous guest blog posts<\/a>.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\"><b>Note<\/b> This is Part 6 of a nine-part series about building your own Windows PowerShell cmdlet. Read the<a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/windows+powershell\/guest+blogger\/sean+kearney\/build+your+own+cmdlet\/\"> entire series<\/a> as it unfolds.<\/p>\n<\/p>\n<p>Here&rsquo;s Sean&hellip;<\/p>\n<\/p>\n<h2>Parameters within cmdlets<\/h2>\n<\/p>\n<p>If you don&rsquo;t enable <b>[CmdletBinding()]<\/b>, you can still extend features of your advanced function as a cmdlet. This is done by preceding a parameter name or names with the argument <b>[parameter()].<\/b><\/p>\n<\/p>\n<p>The additional properties you can send with <b>[parameter()]<\/b> are:<\/p>\n<\/p>\n<ul>\n<li>\n<p>Mandatory<\/p>\n<\/li>\n<li>\n<p>Position<\/p>\n<\/li>\n<li>\n<p>ValueFromPipeline<\/p>\n<\/li>\n<li>\n<p>ValueFromPipelineByPropertyName<\/p>\n<\/li>\n<li>\n<p>ValueFromRemainingArguments<\/p>\n<\/li>\n<li>\n<p>HelpMessage<\/p>\n<\/li>\n<li>\n<p>Alias<\/p>\n<\/li>\n<\/ul>\n<p>Each of these properties has a purpose reflective of its name. This makes them quite easy to use and remember their purpose.<\/p>\n<\/p>\n<h3>Mandatory<\/h3>\n<\/p>\n<p>As you would have guessed, <b>Mandatory<\/b> means that this parameter absolutely must be in the pipeline. If it does not receive data, the cmdlet will prompt for the value. A good example of a mandatory parameter would be the path in Remove-Item. This cmdlet cannot function unless it knows what to remove. This would be mandatory for it to function.<\/p>\n<\/p>\n<p>If we want to make the <b>$FolderName<\/b> parameter mandatory in our cmdlet, we would modify it in the following fashion.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">function global:ADD-LOGFILE{<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[CmdletBinding(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">DefaultParameterSetName=&rdquo;Folder&rdquo;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">SupportsShouldProcess=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ConfirmImpact=&rsquo;High&rsquo;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">PARAM(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Mandatory=$True)<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Folder=&#8221;C:\\PowerShell&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Preface=&#8221;Logfile&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Extension=&#8221;.log&#8221;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)<\/p>\n<\/p>\n<h3>Position<\/h3>\n<\/p>\n<p>Position is simpler to deal with. If you would like users to run your cmdlet without keying in the parameter names, you can specify positions for certain parameters. For example, even though I can execute the following cmdlet&hellip;<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">GET-CHILDITEM &ndash;literalpath C:\\MyFolder<\/p>\n<\/p>\n<p>&hellip;I can equally execute this cmdlet:<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">GET-CHILDITEM C:\\MyFolder<\/p>\n<\/p>\n<p>Why is that? Because the assigned position of the <b>LiteralPath<\/b> parameter is <b>1<\/b>, as we can see from <b>Get-Help<\/b>.<\/p>\n<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6266.hsg-10-4-12-1.png\"><img decoding=\"async\" title=\"Image of command output\" alt=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6266.hsg-10-4-12-1.png\" \/><\/a><\/p>\n<\/p>\n<p>With the position parameter, we can make it easier for users to execute cmdlets with parameters they might typically use. We can do the same thing to our current set of parameters.<\/p>\n<\/p>\n<p>By default, if you don&rsquo;t define this, Windows Powershell will assign a position based on the order that you define the parameters. It is recommended as a best practice to always assign the position when defining the parameters. You&rsquo;ll find things don&rsquo;t break later on when you go to add additional parameters as you need changes.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">function global:ADD-LOGFILE{<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[CmdletBinding(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">DefaultParameterSetName=&rdquo;Folder&rdquo;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">SupportsShouldProcess=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ConfirmImpact=&rsquo;High&rsquo;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">PARAM(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Mandatory=$True),<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=0]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Folder=&#8221;C:\\PowerShell&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Position=1)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Preface=&#8221;Logfile&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Position=2)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Extension=&#8221;.log&#8221;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)<\/p>\n<\/p>\n<h3>ValueFromPipeline<\/h3>\n<\/p>\n<p>You may or may not (because the design is completely in your hands) want to have a parameter accept data from the pipeline. This property is strictly a Boolean True or False setting. It specifies that a parameter can accept input from the pipeline. We can leverage this feature in our cmdlet by changing our parameters in the following manner.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">function global:ADD-LOGFILE{<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[CmdletBinding(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">DefaultParameterSetName=&rdquo;Folder&rdquo;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">SupportsShouldProcess=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ConfirmImpact=&rsquo;High&rsquo;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">PARAM(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=0)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Folder=&#8221;C:\\PowerShell&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Preface=&#8221;Logfile&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Extension=&#8221;.log&#8221;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)<\/p>\n<\/p>\n<h3>ValueFromPipelineByPropertyName<\/h3>\n<\/p>\n<p>This is similar to the prior parameter, but it specifies the actual property name that the parameter can accept from the pipeline. A good example to work with is <b>Get-ChildItem<\/b>. When the <b>Get-ChildItem<\/b> cmdlet is run against the file system, it returns multiple properties such as <b>FullName<\/b>, <b>Extension<\/b>, <b>DirectoryName<\/b>, and <b>LastAccessTime<\/b> amongst others as shown in the following example.<\/p>\n<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2867.hsg-10-4-12-2.png\"><img decoding=\"async\" title=\"Image of properties\" alt=\"Image of properties\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2867.hsg-10-4-12-2.png\" \/><\/a><\/p>\n<\/p>\n<p>If we want to ensure that a parameter only accepts data from the pipeline when the property name is <b>Extension<\/b>, we can make this change to a parameter. We can tell the <b>Add-LogFile<\/b> cmdlet that we are building to accept the <b>Extension<\/b> property if passed through the pipeline.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">function global:ADD-LOGFILE{<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[CmdletBinding(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">DefaultParameterSetName=&rdquo;Folder&rdquo;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">SupportsShouldProcess=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ConfirmImpact=&rsquo;High&rsquo;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">PARAM(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=0)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Folder=&#8221;C:\\PowerShell&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Preface=&#8221;Logfile&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ValueFromPipelineByPropertyName=$True)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Extension=&#8221;.log&#8221;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)<\/p>\n<\/p>\n<h3>ValueFromRemainingArguments<\/h3>\n<\/p>\n<p>When you use this parameter, it identifies that any data coming down the pipeline that is not already assigned to other parameters will be accepted by this variable.<\/p>\n<\/p>\n<h3>HelpMessage<\/h3>\n<\/p>\n<p>There is nothing better for a user than being a little bit helpful. The Help message is a simple bit of text that you can provide to explain what this parameter is. In the case of the cmdlet we are building, it can be as simple as, &ldquo;Folder to place log files in.&rdquo; Here is a simple example of the <b>HelpMessage<\/b> put to use in our cmdlet.<\/p>\n<\/p>\n<p style=\"padding-left: 30px\">function global:ADD-LOGFILE{<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[CmdletBinding(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">DefaultParameterSetName=&rdquo;Folder&rdquo;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">SupportsShouldProcess=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ConfirmImpact=&rsquo;High&rsquo;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">PARAM(<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(Mandatory=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=0,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">HelpMessage=&rsquo;Folder to Store Logfiles in&rsquo;)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Folder=&#8221;C:\\PowerShell&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">HelpMessage=&rsquo;TEXT to prepend all logfiles with&rsquo;)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Preface=&#8221;Logfile&#8221;,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[parameter(ValueFromPipeline=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">Position=1,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">ValueFromPipelineByPropertyName=$True,<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">HelpMessage=&rsquo;File Extension for Logfiles&rsquo;)]<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">[STRING[]]$Extension=&#8221;.log&#8221;<\/p>\n<p style=\"padding-left: 30px\">\n<p style=\"padding-left: 30px\">)<\/p>\n<\/p>\n<p>If we ran our cmdlet now and did not provide any information for the <b>Folder<\/b> parameter (because it is a <b>MandatoryParameter<\/b>), we would see the Help message echoed in this fashion.<\/p>\n<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2766.hsg-10-4-12-3.png\"><img decoding=\"async\" title=\"Image of message\" alt=\"Image of message\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2766.hsg-10-4-12-3.png\" \/><\/a><\/p>\n<\/p>\n<p>Our <b>Folder<\/b> parameter now has a simple line of text to explain its purpose if needed. As part of the features of the cmdlet, Windows Powershell allows the user to enter &ldquo;!?&rdquo; to pull up that simple line of Help.<\/p>\n<\/p>\n<h3>Alias<\/h3>\n<\/p>\n<p>An alias allows you to provide alternate names that a parameter can accept data with. The parameter name itself will not change; but in the case of <b>AcceptValueByPropertyName<\/b>, we can give a parameter multiple names to accept the data with automatically.<\/p>\n<\/p>\n<p>In the case of <b>Folder<\/b>, we could choose to use an alias of <b>Path<\/b> or <b>Destination<\/b> if that made more sense.<\/p>\n<\/p>\n<h3>Validation Parameters<\/h3>\n<\/p>\n<p>You can apply various attributes that allow you to indicate how values sent into the parameters should be dealt with or how they can be referred to alternate. Validation attributes are added like the other parameter attributes, and they can allow us to validate data being passed into the cmdlet or to specify what the cmdlet does not permit for certain parameters. The validation attributes that are available to us are:<\/p>\n<\/p>\n<ul>\n<li>\n<p>AllowNull<\/p>\n<\/li>\n<li>\n<p>AllowEmptyString<\/p>\n<\/li>\n<li>\n<p>AllowEmptyCollection<\/p>\n<\/li>\n<li>\n<p>ValidateCount<\/p>\n<\/li>\n<li>\n<p>ValidateLength<\/p>\n<\/li>\n<li>\n<p>ValidatePattern<\/p>\n<\/li>\n<li>\n<p>ValidateRange<\/p>\n<\/li>\n<li>\n<p>ValidateScript<\/p>\n<\/li>\n<li>\n<p>ValidateSet<\/p>\n<\/li>\n<li>\n<p>ValidateNotNull<\/p>\n<\/li>\n<li>\n<p>ValidateNotNullOrEmpty<\/p>\n<\/li>\n<\/ul>\n<p>~Sean<\/p>\n<\/p>\n<p>Thank you, Sean. You absolutely ROCK! Guest Blogger Week will continue tomorrow when Sean will bring us Part 7.<\/p>\n<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto: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.<\/p>\n<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Windows PowerShell MVP, Sean Kearney, continues a series of guest blogs detailing building your own cmdlet. Microsoft Scripting Guy, Ed Wilson, is here. Guest blogger and Windows PowerShell MVP, Sean Kearney, has written a series about building cmdlets. For more about Sean, see his previous guest blog posts. Note This is Part 6 [&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":[372,56,3,154,45],"class_list":["post-4871","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-build-your-own-cmdlet","tag-guest-blogger","tag-scripting-guy","tag-sean-kearney","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Windows PowerShell MVP, Sean Kearney, continues a series of guest blogs detailing building your own cmdlet. Microsoft Scripting Guy, Ed Wilson, is here. Guest blogger and Windows PowerShell MVP, Sean Kearney, has written a series about building cmdlets. For more about Sean, see his previous guest blog posts. Note This is Part 6 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4871","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=4871"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/4871\/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=4871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=4871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=4871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}