<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://powershell.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tags 'functions' and 'scripting techniques'</title><link>http://powershell.com/cs/search/SearchResults.aspx?q=app:weblogs&amp;tag=functions,scripting+techniques&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'functions' and 'scripting techniques'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>I Found This Module—What Do I Do?</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/15/i-found-this-module-what-do-i-do.aspx</link><pubDate>Wed, 15 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23570</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, talks about how to use a Windows PowerShell module.&lt;/span&gt;&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.microsoft.com/library/media/1033/technet/images/scriptcenter/qanda/q-sm.jpg" alt="Hey, Scripting Guy! Question" /&gt;&amp;nbsp;Hey, Scripting Guy! &amp;nbsp;I found this module in the Scripting Guys Script Repository. Now what do I do?&lt;/p&gt;
&lt;p&gt;&amp;mdash;SH&lt;/p&gt;
&lt;p&gt;&lt;img src="http://img.microsoft.com/library/media/1033/technet/images/scriptcenter/qanda/a-sm.jpg" alt="Hey, Scripting Guy! Answer" /&gt;&amp;nbsp;Hello SH,&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This morning I have been busy booking travel to &lt;a href="http://europe.msteched.com/#fbid=Y6s0qEgGIo3" target="_blank"&gt;Madrid, Spain for TechEd 2013&lt;/a&gt;. I will have a booth there with the Scripting Wife. In addition, I will be joining the Windows PowerShell team for their instructor led lab&amp;mdash;it will be way cool. Air travel these days is so much fun, I genuinely look forward to each upcoming flight. This includes my flight to &lt;a href="http://northamerica.msteched.com/#fbid=fii1JDbUFpU" target="_blank"&gt;TechEd 2013 in New Orleans&lt;/a&gt;, where you can also find the Scripting Wife and me. (I am also conducting a Windows PowerShell instructor led lab in the &lt;a href="http://en.wikipedia.org/wiki/New_Orleans" target="_blank"&gt;big easy&lt;/a&gt;.)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&amp;nbsp;&amp;nbsp;&lt;/strong&gt;This is the fourth part of a multipart series about using Windows PowerShell functions and modules. Prior to reading this blog, you should read the previous posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/08/i-found-this-powershell-function-now-what-do-i-do.aspx" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/13/i-found-this-powershell-function-now-what-do-i-do-part-2.aspx" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/14/i-found-this-powershell-function-now-what-do-i-do-part-3.aspx" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? Part 3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What do I do with a module I find?&lt;/h2&gt;
&lt;p&gt;Let us suppose that I find a module such as the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc" target="_blank"&gt;Windows Update PowerShell Module&lt;/a&gt; in the Scripting Guys Script Repository. What do I do with it? Well, the first thing I need to do is to download and to install the module. But this is where things are actually a bit confusing. This is because I can put the module anywhere I want to put it. One of the great things about Windows PowerShell modules is that no installer is required. Most modules, in fact, use a simple copy and paste type of installation (the so-called XCOPY deployment, but you do not need to use XCOPY if you do not wish to do so).&lt;/p&gt;
&lt;h2&gt;Where do I put the module?&lt;/h2&gt;
&lt;p&gt;There are two places I can put modules so that Windows PowerShell will automatically recognize them, and will automatically import them. These locations are stored in the &lt;strong&gt;PSModulePath &lt;/strong&gt;environmental variable&lt;em&gt;. &lt;/em&gt;From a basic categorization standpoint, one is in my profile/home directory, and the other one is in System32. This output on my computer is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; $env:PSModulePath -split &amp;quot;;&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C:\Users\ed.IAMMRED\Documents\WindowsPowerShell\Modules&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\&lt;/p&gt;
&lt;p&gt;It requires admin rights to copy something into the System32 folder, and that is where people sometimes place modules that require admin rights. The problem with this location is that when Windows undergoes servicing, it remotes items from the system folders that it does not know about. This means that your admin&lt;em&gt; &lt;/em&gt;type of modules can easily become deleted the next time you run Windows update or apply a service pack.&lt;/p&gt;
&lt;p&gt;The problem with storing all modules in my profile/home directory location occurs if I am running as a normal user, and then I need to elevate to an account with admin rights so I can run a module that requires admin rights. My profile/home directory is now a NEW location because I am running as a different user. This makes it painful to navigate back to the old user profile location to launch the module manually.&lt;/p&gt;
&lt;p&gt;The answer is simple. Modify the &lt;strong&gt;$env:PSModulePath&lt;/strong&gt; location to include an additional folder&amp;mdash;either one on a network, or a folder in an easily accessible location. For example, I have a central data&lt;em&gt; &lt;/em&gt;folder that I use to simplify backups (an XCOPY backup, so to speak). I could easily create a central modules folder that is accessible for all users on the computer. This technique is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; $env:PSModulePath = $env:PSModulePath + &amp;#39;;c:\data\modules&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; $env:PSModulePath -split &amp;quot;;&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C:\Users\ed.IAMMRED\Documents\WindowsPowerShell\Modules&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C:\Windows\system32\WindowsPowerShell\v1.0\Modules\&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;c:\data\modules&lt;/p&gt;
&lt;h2&gt;How do I put the module in its location?&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s go back to the &lt;em&gt;Windows Update PowerShell Module &lt;/em&gt;from the Scripting Guys Script Repository. It is contained in a file called PSWindowsUpdate.zip. I click the PSWindowsUpdate.zip file in the Script Repository, and after I agree to the terms of use, Internet Explorer asks if I want to Open, Save, or Cancel my action. This is shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5736.hsg_2D00_5_2D00_15_2D00_13_2D00_01.png"&gt;&lt;img title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5736.hsg_2D00_5_2D00_15_2D00_13_2D00_01.png" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If I select Open, the zipped file opens revealing a subfolder as shown here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2677.hsg_2D00_5_2D00_15_2D00_13_2D00_02.png"&gt;&lt;img title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/2677.hsg_2D00_5_2D00_15_2D00_13_2D00_02.png" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cool, it seems that all I need to do is to open my module directory and drag the folder from the zipped folder to my module home directory. The problem if I do this is the files in the folder will all be blocked.&amp;nbsp; This is shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4718.hsg_2D00_5_2D00_15_2D00_13_2D00_03.png"&gt;&lt;img title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/350x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4718.hsg_2D00_5_2D00_15_2D00_13_2D00_03.png" alt="Image of menu" width="350" height="480" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I can use Windows PowerShell&amp;nbsp;3.0 to unblock the files, but it is easier to unblock the files before installation. To do this, save the .zip file, then right-click it to unblock the file prior to extraction. In this way, all the files contained therein are unblocked. However, if I forget to do this, I can use a command such as the following to unblock the files:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED\Documents\WindowsPowerShell\Modules&amp;gt; gci .\PSWindowsUpdate -Re&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;curse | Unblock-File&lt;/p&gt;
&lt;p&gt;After I copy the unzipped and unblocked Windows PowerShell module files to the module directory, I can import the module and use the cmdlets. Because I am dealing with Windows update, the Windows PowerShell console needs to be elevated. The following error appears if the Windows PowerShell console is not elevated.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0181.hsg_2D00_5_2D00_15_2D00_13_2D00_04.png"&gt;&lt;img title="Image of error message" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0181.hsg_2D00_5_2D00_15_2D00_13_2D00_04.png" alt="Image of error message" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After I elevate Windows PowerShell, I use the &lt;strong&gt;Import-Module&lt;/strong&gt; cmdlet to import the module, and I use the &lt;strong&gt;Get-Command&lt;/strong&gt; cmdlet to see what commands are exposed by the module. This is shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6014.hsg_2D00_5_2D00_15_2D00_13_2D00_05.png"&gt;&lt;img title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6014.hsg_2D00_5_2D00_15_2D00_13_2D00_05.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now that I see the commands, I can use them just like any other Windows PowerShell command from any other module. So I can check to see what updates are available via the &lt;strong&gt;Get-WUList&lt;/strong&gt; cmdlet (function) as shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-WUList&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;ComputerName Status KB&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;Size Title&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;------------ ------ --&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ---- -----&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;EDLT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ---H-- KB2694771&amp;nbsp;&amp;nbsp; 5 MB Bing Desktop v1.2&lt;/p&gt;
&lt;p&gt;To install an update, I use the &lt;strong&gt;Get-WUInstall&lt;/strong&gt; function, and to hide an update I use the &lt;strong&gt;Hide-WUUpdate&lt;/strong&gt; command. Pipeline support is available.&lt;/p&gt;
&lt;p&gt;I can even check to see if a reboot is required as shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-WURebootStatus&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Reboot is not Required.&lt;/p&gt;
&lt;p&gt;SH, that is all there is to using a Windows PowerShell module.&amp;nbsp; Join me tomorrow when I will reveal the 2013 Scripting Games Event 4.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3572613" width="1" height="1" alt="" /&gt;</description></item><item><title>I Found this PowerShell Function—Now What Do I Do? Part 3</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/14/i-found-this-powershell-function-now-what-do-i-do-part-3.aspx</link><pubDate>Tue, 14 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23459</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, talks about combining functions into a single function file, and using them in scripts.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This morning is sort of mellow. It seems as if the clouds are touching the ground, and all sound is suppressed by a thick cloth batten. After seemingly weeks of rain, it is nice to have a not so wet day. I am on the lanai sitting in our porch swing reading my email via Outlook Web Access on my Surface RT. I love the long battery life and the portability of this device, and the fact that it has Windows PowerShell makes it even better.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&amp;nbsp;&amp;nbsp;&lt;/strong&gt;This is the third part of a multipart series about using Windows PowerShell functions and modules. Prior to reading this blog, you should read the previous posts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/08/i-found-this-powershell-function-now-what-do-i-do.aspx" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? Part 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/13/i-found-this-powershell-function-now-what-do-i-do-part-2.aspx" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? Part 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;em&gt;&amp;nbsp;&lt;/em&gt;If one function is cool, then two are even better&lt;/h2&gt;
&lt;p&gt;Yesterday in Part 2, I talked about dot sourcing a script that contains a function into the Windows PowerShell console so I could use the function just like it was a cmdlet. Today I want to expand on that idea just a bit by including two functions in a script file. The two functions use WMI to create a similar output to standard CIM functions in Windows&amp;nbsp;8. The equilivant functions in Windows&amp;nbsp;8 are &lt;strong&gt;Get-Volume&lt;/strong&gt; and &lt;strong&gt;Get-NetAdapter&lt;/strong&gt;. Here is the content of the two WMI functions:&lt;/p&gt;
&lt;h3 style="padding-left:30px;"&gt;TwoWmiFunctions.ps1&lt;/h3&gt;
&lt;p style="padding-left:30px;"&gt;Function Get-Volume&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Param($cn = $env:computername)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Get-WmiObject -class win32_volume -ComputerName $cn|&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Select-Object driveletter, @{LABEL=&amp;#39;FileSystemLabel&amp;#39;;EXPRESSION={$_.label}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; filesystem,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; @{LABEL=&amp;quot;Size&amp;quot;;EXPRESSION={&amp;quot;{0:N2} Gigabytes&amp;quot; -f ($_.capacity/1GB) }},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; @{LABEL=&amp;quot;SizeRemaining&amp;quot;;EXPRESSION={&amp;quot;{0:N2} Gigabytes&amp;quot; -f ($_.freespace/1GB) }}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;} #end function Get-Volume&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Get-NetAdapter&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Param($cn = $env:computername)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Get-WmiObject win32_networkadapter |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; Where-Object {$_.netconnectionstatus} |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Select-Object name,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{LABEL=&amp;#39;InterfaceDescription&amp;#39;;EXPRESSION={$_.Description}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{LABEL=&amp;#39;ifIndex&amp;#39;;EXPRESSION={$_.Index}},&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @{LABEL=&amp;#39;Status&amp;#39;;EXPRESSION={&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If($_.netconnectionstatus -eq 2){&amp;quot;not present&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If($_.netconnectionstatus -eq 4){&amp;quot;up&amp;quot;}}}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;} # end function get-NetAdapter&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:12px;"&gt;For ease of use, I have uploaded these functions to the Scripting Guys Script Repository: &lt;/span&gt;&lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Two-WMI-Functions-94c31b5f" target="_blank"&gt;Two WMI Functions&lt;/a&gt;&lt;span style="font-size:12px;"&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Using the function script by dot sourcing it&lt;/h2&gt;
&lt;p&gt;To dot source the script that contains the two functions, all I need to do is to place a period (dot) at the beginning of the console line, and then use the path to the script that contains the functions. I can then use the functions directly. This is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;.&lt;/strong&gt; C:\fso\TwoWmiFunctions.ps1&lt;/p&gt;
&lt;p&gt;The following image shows dot sourcing the script that contains the two functions and then using the two functions.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0458.hsg_2D00_5_2D00_14_2D00_13_2D00_01.png"&gt;&lt;img title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0458.hsg_2D00_5_2D00_14_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Dot source to interop between Windows versions&lt;/h2&gt;
&lt;p&gt;Lots of people are migrating to Windows&amp;nbsp;8 on their desktops; but unfortunately for many network administrators, they are forced to interop between Windows&amp;nbsp;8 and other versions of Windows. One of the things that is great about Windows&amp;nbsp;8 (and Windows Server&amp;nbsp;2012 for that matter) are the many CIM functions that wrap WMI classes. These are convenient and easy to use. However, for down-level systems, I still need to use the WMI classes. To avoid really cluttering up a script with a bunch of WMI code, I can use dot sourcing to handle the transition period. Here is an example of how that might work:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;if(gcm get-volume){Get-Volume} ELSE {. C:\fso\TwoWmiFunctions.ps1; Get-Volume}&lt;/p&gt;
&lt;p&gt;So all I need to do is to use &lt;strong&gt;Get-Command&lt;/strong&gt; to see if the &lt;strong&gt;Get-Volume&lt;/strong&gt; function (available in Windows&amp;nbsp;8) exists. If it does, I call the &lt;strong&gt;Get-Volume&lt;/strong&gt; command. If the &lt;strong&gt;Get-Volume&lt;/strong&gt; function is not available (because the version of Windows is older than Windows&amp;nbsp;8), I dot source my TwoWMIFunctions.ps1 script that contains my two functions, and then I call &lt;strong&gt;Get-Volume&lt;/strong&gt; from the dot-sourced script. This makes for a nice transitional bit of code.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt; &amp;nbsp;When you create this sort of transitional&lt;em&gt; &lt;/em&gt;function, ensure that the property names are the same. In this way, using one function or the other will also be the same. In my example TwoWmiFunctions.ps1 script, I had to rename several WMI class property names for compatibility.&lt;/p&gt;
&lt;p&gt;In the following image, I use the dot-source technique to bring in the script that contains the compatibility functions.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8233.hsg_2D00_5_2D00_14_2D00_13_2D00_02.png"&gt;&lt;img title="Image of command" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8233.hsg_2D00_5_2D00_14_2D00_13_2D00_02.png" alt="Image of command" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now What Do I Do? Week will continue tomorrow when I will talk about using a Windows PowerShell module. It is really cool, and you do not want to miss it.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3572371" width="1" height="1" alt="" /&gt;</description></item><item><title>I Found this PowerShell Function—Now What Do I Do? Part 2</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/13/i-found-this-powershell-function-now-what-do-i-do-part-2.aspx</link><pubDate>Mon, 13 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23430</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, continues his discussion about what to do with a Windows PowerShell function.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Last week I did not get a chance to finish answering a question from JB about how to use a Windows PowerShell function.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt; &amp;nbsp;&amp;nbsp;This is the second part of a multipart series about using Windows PowerShell functions and modules. You should read the first blog post, &lt;a href="http://blogs.technet.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;WeblogID=7618&amp;amp;WeblogPostID=3570211" target="_blank"&gt;I Found this PowerShell Function&amp;mdash;Now What Do I Do? &amp;ndash; Part 1&lt;/a&gt; prior to reading this post.&lt;/p&gt;
&lt;h2&gt;Functions promote code reuse&lt;/h2&gt;
&lt;p&gt;In the first installment in this series about using functions, I talked about the more traditional technique of copying and pasting the function directly into a script. This works well if you want to write a script. But one of the powerful things about Windows PowerShell is that I do not have to write a script. In fact, the great thing about Andy Schneider&amp;rsquo;s &lt;strong&gt;Set-ScreenResolution&lt;/strong&gt; function is that he wrote it as a function.&lt;/p&gt;
&lt;h3&gt;Top ten Windows PowerShell function best practices&lt;/h3&gt;
&lt;p&gt;Of course, being able to reuse the code depends on a well written function. Here is my top ten list of Windows PowerShell function best practices.&lt;/p&gt;
&lt;p&gt;A function should:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use the standard Verb-Noun naming convention.&lt;/li&gt;
&lt;li&gt;Do one thing and do it well.&lt;/li&gt;
&lt;li&gt;Return an object.&lt;/li&gt;
&lt;li&gt;Incorporate comment-based Help.&lt;/li&gt;
&lt;li&gt;Expose parameters instead of using hard-coded values.&lt;/li&gt;
&lt;li&gt;Accept piped input if it makes sense for the use-case scenario.&lt;/li&gt;
&lt;li&gt;Run and return default information if it makes sense for the use-case scenario (instead of requiring input, or returning an error when it is run without parameters).&lt;/li&gt;
&lt;li&gt;Offer parameter aliases for common parameters (for example, CN for &lt;strong&gt;ComputerName&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Name parameters in accordance with standard Windows PowerShell cmdlets (for example &lt;strong&gt;ComputerName&lt;/strong&gt; instead of &lt;em&gt;server, laptop, &lt;/em&gt;or &lt;em&gt;machine&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Use parameter validation techniques to limit user input.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt; &amp;nbsp;&amp;nbsp;For more information about Windows PowerShell functions, see &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/functions/" target="_blank"&gt;this collection of Hey, Scripting Guy! Blog posts&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Save the function into a .ps1 script file&lt;/h2&gt;
&lt;p&gt;So suppose you find a well-written function and you want to be able to use it in the Windows PowerShell console. A well-written Windows PowerShell function will, in fact, act and behave like a Windows PowerShell cmdlet. So bringing it into the Windows PowerShell console will enhance the interactive use experience of Windows PowerShell.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s go back to the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/2a631d72-206d-4036-a3f2-2e150f297515" target="_blank"&gt;Set-ScreenResolution function&lt;/a&gt; that I used last week (written by Andy Schneider). I go to the Scripting Guys Script Repository, find the &lt;strong&gt;Set-ScreenResolution&lt;/strong&gt; script and copy it to the clipboard. Now, I paste it into the Windows PowerShell ISE, and I save it with a file name like Set-ScreenResolutionFunction.ps1. Here is the script:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7103.hsg_2D00_5_2D00_13_2D00_13_2D00_01.png"&gt;&lt;img title="Image of script" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7103.hsg_2D00_5_2D00_13_2D00_13_2D00_01.png" alt="Image of script" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Dot source the script file&lt;/h2&gt;
&lt;p&gt;When I have the function stored in a script file, I can use the function in my Windows PowerShell console, or even in another Windows PowerShell script. The key to doing this is to store the script file that contains the function in an easily locatable folder. For me, that folder is off the root of drive C (C:\fso). I have used this folder for my scratch folder for over a decade.&lt;/p&gt;
&lt;h3&gt;Keys to success for using dot sourcing&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Save the function into a script file with a similar name to the function.&lt;/li&gt;
&lt;li&gt;Save the script file that contains the function in an easily accessed location.&lt;/li&gt;
&lt;li&gt;Make sure that the script file contains only the function, and no &amp;ldquo;entry code&amp;rdquo; that will automatically launch the function.&lt;/li&gt;
&lt;li&gt;Dot source functions into scripts that may have code that changes for ease of update.&lt;/li&gt;
&lt;li&gt;Use the syntax: period, space, path to script (&amp;lt;.&amp;gt;&amp;lt;space&amp;gt;&amp;lt;path&amp;gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To dot source the Set-ScreenResolutionFunction.ps1 script into the Windows PowerShell console, I use the syntax shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;.&lt;/strong&gt; C:\fso\Set-ScreenResolutionFunction.ps1&lt;/p&gt;
&lt;p&gt;To call the &lt;strong&gt;Set-ScreenResolution&lt;/strong&gt; function, I type the function name, just like I would do with a regular Windows PowerShell cmdlet. In fact, tab expansion even works. This is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-ScreenResolution -Width 800 -Height 600&lt;/p&gt;
&lt;p&gt;This technique is shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3833.hsg_2D00_5_2D00_13_2D00_13_2D00_02.png"&gt;&lt;img title="Image of script" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3833.hsg_2D00_5_2D00_13_2D00_13_2D00_02.png" alt="Image of script" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I can also use this technique in the Windows PowerShell ISE. In the image that follows, I dot source the Set-ScreenResolutionFunction.ps1 script into my script.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:12px;"&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7416.hsg_2D00_5_2D00_13_2D00_13_2D00_03.png"&gt;&lt;img title="Image of script" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7416.hsg_2D00_5_2D00_13_2D00_13_2D00_03.png" alt="Image of script" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Well, that is about all for now. Now What Do I Do? Week will continue tomorrow when I will continue to talk about using Windows PowerShell functions.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3570668" width="1" height="1" alt="" /&gt;</description></item><item><title>Named Arguments for PowerShell Functions: Best Practices</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/11/named-arguments-for-powershell-functions-best-practices.aspx</link><pubDate>Thu, 11 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22719</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, talks about using named arguments in Windows PowerShell functions.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. If I go to the trouble of writing a Windows PowerShell script, I generally do not use unnamed arguments (such as &lt;strong&gt;$args&lt;/strong&gt; as I illustrated yesterday in &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/10/accepting-arguments-for-powershell-functions-best-practices.aspx" target="_blank"&gt;Accepting Arguments for PowerShell Functions: Best Practices&lt;/a&gt;). Instead I create named arguments for my functions. It is just so much more powerful, and so much more flexible. Besides, I can still pass values appositionally in an unnamed fashion if I wish to do so.&lt;/p&gt;
&lt;h2&gt;Create a named argument in five easy steps&lt;/h2&gt;
&lt;p&gt;In yesterday&amp;#39;s blog,&amp;nbsp;I said that there are only three requirements to create a function in Windows PowerShell:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Function&lt;/strong&gt; keyword&lt;/li&gt;
&lt;li&gt;The name of the function&lt;/li&gt;
&lt;li&gt;A script block&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To create a named argument in a Windows PowerShell function, I need only two &amp;nbsp;additional things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Param&lt;/strong&gt; keyword&lt;/li&gt;
&lt;li&gt;A variable to hold the argument inside a pair of parentheses&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following script illustrates this technique:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function myfunction&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Param($myargument)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;quot;This value of `$myargument is $myargument&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;To use &lt;strong style="font-size:12px;"&gt;MyFunction&lt;/strong&gt;, I first have to run the script. This loads the function into memory and makes it available via the function PSDrive. Because I have not saved the script containing the function, when I run the script, it appears in the Console pane below the Script pane. When the script runs, the Windows PowerShell prompt returns, and I can call the function by typing the name of the function. I then supply a value for the argument by typing it. This is shown in the image that follows.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4617.hsg_2D00_4_2D00_11_2D00_13_2D00_01.png"&gt;&lt;img style="border:0px currentColor;" title="Image of script" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4617.hsg_2D00_4_2D00_11_2D00_13_2D00_01.png" alt="Image of script" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Keep in mind that tab expansion works here. So I do not have to type the entire name of &lt;strong&gt;MyFunction&lt;/strong&gt;, nor do I need to type the complete name of &lt;strong&gt;MyArgument&lt;/strong&gt;&lt;em&gt;. &lt;/em&gt;In fact, I only had to type &lt;strong&gt;my&lt;/strong&gt; and press the Tab key to get the &lt;strong&gt;MyFunction&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;command onto the command line. When I type the hyphen (&lt;strong&gt;&amp;ndash;&lt;/strong&gt;) for the named argument (parameter) a pop-up list appears, as shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6153.hsg_2D00_4_2D00_11_2D00_13_2D00_02.png"&gt;&lt;img style="border:0px currentColor;" title="Image of script" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6153.hsg_2D00_4_2D00_11_2D00_13_2D00_02.png" alt="Image of script" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The advantage of using named arguments (parameters) is that I do not need to name the parameter if I do not want to. I can use it as a positional parameter. In this manner, it behaves like an unnamed argument (&lt;strong&gt;$args&lt;/strong&gt;). This is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;PS C:\&amp;gt; myfunction &amp;quot;this is a&amp;nbsp; string&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;This value of $myargument is this is a&amp;nbsp; string&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;Because creating named parameters in Windows PowerShell is so easy, and because using the &lt;strong style="font-size:12px;"&gt;Param&lt;/strong&gt;&lt;em style="font-size:12px;"&gt; &lt;/em&gt;keyword is the entry into the world of advanced functions, I never use &lt;strong style="font-size:12px;"&gt;$args&lt;/strong&gt; in a Windows PowerShell script. Because it is an automatic variable that becomes available in certain circumstances, using &lt;strong style="font-size:12px;"&gt;$args&lt;/strong&gt; is more difficult to understand because nothing has been created in the script. It is just there.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;On the other hand, because the &lt;strong&gt;Param&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;block is declared and available for inspection, it makes sense, and is easier to understand. If I begin with a script that uses &lt;strong&gt;$args&lt;/strong&gt; and I later decide that I need to add functionality, I will have to add a &lt;strong&gt;Param&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;block to get access to advanced features.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Join me tomorrow when I will welcome guest bloggers Yuri Diogenes and Tom Shinder back with the second installment in their security series. If you want to refresh your memory, check out their first installment in the series:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/29/security-series-using-powershell-to-protect-your-private-cloud-infrastructure.aspx" target="_blank"&gt;Security Series: Using PowerShell to Protect Your Private Cloud Infrastructure&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3564417" width="1" height="1" alt="" /&gt;</description></item><item><title>Accepting Arguments for PowerShell Functions: Best Practices</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/10/accepting-arguments-for-powershell-functions-best-practices.aspx</link><pubDate>Wed, 10 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22677</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, talks about the best practices surrounding accepting input for a Windows PowerShell function.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. April in the Carolina&amp;rsquo;s is a special time. In fact, it is my favorite time of the year here. This is because the weather is invariably mild. This week, it has been sunny, moderate temperature, mild humidity, and clear skies. The Scripting Neighbors tell me it is perfect golf weather. It is also perfect &amp;ldquo;sit on the lanai and write Windows PowerShell scripts&amp;rdquo; weather. Although I have never had much luck with &lt;a href="http://quoteinvestigator.com/2011/08/01/golf-small-hole/" target="_blank"&gt;putting a small ball into an even smaller hole with equipment not designed for that purpose&lt;/a&gt;, I can compute the trajectory, and force necessary to accomplish the task with a one-line Windows PowerShell command.&lt;/p&gt;
&lt;h2&gt;Passing a value to a Windows PowerShell function&lt;/h2&gt;
&lt;p&gt;If I have a function that I need to pass a value to, I can use the automatic variable &lt;strong&gt;$args&lt;/strong&gt;. This makes the function easy to write and easy to use. The following function uses three steps to create the function. It calls the function keyword, provides a name, and creates a script block that contains code.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function myfunction&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;quot;the computer name is $args&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;In the Windows PowerShell ISE, I run the script (I do not have to save the code into a .ps1 file), and the function loads into memory. I can then call the function directly in the execution pane (the dark blue box that follows) and pass a value to the function when I call it. The command line is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;myfunction $env:COMPUTERNAME&lt;/p&gt;
&lt;p&gt;The image that follows illustrates creating the function, using &lt;strong&gt;$args&lt;/strong&gt; in the script block, and calling the function from the execution pane.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0880.hsg_2D00_4_2D00_10_2D00_13_2D00_01.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0880.hsg_2D00_4_2D00_10_2D00_13_2D00_01.png" alt="Image of command" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Anything I add following the name of the function populates the &lt;strong&gt;$args&lt;/strong&gt; variable. In the command that follows, I pass the value &lt;strong&gt;mred&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;to the function. Interestingly, I do not have to supply quotation marks when passing the value.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; myfunction mred&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;the computer name is mred&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; myfunction &amp;quot;mred&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;the computer name is mred&lt;/p&gt;
&lt;p&gt;I can also use the output from the &lt;strong&gt;Get-WmiObject&lt;/strong&gt; cmdlet for input. Therefore, the following code uses WMI to return the computer name and to pass it to the &lt;strong&gt;MyFunction&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;function.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; myfunction (gwmi win32_computersystem).name&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;the computer name is EDLT&lt;/p&gt;
&lt;p&gt;One thing to keep in mind, is that when I use the &lt;strong&gt;$args&lt;/strong&gt; automatic variable as illustrated in the &lt;strong&gt;MyFunction&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;function, I cannot pipe input to the function. This can actually be a bit of a problem, because it could be really hard to troubleshoot due to the fact that no error arises. This is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; $env:COMPUTERNAME | myfunction&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;the computer name is&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If I want to pipel input to my function, I use the &lt;strong&gt;$input&lt;/strong&gt; automatic variable. The only change that is required to my function is to change &lt;strong&gt;$args&lt;/strong&gt; to &lt;strong&gt;$input&lt;/strong&gt;, as shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function afunction&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;quot;the computer name is $input&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;I then pipe the input to the function by using the command shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; $env:COMPUTERNAME | afunction&lt;/p&gt;
&lt;p&gt;If I attempt to provide positional input to the function instead of piping the input, no error arises, but no value passes either.&lt;/p&gt;
&lt;p&gt;The command and associated output are shown in the image here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8880.hsg_2D00_4_2D00_10_2D00_13_2D00_02.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8880.hsg_2D00_4_2D00_10_2D00_13_2D00_02.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Best Practices Week will continue tomorrow when I will talk some more about Windows PowerShell functions.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3564373" width="1" height="1" alt="" /&gt;</description></item><item><title>Using PowerShell Functions: Best Practices</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/09/using-powershell-functions-best-practices.aspx</link><pubDate>Tue, 09 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22637</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong style="font-size:12px;"&gt;Summary&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;: Microsoft Scripting Guy, Ed Wilson, talks about some best practices for using Windows PowerShell functions.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;A simple function&lt;/h2&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Function&lt;/strong&gt; keyword&lt;/li&gt;
&lt;li&gt;The name of the function&lt;/li&gt;
&lt;li&gt;A script block&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is it. This means that the following is a legitimate function:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function a {}&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; function a {}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; gps | a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; dir function:a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;CommandType&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ModuleName&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-----------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Adding functionality to the function&lt;/h2&gt;
&lt;p&gt;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 &lt;strong&gt;Select-Object&lt;/strong&gt; cmdlet and pick the last three entries in the data. The following script illustrates this technique (&lt;strong&gt;gps&lt;/strong&gt; is an alias for the &lt;strong&gt;Get-Process&lt;/strong&gt; cmdlet, and &lt;strong&gt;select&lt;/strong&gt; is an alias for the &lt;strong&gt;Select-Object&lt;/strong&gt; cmdlet).&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; gps | select -Last 3&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Handles&amp;nbsp; NPM(K)&amp;nbsp;&amp;nbsp;&amp;nbsp; PM(K)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WS(K) VM(M)&amp;nbsp;&amp;nbsp; CPU(s)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Id ProcessName&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-------&amp;nbsp; ------&amp;nbsp;&amp;nbsp;&amp;nbsp; -----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----- -----&amp;nbsp;&amp;nbsp; ------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- -----------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 207&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1340&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3064&amp;nbsp;&amp;nbsp;&amp;nbsp; 40&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1848 WUDFHost&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 405&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3636&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10012&amp;nbsp;&amp;nbsp;&amp;nbsp; 95&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1904 WUDFHost&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 214&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3336&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7852&amp;nbsp;&amp;nbsp;&amp;nbsp; 89&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2880 ZeroConfigService&lt;/p&gt;
&lt;p&gt;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 &lt;strong&gt;Select-Object&lt;/strong&gt; cmdlet and chooses the last three items, I can put this into a function that accepts pipelined input and outputs the last three items.&lt;/p&gt;
&lt;p&gt;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 &amp;ldquo;&lt;strong&gt;l&lt;/strong&gt;&amp;rdquo; (as in lower case letter &amp;ldquo;L&amp;rdquo;). Inside the script block, I use the automatic variable &lt;strong&gt;$input&lt;/strong&gt;, which is the input piped into a function.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;$input&lt;/strong&gt; variable only exists inside the context of a function, and only for the time the function is called. If I check the value of &lt;strong&gt;$input&lt;/strong&gt; outside of the function, it is empty. So what I pass to the function is then piped to the &lt;strong&gt;Select-Object&lt;/strong&gt; cmdlet, and the last three items are returned from the function. The function is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function l {$input | select -Last 3}&lt;/p&gt;
&lt;p&gt;To use the function, I pipe results to the function. The following script selects the last three processes.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; gps | l&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Handles&amp;nbsp; NPM(K)&amp;nbsp;&amp;nbsp;&amp;nbsp; PM(K)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WS(K) VM(M)&amp;nbsp;&amp;nbsp; CPU(s)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Id ProcessName&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-------&amp;nbsp; ------&amp;nbsp;&amp;nbsp;&amp;nbsp; -----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ----- -----&amp;nbsp;&amp;nbsp; ------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- -----------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 207&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1340&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3064&amp;nbsp;&amp;nbsp;&amp;nbsp; 40&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1848 WUDFHost&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 405&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3636&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10012&amp;nbsp;&amp;nbsp;&amp;nbsp; 95&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1904 WUDFHost&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 214&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3336&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7852&amp;nbsp;&amp;nbsp;&amp;nbsp; 89&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2880 ZeroConfigService&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:12px;"&gt;I can select the last three services (&lt;/span&gt;&lt;strong style="font-size:12px;"&gt;gsv&lt;/strong&gt;&lt;span style="font-size:12px;"&gt; is an alias) as shown here.&lt;/span&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;gsv | l&lt;/p&gt;
&lt;p&gt;Or maybe I want to look at the last three entries in the event log as shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-EventLog application | l&lt;/p&gt;
&lt;p&gt;I can even use the &lt;strong&gt;range&lt;/strong&gt; operator and select the last three numbers. This command is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;1..10 | l&lt;/p&gt;
&lt;p&gt;These commands and their associated output are shown in the following image.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5417.hsg_2D00_4_2D00_9_2D00_13_2D00_01.png"&gt;&lt;img style="border:0px currentColor;" title="Image of command output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5417.hsg_2D00_4_2D00_9_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Best Practices Week will continue tomorrow when I will continue talking about functions.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ed Wilson, Microsoft Scripting Guy&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3563607" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Easily Add Whatif Support to Your PowerShell Functions</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/07/08/weekend-scripter-easily-add-whatif-support-to-your-powershell-functions.aspx</link><pubDate>Sun, 08 Jul 2012 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:17545</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Microsoft Scripting Guy, Ed Wilson, shows how to easily add &lt;i&gt;whatif&lt;/i&gt; support to your Windows PowerShell functions.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. I love demoing Windows PowerShell to people who have never seen it&amp;mdash;and believe it or not, there are still IT Pros who have not seen or used Windows PowerShell. Most people have heard of it by now (if they are in the business), but there is still a surprisingly large number of people who do not use Windows PowerShell. One of the features that generally gets ooohs and ahhhhs (and at times even applause) is the &lt;i&gt;whatif &lt;/i&gt;parameter.&lt;/p&gt;
&lt;p&gt;I generally tell people that they no longer have to run a command to see what it will do. Often I ask for a show of hands to see how many people have run a command and they did not know what it would do. Not surprisingly, the number of hands that goes up is large. Scarier, is when I ask who has run a command on a production system, and they were not certain what it would do. This is not a sign of carelessness, but rather a sign of desperation&amp;mdash;the server is down, you go to TechNet, and it says to fix the problem, run this cryptic command. You do it and hope for the best. But what if there was a type-o on that page? With Windows PowerShell, this is no longer a concern because you can use &lt;i&gt;whatif.&lt;/i&gt;&lt;/p&gt;
&lt;h2&gt;Adding support for the whatif parameter&lt;/h2&gt;
&lt;p&gt;One of the great features of Windows PowerShell is using the &lt;i&gt;whatif &lt;/i&gt;parameter on cmdlets that change the system state, such as the &lt;b&gt;Stop-Service&lt;/b&gt; or the &lt;b&gt;Stop-Process&lt;/b&gt; cmdlets. In fact, by consistently utilizing the &lt;i&gt;whatif &lt;/i&gt;switched parameter, it is possible to avoid many inadvertent system outages. As a Windows PowerShell best practice, you should also implement the &lt;i&gt;whatif &lt;/i&gt;parameter in your advanced functions. In the past, this meant creating special parameters, and adding lots of extra code to handle the output. Now, it requires a single line of code.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;b&gt;Note&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;[cmdletbinding()]&lt;/b&gt; appears with empty parentheses because there are other things, such as &lt;b&gt;SupportsShouldProcess&lt;/b&gt;, that can appear between the parentheses.&lt;/p&gt;
&lt;p&gt;The following function illustrates setting &lt;b&gt;SupportsShouldProcess &lt;/b&gt;to True inside the parentheses of the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute.&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;[cmdletbinding(SupportsShouldProcess=$True)]&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($path)&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;md $path&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;Now when you call the function with the &lt;i&gt;whatif &lt;/i&gt;switched parameter, a message appears in the output detailing the exact behavior the cmdlet takes when run without the &lt;i&gt;whatif &lt;/i&gt;parameter. This is shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5102.Wes_2D00_7_2D00_8_2D00_12_2D00_1.png"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5102.Wes_2D00_7_2D00_8_2D00_12_2D00_1.png" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3507237" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Cmdletbinding Attribute Simplifies PowerShell Functions</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/07/07/weekend-scripter-cmdletbinding-attribute-simplifies-powershell-functions.aspx</link><pubDate>Sat, 07 Jul 2012 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:17541</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;b&gt;Summary&lt;/b&gt;: Microsoft Scripting Guy, Ed Wilson, talks about using the &lt;strong&gt;cmdletbinding&lt;/strong&gt; attribute to simplify Windows PowerShell functions.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This morning I was sitting around playing with Windows PowerShell, and I realized that I had not written much about the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute. So here goes&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The first step in creating an advanced function is to add the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute. This single addition adds several capabilities such as additional parameter checking, and the ability to easily use the &lt;b&gt;Write-Verbose &lt;/b&gt;cmdlet.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To use the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute, you place the attribute in a square bracket attribute tag and include it in the first non-commented line in the function. In addition, the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute requires the use of &lt;b&gt;param&lt;/b&gt;&lt;i&gt; &lt;/i&gt;keyword. If your advanced function requires no parameters, you can use the keyword without specifying any parameters. This technique is shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When you have the basic outline of the advanced function, you can begin to fill in the blanks. For example, to use the &lt;b&gt;Write-Verbose&lt;/b&gt; cmdlet only requires adding the following command.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Write-Verbose &amp;quot;verbose stream&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Easy verbose messages&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When loaded, the function permits the use of the &lt;i&gt;verbose &lt;/i&gt;switched parameter. Use of this parameter causes each &lt;b&gt;Write-Verbose&lt;/b&gt; statement to write to the Windows PowerShell console output. When the function runs without the &lt;i&gt;verbose &lt;/i&gt;switch, no output displays from the &lt;i&gt;verbose&lt;/i&gt; stream.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The great thing about using &lt;b&gt;Write-Verbose&lt;/b&gt; is that detailed information (such as the progress in making remote connections, loading modules, and other operations that could cause a script to fail) outputs as events happen. This provides a built-in diagnostic mode for the advanced function with virtually no additional programing.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;Automatic parameter checks&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The default behavior for a Windows PowerShell function is that additional values specified to an unnamed argument are available in the automatic &lt;b&gt;$args&lt;/b&gt; variable. This behavior, although potentially useful, easily becomes a source of errors for a script. The following function illustrates this behavior.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;#[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($a)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;#$args&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When this function runs, any value supplied to the &lt;i&gt;&amp;ndash;a&lt;/i&gt; parameter appears in the output as shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function -a 1,2,3,4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;3&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;4&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;On the other hand, when you call the function, if you omit the first comma, no error generates, but the output displayed does not meet expectations. This is shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function -a 1 2,3,4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;1&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The remaining parameters appear in the automatic &lt;b&gt;$args&lt;/b&gt; variable. Placing the &lt;b&gt;$args&lt;/b&gt; variable in the function illustrates this. First, add the &lt;b&gt;$args&lt;/b&gt; automatic variable as shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;#[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($a)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$args&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now, when calling the function, whilst omitting the first comma, the following output appears.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function -a 1 2,3,4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;3&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;4&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Although interesting, you may not want this behavior. One way to correct it is to check the number of arguments that are supplied to the function. You can do this by monitoring the &lt;b&gt;count&lt;/b&gt; property of the &lt;b&gt;$args&lt;/b&gt; variable as shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;#[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($a)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$args.count&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When passing multiple arguments to the function, the value of the count property increases. In the output that is shown here, the first number 1, returns from the &lt;i&gt;&amp;ndash;a&lt;/i&gt; position. The number 3 is the count of extra arguments (that is, those not supplied for the named argument).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function 1 2 3 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;3&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;By using this feature, and checking the &lt;b&gt;count&lt;/b&gt;&lt;i&gt; &lt;/i&gt;property of &lt;b&gt;$args&lt;/b&gt;, one line of code prevents extra arguments coming to the function. This change is shown here:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;#[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($a,$b)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$b&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;if($args.count -gt 0) {Write-Error &amp;quot;unhandled arguments supplied&amp;quot;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When run, as shown in the following code, the first two parameters supplied are accepted for the &lt;i&gt;&amp;ndash;a&lt;/i&gt; and the &lt;i&gt;&amp;ndash;b&lt;/i&gt; parameters. The two remaining parameters go into the &lt;b&gt;$args&lt;/b&gt; automatic variable. This increases the &lt;b&gt;count&lt;/b&gt;&lt;i&gt; &lt;/i&gt;property of &lt;b&gt;$args&lt;/b&gt; to a value greater than 0, and therefore an error occurs.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function 1 2 3 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;2&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;my-function : unhandled arguments supplied&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;At line:1 char:12&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;+ my-function &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp; 1 2 3 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + CategoryInfo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : NotSpecified: (:) [Write-Error], WriteErrorException&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,my-&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; function&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The easiest way to identify unhandled parameters supplied to a Windows PowerShell function is to use the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute. One of the features of using the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute is that it generates an error when unhandled parameter values appear on the command line. The following function illustrates the &lt;b&gt;cmdletbinding&lt;/b&gt; attribute.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;function my-function&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;[cmdletbinding()]&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;Param($a,$b)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;$b&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When calling the above function with too many arguments, the following error appears:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;PS C:\Users\ed.IAMMRED&amp;gt; my-function 1 2 3 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;my-function : A positional parameter cannot be found that accepts argument &amp;#39;3&amp;#39;.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;At line:1 char:12&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;+ my-function &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;nbsp; 1 2 3 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + CategoryInfo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : InvalidArgument: (:) [my-function], ParameterBindingE&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; xception&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;/p&gt;
&lt;p class="CodeBlock" style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; + FullyQualifiedErrorId : PositionalParameterNotFound,my-function&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3507234" width="1" height="1" alt="" /&gt;</description></item><item><title>PowerShell Pie for Pi Day</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2012/03/14/powershell-pie-for-pi-day.aspx</link><pubDate>Wed, 14 Mar 2012 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:15322</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;b&gt;ummary&lt;/b&gt;: Use the built in pi value in an impromptu function to get the circumference of a circle by using Windows PowerShell.&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I are still pretty geeked out from the first ever &lt;a href="http://powershellgroup.org/content/powershell-saturday" target="_blank"&gt;Windows PowerShell Saturday&lt;/a&gt; that was held in Columbus Ohio. Add that today will be the third live meeting in the &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/03/06/windows-powershell-for-the-busy-admin.aspx" target="_blank"&gt;PowerShell Essentials for the Busy Admin&lt;/a&gt; series, and the week is pretty complete. But, as they say on late night television (at least in the United States), &amp;ldquo;Wait! There is more!&amp;rdquo; I completed writing all the events for the 2012 Scripting Games, and I emailed them off to the 20 guest commentators. I completed the 2012 Scripting Games quiz and got it sent off to the people who will turn it into an online quiz. And in just a few days, it will be International PowerShell User Group day! Now that ought to be enough to make any geek or geekette jump up and down with excitement.&lt;/p&gt;
&lt;h1&gt;How to get pi in PowerShell&lt;/h1&gt;
&lt;p&gt;I know I wrote a blog about not using the .NET Framework classes&amp;mdash;but I was talking about unless you need to do so. Well, the easy way to get access to pi is to use the .NET Framework &lt;b&gt;Math&lt;/b&gt;&lt;i&gt; &lt;/i&gt;class. Pi is available as a static property, which means it is always available. I know that pi is equal to 3.14, or 22/7, but that is about it. Beyond the first few digits, it starts to get fuzzy for me. But I do not need to remember it because I can use the static pi property from the &lt;b&gt;Math&lt;/b&gt;&lt;i&gt; &lt;/i&gt;class. The following example illustrates using the pi property from the &lt;b&gt;Math&lt;/b&gt;&lt;i&gt; &lt;/i&gt;class to obtain a more precise value than simply 3.14.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; [math]::pi&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;3.14159265358979&lt;/p&gt;
&lt;p&gt;The key to using a static property from a .NET Framework class is remembering to use the double colon symbol (&lt;b&gt;::&lt;/b&gt;). If you are wondering how I found this property, it is easy&amp;mdash;I used the &lt;b&gt;Get-Member &lt;/b&gt;cmdlet. This technique is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;[math] | Get-Member &amp;ndash;Static&lt;/p&gt;
&lt;p&gt;The command and the associated output are shown here.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7180.hsg_2D00_3_2D00_14_2D00_12_2D00_1.png"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7180.hsg_2D00_3_2D00_14_2D00_12_2D00_1.png" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Suppose I need to calculate the circumference of a circle. In fact, I do this quite often in my woodworking shop. I cut out a circle for a tabletop, and I want to add an edge band to the circle so that it does not display open-pored end grain. Well, I need to know the circumference of the circle so I know how long of a piece of wood to cut. I could use paper and pencil, and perform this calculation:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Circumference = 2&amp;pi;r&lt;/p&gt;
&lt;h1&gt;Creating an impromptu function that uses pi&lt;/h1&gt;
&lt;p&gt;One of the cool things I can do in Windows PowerShell is creating an impromptu function. I do not need to open the Windows PowerShell ISE, type out a long convoluted script containing a function, then save it and dot source it into my Windows PowerShell console. Instead, I can create the function on the fly and use it throughout my session.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;function get-circumference { Param($r)2*[math]::pi*$r }&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1780.hsg_2D00_3_2D00_14_2D00_12_2D00_2.png"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1780.hsg_2D00_3_2D00_14_2D00_12_2D00_2.png" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Instead of using the &lt;b&gt;Function&lt;/b&gt; keyword, I can also create the function directly on the function drive. To do this, I use the &lt;b&gt;New-Item &lt;/b&gt;cmdlet. The code to do this is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Item -path function:get-circumference -Value {Param($r)2*[math]::pi*$r}&lt;/p&gt;
&lt;p&gt;The code to create the &lt;b&gt;Get-Circumference&lt;/b&gt; function directly on the function drive and the associated output are shown in the image that follows.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3324.hsg_2D00_3_2D00_14_2D00_12_2D00_3.png"&gt;&lt;img src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3324.hsg_2D00_3_2D00_14_2D00_12_2D00_3.png" alt="Image of command output" title="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Well, that is about all there is to using pi to get the circumference of a circle. I need to get to work on prepping for &lt;a href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032508053&amp;amp;Culture=en-US" target="_blank"&gt;today&amp;rsquo;s live meeting&lt;/a&gt;. See you then. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook" target="_blank"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3486412" width="1" height="1" alt="" /&gt;</description></item><item><title>Use a PowerShell Function to Find Specific WMI Classes</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/10/22/use-a-powershell-function-to-find-specific-wmi-classes.aspx</link><pubDate>Sat, 22 Oct 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:12873</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; Use a Windows PowerShell function to find WMI classes with specific qualifiers.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. In &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2011/10/20/use-the-set-wmiinstance-powershell-cmdlet-to-ease-configuration.aspx"&gt;Thursday&amp;rsquo;s article&lt;/a&gt;, I talked about using the &lt;b&gt;Set-WmiInstance&lt;/b&gt; cmdlet to work with WMI classes. One of the parameters, the &lt;i&gt;class &lt;/i&gt;parameter, works with WMI singleton objects. Now, it is certainly possible to use WBEMTest to find singleton WMI classes. Such a WMI class is shown in the following figure in the WBEMTest utility.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5383.hsg_2D00_10_2D00_22_2D00_11_2D00_1.png"&gt;&lt;img title="Image of a WMI singleton class" alt="Image of a WMI singleton class" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5383.hsg_2D00_10_2D00_22_2D00_11_2D00_1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But with 1,085 WMI classes in Root\Cimv2, it is faster and more fun to use a WMI schema query. WMI schema queries are &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa393278(v=vs.85).aspx"&gt;mentioned on MSDN&lt;/a&gt;, but there are no Windows PowerShell examples. I decided I needed to write a Windows PowerShell function that would query the schema to find the singleton classes for which I was looking. In addition, there are other class qualifiers I was interested in seeing as well. For example, there is a &lt;b&gt;supportsupdate&lt;/b&gt;&lt;i&gt; &lt;/i&gt;qualifier that lets me know that I can use that class to make modifications to a computer. There are other qualifiers that are even more important: &lt;b&gt;abstract&lt;/b&gt; and &lt;b&gt;dynamic&lt;/b&gt;. As an IT pro, I want to query &lt;i&gt;dynamic &lt;/i&gt;WMI classes, and not the abstracts. For ease of use, I uploaded the script to the &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Get-WMI-Class-qualifiers-239970e7"&gt;Scripting Guys Script Repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I ended up writing a function I could use to find classes with specific qualifiers. As shown in the following figure, there are a few &lt;b&gt;singleton&lt;/b&gt;&lt;i&gt; &lt;/i&gt;WMI classes. I opened the function in the Windows PowerShell ISE, ran the script once to load the function into memory, and then I went to the command pane and typed the following command:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-WMIClassesWithQualifiers -qualifier singleton&lt;/p&gt;
&lt;p&gt;The command and associated output are shown in the following figure.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7120.hsg_2D00_10_2D00_22_2D00_11_2D00_2.png"&gt;&lt;img title="Image of command and associated output" alt="Image of command and associated output" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7120.hsg_2D00_10_2D00_22_2D00_11_2D00_2.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A WMI schema query queries the &lt;b&gt;meta_class&lt;/b&gt; WMI class. It uses the &lt;b&gt;isa&lt;/b&gt;&lt;i&gt; &lt;/i&gt;keyword to specify from which WMI class I want to return the schema information. That part is rather simple. The difficult part was getting the quotation marks placed in the right position to enable automatic querying. Here is the query line I derived:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$query = &amp;quot;select * from meta_class where __this isa &amp;quot;&amp;quot;$($class.name)&amp;quot;&amp;quot; &amp;quot;&lt;/p&gt;
&lt;p&gt;I am interested in the qualifiers; therefore, I choose only the name of the WMI class and the qualifiers. This line appears is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$a = gwmi -Query $query -Namespace $namespace |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; select -Property __class, qualifiers&lt;/p&gt;
&lt;p&gt;If the qualifiers contain the qualifier I am looking for, I return the WMI class name:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;if($a.qualifiers | % { $_ | ? { $_.name -match &amp;quot;$qualifier&amp;quot; }})&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { $a.__class }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The core portion of the script, with the aliases removed is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Param([string]$qualifier = &amp;quot;dynamic&amp;quot;,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; [string]$namespace = &amp;quot;root\cimv2&amp;quot;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;$classes = Get-WmiObject -list -namespace $namespace&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;foreach($class in $classes)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; $query = &amp;quot;Select * from meta_class where __this isa &amp;quot;&amp;quot;$($class.name)&amp;quot;&amp;quot; &amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; $a = Get-WmiObject -Query $query -Namespace $namespace |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; Select-Object -Property __class, qualifiers&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; if($a.qualifiers | ForEach-Object { $_ | Where-Object { $_.name -match &amp;quot;$qualifier&amp;quot; }})&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { $a.__class }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; } #end foreach $class&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Well, that is about it for today. I hope you enjoy the function, and have an awesome weekend.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3459745" width="1" height="1" alt="" /&gt;</description></item></channel></rss>