{"id":51743,"date":"2009-12-22T00:01:00","date_gmt":"2009-12-22T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/12\/22\/hey-scripting-guy-how-can-i-use-real-names-for-windows-powershell-functions\/"},"modified":"2009-12-22T00:01:00","modified_gmt":"2009-12-22T00:01:00","slug":"hey-scripting-guy-how-can-i-use-real-names-for-windows-powershell-functions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-use-real-names-for-windows-powershell-functions\/","title":{"rendered":"Hey, Scripting Guy! How Can I Use &#8220;Real Names&#8221; for Windows PowerShell Functions?"},"content":{"rendered":"<p class=\"MsoNormal\">&nbsp;<a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! I enjoyed reading <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2009\/12\/21\/hey-scripting-guy-december-21-2009.aspx\">yesterday&rsquo;s blog post<\/a> about working with functions. I was really interested when you were talking about using &ldquo;real names&rdquo; for my functions. You did not say too much about why I should do that, but I guess it makes sense. I am thinking about writing a function that reads a text file, and I am considering using the <b>Read<\/b> verb for that. Therefore, the function would be named <b>Read-TextFile<\/b>. What do you think?<\/p>\n<p class=\"MsoNormal\"><span>&#8212; DS<\/span><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello DS, <\/p>\n<p class=\"MsoNormal\"><span>Microsoft Scripting Guy Ed Wilson here, I am listening to <a href=\"http:\/\/en.wikipedia.org\/wiki\/The_Go-Go%27s\">The Go-Go&rsquo;s<\/a> on my <a href=\"http:\/\/zune.net\/en-us\/products\/zunehd\/default.htm\"><font face=\"Segoe\">Zune HD<\/font><\/a> and sipping a cup of English Breakfast tea from my new tea pot. I had not heard The Go-Go&rsquo;s for a while, and the shuffle feature just brought up the song. Nice compliment to my tea.&nbsp;<\/span><\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of Windows PowerShell 2.0 Best Practices book\" alt=\"Image of Windows PowerShell 2.0 Best Practices book\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/november\/hey1123\/hsg-11-23-09-03.jpg\" width=\"197\" height=\"240\"><\/p>\n<p class=\"Readeraidonly\">Note: Portions of today&#8217;s Hey, Scripting Guy! article are excerpted from the Microsoft Press book, <em>Windows PowerShell 2.0 Best Practices<\/em> by Ed Wilson. This book is <a href=\"http:\/\/bit.ly\/1NBxZ0\"><font face=\"Segoe\">now available<\/font><\/a>.<\/p>\n<p class=\"MsoNormal\">DS, in addition to using &ldquo;approved verbs,&rdquo; it is a good idea to use the verb in the same manner in which the Windows PowerShell team used it. The easy way to verify this is to use the <b>Get-Command<\/b> cmdlet with the verb parameter. To see cmdlets that use the <b>Read<\/b> verb, you would use the command shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><font size=\"2\">PS C:&gt; Get-Command -Verb read<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><\/p>\n<p><font size=\"2\" face=\"Lucida Sans Typewriter\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><font size=\"2\">CommandType<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<span>&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; <\/span>Definition<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><font size=\"2\">&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&#8212;&#8212;&#8212;-<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><font size=\"2\">Cmdlet<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Read-Host<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Read-Host [[-Prompt] &lt;Object&gt;] [-AsSecureString]&#8230;<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><\/p>\n<p><font size=\"2\" face=\"Lucida Sans Typewriter\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span><\/p>\n<p><font size=\"2\" face=\"Lucida Sans Typewriter\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><font size=\"2\">PS C:&gt;<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\">In reviewing the list of cmdlets that use the verb <b>Read<\/b>, you can see there is only one cmdlet that uses the verb <b>Read<\/b>. It is the <b>Read-Host<\/b> cmdlet, which is used to obtain information from the command line. This would indicate that the verb <b>Read<\/b> is not used to describe reading a file. There is no verb called Display, and the <b>Write<\/b> verb is used in cmdlet names such as <b>Write-Error<\/b> and <b>Write-Debug<\/b>, both of which do not really seem to have the concept of displaying information. If you were writing a function that would read the content of a text file and display statistics about that file, you might call the function <b>Get-TextStatistics<\/b>. <\/p>\n<p class=\"MsoNormal\">By using a name such as <b>Get-TextStatistics<\/b>, we are following the Windows PowerShell team&rsquo;s examples of cmdlet names such as <b>Get-Process<\/b> and <b>Get-Service<\/b>. The <b>Get<\/b><i> <\/i>verb includes the concept of emitting retrieved content as essential functionality. The <b>Get-TextStatistics<\/b> function accepts a single parameter called <b>path<\/b>. The interesting thing about parameters for functions is that when you pass a value to the parameter, you use a dash. When you refer to the value inside the function, it is a variable such as <b>$path<\/b>. To call the <b>Get-TextStatistics<\/b> function, you have a couple of options. The first is to use the name of the function and put the value in parenthesis. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-TextStatistics(&#8220;C:fsomytext.txt&#8221;)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">This is a natural way to call the function, and it works when there is a single parameter. It does not work when there are two or more parameters. Another way to pass a value to the function is to use the dash and the parameter name. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-TextStatistics &ndash;path &#8220;C:fsomytext.txt&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">You will note from the previous example that no parentheses are required. You can also use positional arguments when passing a value. In this usage, you omit the name of the parameter entirely, and simply place the value for the parameter following the call to the function. This is illustrated here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-TextStatistics &#8220;C:fsomytext.txt&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"Readeraidonly\">The use of positional arguments works well when one is working from the command line and wishes to speed things along by reducing the typing load. It can be a bit confusing, and in general I tend to avoid it, even when working at the command line. This is because I often copy my working code from the console directly into a script; as a result, I would need to retype the command a second time to get rid of aliases and unnamed arguments. With the improvements in tab expansion, I feel that the time saved by using positional arguments or partial arguments does not sufficiently warrant the time involved in retyping commands when they need to be transferred to scripts. The other reason for always using named arguments is that it helps me to be aware of the exact command syntax. <\/p>\n<p class=\"MsoNormal\">One additional way to pass a value to a function is to use partial parameter names. All that is required is enough of the parameter name to disambiguate it from other parameters. This means if you have two parameters that both begin with the letter &ldquo;p,&rdquo; you would need to supply enough letters of the parameter name that will separate it from the other parameter. This is illustrated here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-TextStatistics &ndash;p &#8220;C:fsomytext.txt&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The complete text of the <b>Get-TextStatistics<\/b> function is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Function Get-TextStatistics($path)<br>{<br><span>&nbsp;<\/span>Get-Content -path $path |<br><span>&nbsp;<\/span>Measure-Object -line -character -word<br>}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Between Windows PowerShell 1.0 and Windows PowerShell 2.0, the number of verbs grew from 40 to 60. It is anticipated that the list of standard verbs should cover 80-85 percent of administrative tasks. The new verbs are listed here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Checkpoint<br>Complete<br>Connect<br>Debug<br>Disable<br>Disconnect<br>Enable<br>Enter<br>Exit<br>Limit<br>Receive<br>Register<br>Reset<br>Restore<br>Send<br>Show<br>Undo<br>Unregister<br>Use<br>Wait<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After the function has been named, you will create any parameters the function may require. The parameters are contained within parentheses. In the <b>Get-TextStatistics<\/b> function, the function accepts a single parameter, <b>path<\/b>. When you have a function that accepts a single parameter, you can pass the value to the function by placing the value for the parameter inside parentheses. This command is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Get-TextLength(&#8220;C:fsotest.txt&#8221;)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The path &#8220;C:fsotest.txt&#8221; is passed to the <b>Get-TextStatistics<\/b> function via the <b>path<\/b> parameter. Inside the function, the string &#8220;C:fsotext.txt&#8221; is contained in the <b>$path<\/b> variable. The <b>$path<\/b> variable only lives within the confines of the <b>Get-TextStatistics<\/b> function. It is not available outside the scope of the function. It is available from within child scopes of the <b>Get-TextStatistics<\/b> function. A child scope of the <b>Get-TextStatistics<\/b> is one that is created from within the <b>Get-TextStatistics<\/b> function. <\/p>\n<p class=\"MsoNormal\">In the Get-TextStatisticsCallChildFunction.ps1 script, the <b>Write-Path<\/b> function is called from within the <b>Get-TextStatistics<\/b> function. This means the <b>Write-Path<\/b> function will have access to variables that are created within the <b>Get-TextStatistics<\/b> function. This is the concept of variable scope and is an extremely important concept when working with functions. As you use functions to separate the creation of objects, you must always be aware of where the object gets created and where you intend to use that object. In the <b>Get-TextStatisticsCallChildFunction<\/b> the <b>$path<\/b> variable does not obtain its value until it is passed to the function. Therefore, it lives within the <b>Get-TextStatistics<\/b> function. But because the <b>Write-Path<\/b> function is called from within the <b>Get-TextStatistics<\/b> function, it inherits the variables from that scope. When you call a function from within another function, variables created within the parent function are available to the child function. This is seen in the Get-TextStatisticsCallChildFunction.ps1 script. <\/p>\n<p class=\"CodeBlockScreenedHead\"><b>Get-TextStatisticsCallChildFunction.ps1<\/p>\n<p><\/b><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Function Get-TextStatistics($path)<br>{<br><span>&nbsp;<\/span>Get-Content -path $path |<br><span>&nbsp;<\/span>Measure-Object -line -character -word<br><span>&nbsp;<\/span>Write-Path<br>}<\/p>\n<p>Function Write-Path()<br>{<br><span>&nbsp;<\/span>&#8220;Inside Write-Path the `$path variable is equal to $path&#8221;<br>}<\/p>\n<p>Get-TextStatistics(&#8220;C:fsotest.txt&#8221;)<br>&#8220;Outside the Get-TextStatistics function `$path is equal to $path&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Inside the <b>Get-TextStatistics<\/b> function, the <b>$path<\/b> variable is used to provide the path to the <b>Get-Content<\/b> cmdlet. When the <b>Write-Path<\/b> function is called, nothing is passed to it. But inside the <b>Write-Path<\/b> function, the value of <b>$path<\/b> is maintained. Outside both of the functions, however, <b>$path<\/b> does not have any value. The output from running the script is seen here:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of output from running script\" alt=\"Image of output from running script\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/december\/hey1222\/hsg-12-22-09-01.jpg\" width=\"600\" height=\"462\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">You will then need to open and close a script block. The curly bracket is used to delimit the script block on a function. As a best practice, when writing a function I will always use the <b>function<\/b> keyword, and type the name, the input parameters, and the curly brackets for the script block at the same time. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Function My-Function()<br>{<br><span>&nbsp;<\/span>#insert code here<br>} <\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">DS, that is all there is to working with function names and function parameters. Function Week will continue tomorrow. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/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 class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/span><\/b><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; &nbsp; Hey, Scripting Guy! I enjoyed reading yesterday&rsquo;s blog post about working with functions. I was really interested when you were talking about using &ldquo;real names&rdquo; for my functions. You did not say too much about why I should do that, but I guess it makes sense. I am thinking about writing a function [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,45],"class_list":["post-51743","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; &nbsp; Hey, Scripting Guy! I enjoyed reading yesterday&rsquo;s blog post about working with functions. I was really interested when you were talking about using &ldquo;real names&rdquo; for my functions. You did not say too much about why I should do that, but I guess it makes sense. I am thinking about writing a function [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51743","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51743"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51743\/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=51743"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51743"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51743"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}