{"id":3856,"date":"2013-04-09T00:01:00","date_gmt":"2013-04-09T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/04\/09\/using-powershell-functions-best-practices\/"},"modified":"2013-04-09T00:01:00","modified_gmt":"2013-04-09T00:01:00","slug":"using-powershell-functions-best-practices","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/using-powershell-functions-best-practices\/","title":{"rendered":"Using PowerShell Functions: Best Practices"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Microsoft Scripting Guy, Ed Wilson, talks about some best practices for using Windows PowerShell functions.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Windows PowerShell functions are really powerful, and at the same time, they are incredibly simple to create. This makes Windows PowerShell functions flexible and functional. But this flexibility also means that there is a lot of misunderstanding.<\/p>\n<h2>A simple function<\/h2>\n<p>At the low end (in terms of readability, functionality, features, and so on), a Windows PowerShell function is creatable on a single line interactively at the Windows PowerShell console. The minimum number of elements required to create a function are:<\/p>\n<ul>\n<li>The <strong>Function<\/strong> keyword<\/li>\n<li>The name of the function<\/li>\n<li>A script block<\/li>\n<\/ul>\n<p>That is it. This means that the following is a legitimate function:<\/p>\n<p style=\"padding-left: 30px\">function a {}<\/p>\n<p>It does not do anything, but it is legitimate. Running the code at a command prompt in the Windows PowerShell console creates the function. I can then pipe output to it, and even verify that it exists on the Windows PowerShell function PS drive. The following script illustrates these concepts.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; function a {}<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gps | a<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; dir function:a<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">CommandType&nbsp;&nbsp;&nbsp;&nbsp; Name&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModuleName<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;-&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-<\/p>\n<p style=\"padding-left: 30px\">Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a<span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n<h2>Adding functionality to the function<\/h2>\n<p>I often need to get a view of data, or a snapshot of data, before I return all of the data. Typically, I pipe the data to the <strong>Select-Object<\/strong> cmdlet and pick the last three entries in the data. The following script illustrates this technique (<strong>gps<\/strong> is an alias for the <strong>Get-Process<\/strong> cmdlet, and <strong>select<\/strong> is an alias for the <strong>Select-Object<\/strong> cmdlet).<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gps | select -Last 3<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 207&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp; 1340&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3064&nbsp;&nbsp;&nbsp; 40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1848 WUDFHost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 405&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 19&nbsp;&nbsp;&nbsp;&nbsp; 3636&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10012&nbsp;&nbsp;&nbsp; 95&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1904 WUDFHost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18&nbsp;&nbsp;&nbsp;&nbsp; 3336&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7852&nbsp;&nbsp;&nbsp; 89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2880 ZeroConfigService<\/p>\n<p>I use this type of code when I am troubleshooting or simply perusing the status of a computer. Because I have established a pattern that pipes data to the <strong>Select-Object<\/strong> cmdlet and chooses the last three items, I can put this into a function that accepts pipelined input and outputs the last three items.<\/p>\n<p>Because I am writing the function interactively in the Windows PowerShell console, and because I will be using it a lot, I give it a really short name. Here I call it &ldquo;<strong>l<\/strong>&rdquo; (as in lower case letter &ldquo;L&rdquo;). Inside the script block, I use the automatic variable <strong>$input<\/strong>, which is the input piped into a function.<\/p>\n<p>The <strong>$input<\/strong> variable only exists inside the context of a function, and only for the time the function is called. If I check the value of <strong>$input<\/strong> outside of the function, it is empty. So what I pass to the function is then piped to the <strong>Select-Object<\/strong> cmdlet, and the last three items are returned from the function. The function is shown here.<\/p>\n<p style=\"padding-left: 30px\">function l {$input | select -Last 3}<\/p>\n<p>To use the function, I pipe results to the function. The following script selects the last three processes.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; gps | l<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 207&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp; 1340&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3064&nbsp;&nbsp;&nbsp; 40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1848 WUDFHost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 405&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 19&nbsp;&nbsp;&nbsp;&nbsp; 3636&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10012&nbsp;&nbsp;&nbsp; 95&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1904 WUDFHost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 214&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18&nbsp;&nbsp;&nbsp;&nbsp; 3336&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7852&nbsp;&nbsp;&nbsp; 89&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2880 ZeroConfigService<\/p>\n<p><span style=\"font-size: 12px\">I can select the last three services (<\/span><strong style=\"font-size: 12px\">gsv<\/strong><span style=\"font-size: 12px\"> is an alias) as shown here.<\/span><\/p>\n<p style=\"padding-left: 30px\">gsv | l<\/p>\n<p>Or maybe I want to look at the last three entries in the event log as shown here.<\/p>\n<p style=\"padding-left: 30px\">Get-EventLog application | l<\/p>\n<p>I can even use the <strong>range<\/strong> operator and select the last three numbers. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">1..10 | l<\/p>\n<p>These commands and their associated output are shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5417.hsg-4-9-13-01.png\"><img decoding=\"async\" style=\"border: 0px currentColor\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5417.hsg-4-9-13-01.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Best Practices Week will continue tomorrow when I will continue talking about functions.<\/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><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><span style=\"font-size: 12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about some best practices for using Windows PowerShell functions. Microsoft Scripting Guy, Ed Wilson, is here. Windows PowerShell functions are really powerful, and at the same time, they are incredibly simple to create. This makes Windows PowerShell functions flexible and functional. But this flexibility also means that there [&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":[331,69,3,4,45],"class_list":["post-3856","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-best-practices","tag-functions","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about some best practices for using Windows PowerShell functions. Microsoft Scripting Guy, Ed Wilson, is here. Windows PowerShell functions are really powerful, and at the same time, they are incredibly simple to create. This makes Windows PowerShell functions flexible and functional. But this flexibility also means that there [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3856","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=3856"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3856\/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=3856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}