{"id":17481,"date":"2010-08-09T00:01:00","date_gmt":"2010-08-09T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/08\/09\/how-do-i-use-a-windows-powershell-script-containing-functions\/"},"modified":"2010-08-09T00:01:00","modified_gmt":"2010-08-09T00:01:00","slug":"how-do-i-use-a-windows-powershell-script-containing-functions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-do-i-use-a-windows-powershell-script-containing-functions\/","title":{"rendered":"How Do I Use a Windows PowerShell Script Containing Functions?"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p><strong>Summary<\/strong>: Using a script containing <a href=\"http:\/\/technet.microsoft.com\/en-us\/scriptcenter\/powershell.aspx\">Windows PowerShell<\/a> functions can be as simple as dot-sourcing the script.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" \/><\/p>\n<p> Hey, Scripting Guy! I was looking in the <a href=\"http:\/\/gallery.technet.microsoft.com\/ScriptCenter\/en-us\/\">Script Center Script Repository<\/a> for Windows PowerShell scripts, and I found one that was really cool. Unfortunately, when I attempted to use it, it did not work. I know that scripts in the Script Repository are not supported, and I am not asking you to fix the script, but I need to make sure I am using the script properly. <\/p>\n<p>&#8212; OM<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" \/><\/p>\n<p> Hello OM, <\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. It seems that every year some business consultant writes a book that becomes &ldquo;the book&rdquo; for businesses during that calendar year. I remember one book about sharks, and before that a book about a carpet salesperson. The books themselves are generally innocuous, but the violence inflicted upon &ldquo;corporate speak&rdquo; is often irreparable. A brief stroll down the corridors of any Fortune 500 company should be long enough to sample the drivel of &ldquo;putting skin in the game,&rdquo; &ldquo;seeking win-win solutions,&rdquo; or &ldquo;finding an end game strategy.&rdquo; While it appears that many of the tortured phrases are &ldquo;leveraged&rdquo; from athletic contests, some are more pedestrian if not downright mundane. Consider the moniker &ldquo;elevator pitch&rdquo; that I assume replaces the now semi-pejorative &ldquo;executive summary.&rdquo; <\/p>\n<p>OM, a &ldquo;30,000-foot view&rdquo; (perhaps now updated to 40,000-foot view with reference to the higher altitudes the airlines are flying in attempts to reduce fuel costs) of Windows PowerShell might consist of the following: &ldquo;Windows PowerShell is both a scripting language and an interactive command environment. It is as if Microsoft took the old-fashioned command prompt, and put VBScript inside it.&rdquo; <\/p>\n<p>It is this dual nature of Windows PowerShell&mdash;the scripting and the interactive environment&mdash;that confuses people when they first begin to &ldquo;leverage PowerShell for their network automation solution&rdquo; (ugh&mdash;sorry about that). <a href=\"http:\/\/support.microsoft.com\/kb\/968929\">Windows PowerShell 2.0<\/a> mitigates this confusion a little because there is the Windows PowerShell console, and the Windows PowerShell ISE (integrated scripting environment&mdash;a script editor). I open the Windows PowerShell console when I want to work in an interactive fashion, and I open the Windows PowerShell ISE when I want to write, edit, or run a script. Of course, you can run Windows PowerShell scripts from within the Windows PowerShell console, but I often prefer to open the script in the ISE so that I can peruse the code the script is executed, especially if it is one with which I have not recently worked. <\/p>\n<p>Windows PowerShell contains a number of little programs called cmdlets (pronounced &ldquo;command lets&rdquo;). I obtain a list of the cmdlets by using the <strong>Get-Command<\/strong> cmdlet and specifying the <strong>CommandType<\/strong> of cmdlet. The command shown here produces the output displayed in the image following it:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #0000ff\">Get-Command<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-CommandType<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">cmdlet<\/span> <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5381.hsg080910011_17227C0A.jpg\"><img decoding=\"async\" height=\"462\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1581.hsg080910011_thumb_747E3D8E.jpg\" alt=\"Image of output of Get-Command cmdlet\" border=\"0\" title=\"Image of output of Get-Command cmdlet\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>To use one of these cmdlets can be as simple as typing the cmdlet name and pressing ENTER, or as complex as supplying multiple values for numerous parameters (for example, to obtain a list of all the services on the workstation using <strong>Get-Service<\/strong>). The command <strong>Get-Service<\/strong> produces the output shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8037.hsg080910021_13C0E462.jpg\"><img decoding=\"async\" height=\"462\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8446.hsg080910021_thumb_60F0DDED.jpg\" alt=\"Image of output of Get-Service cmdlet\" border=\"0\" title=\"Image of output of Get-Service cmdlet\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>The scripting language aspect of Windows PowerShell allows one to use things such as <strong>for<\/strong>\/<strong>next<\/strong>; however, in Windows PowerShell language, it is simply the <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/04\/24\/hey-scripting-guy-april-24-2010.aspx\">for statement<\/a> because there is no next. To produce a list of numbers from 1 to 10, you could use code such as this:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #000000\">for(<\/span><span style=\"color: #2b91af\">$a<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #800000\">1<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">;<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$a<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">-le<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #800000\">10<\/span><span style=\"color: #0000ff\">;<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$a++<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #2b91af\">$a<\/span><span style=\"color: #000000\">}<\/span> <\/p>\n<p>By adding additional information in the script block (the curly brackets), the output is modified. The following image shows the output. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0511.hsg080910031_6737B47B.jpg\"><img decoding=\"async\" height=\"409\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3731.hsg080910031_thumb_38DE2ECE.jpg\" alt=\"Image of modified output\" border=\"0\" title=\"Image of modified output\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>OM, you may be asking what this has to do with running a script found in the Script Repository. Suppose you find a script named Add-Numbers.ps1 that contains a single function called <strong>Add-Numbers<\/strong>. The function accepts two numbers and returns the sum. The following image shows the content of the function.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3666.hsg080910041_665F4E91.jpg\"><img decoding=\"async\" height=\"562\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2677.hsg080910041_thumb_7EEEEBE1.jpg\" alt=\"Image of content of function\" border=\"0\" title=\"Image of content of function\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>When I run the Add-Numbers.ps1 script, nothing happens. If I use the <strong>dir<i> <\/i><\/strong>command (an alias for the <a href=\"http:\/\/www.bing.com\/visualsearch?g=powershell_cmdlets&amp;FORM=Z9GE22\">Get-ChildItem cmdlet<\/a>), I can confirm that absolutely nothing did in fact happen. If I dot-source the script (by placing a period and a space on the line in front of the path to the script), and then I use the <strong>dir<\/strong> command to check the function drive, I can see that the <strong>Add-Numbers<\/strong> function was added to the function drive. This allows me to use the function in the same manner that I use Windows PowerShell cmdlets. The following image illustrates this technique. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7853.hsg080910051_5E67AC2F.jpg\"><img decoding=\"async\" height=\"269\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1184.hsg080910051_thumb_6FD80D07.jpg\" alt=\"Image of checking to see if Add-Numbers function can be used in same manner as cmdlets\" border=\"0\" title=\"Image of checking to see if Add-Numbers function can be used in same manner as cmdlets\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>In modifying the script to contain code that will run when the script launches (also known as directly executable code), you will see output when the script runs. The revised Add-Numbers.ps1 script adds command-line parameters, and calls the <strong>Add-One<\/strong> function with values supplied by the command-line parameters. I assign default values for the two command-line parameters because it is often desirable for a script to run without user intervention. The revised script is shown here. <\/p>\n<p style=\"padding-left: 30px\"><strong>Add-NumbersWithExecutableCode.ps1<\/strong><\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #000000\">Param(<\/span><span style=\"color: #2b91af\">$intOne<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #800000\">5<\/span><span style=\"color: #000000\">,<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #2b91af\">$intTwo<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #800000\">3<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">Function<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">add-numbers<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">Param(<\/span><span style=\"color: #2b91af\">$intOne<\/span><span style=\"color: #000000\">,<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #2b91af\">$intTwo<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #2b91af\">$intOne<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">+<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$intTwo<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #000000\">end<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">function<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">add-numbers<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">***<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">entry<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">point<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">to<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">script<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">***<\/span><span style=\"color: #808080\">     <br \/><\/span><span style=\"color: #000000\">add-numbers<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-intOne<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$intOne<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-inttwo<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$intTwo<\/span> <\/p>\n<p>Most of the scripts I write contain directly executable code with judiciously selected default values. This allows a person to run a script with no intervention. If you deploy a script such as a logon script using <a href=\"http:\/\/technet.microsoft.com\/en-us\/windowsserver\/bb310732.aspx\">Group Policy<\/a>, you do not want the user to be bothered with questions. You want the script to run in an unattended fashion. I will talk about using Group Policy to run a logon script in this coming Saturday&rsquo;s Weekend Scripter article. <\/p>\n<p>When running the Add-NumbersWithExecutableCode.ps1 script, the two default values are used, and the number 8 appears on the Windows PowerShell console. Because the script creates command-line parameters, it accepts different values when it launches. You can use the parameter names or positional arguments. All this is groovy. As before, the function does not appear on the function drive. The problem with executable code arises when the script is dot-sourced into the Windows PowerShell console. The following image illustrates the problem&mdash;the executable code launches using the default parameter values, and the number 8 appears on the Windows PowerShell console. However, the good news is that the function resides on the function drive and is available for additional use. <\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4718.hsg080910061_1D592CCB.jpg\"><img decoding=\"async\" height=\"352\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2086.hsg080910061_thumb_4EE49A60.jpg\" alt=\"Image of proof function is available for additional use\" border=\"0\" title=\"Image of proof function is available for additional use\" style=\"border-bottom: 0px;border-left: 0px;border-top: 0px;border-right: 0px\" \/><\/a> <\/p>\n<p>It is therefore up to the person who writes the script: Include only functions, or add additional code that permits independent execution of the script? The decision point is the use case scenario for the script&mdash;how will you normally use the script?<\/p>\n<p>&nbsp;<\/p>\n<p>OM, that is all there is to using a script that contains a function at the Windows PowerShell console. Running Windows PowerShell Scripts Week will continue tomorrow when we will talk about using functions in scripts. <\/p>\n<p>We invite you to follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to us at <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a> or post them on the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\">Official Scripting Guys Forum.<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/strong><\/p>\n<p><strong><br \/><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Summary: Using a script containing Windows PowerShell functions can be as simple as dot-sourcing the script. &nbsp; Hey, Scripting Guy! I was looking in the Script Center Script Repository for Windows PowerShell scripts, and I found one that was really cool. Unfortunately, when I attempted to use it, it did not work. I know [&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":[69,51,2,3,4,45],"class_list":["post-17481","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-functions","tag-getting-started","tag-running","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Summary: Using a script containing Windows PowerShell functions can be as simple as dot-sourcing the script. &nbsp; Hey, Scripting Guy! I was looking in the Script Center Script Repository for Windows PowerShell scripts, and I found one that was really cool. Unfortunately, when I attempted to use it, it did not work. I know [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/17481","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=17481"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/17481\/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=17481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=17481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=17481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}