{"id":16761,"date":"2010-10-20T00:01:00","date_gmt":"2010-10-20T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/10\/20\/use-powershell-to-combine-multiple-commands-for-ease-of-use\/"},"modified":"2010-10-20T00:01:00","modified_gmt":"2010-10-20T00:01:00","slug":"use-powershell-to-combine-multiple-commands-for-ease-of-use","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-combine-multiple-commands-for-ease-of-use\/","title":{"rendered":"Use PowerShell to Combine Multiple Commands for Ease of Use"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p><strong>Summary<\/strong>: Learn how to use Windows PowerShell 2.0 to combine multiple commands into new custom functions and simplify your scripting.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" border=\"0\" align=\"left\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" height=\"34\" title=\"Hey, Scripting Guy! Question\" \/>Hey, Scripting Guy! I do a lot of work from the Windows PowerShell command line. In fact, I write very few scripts, but I run lots of commands. I would like to create a custom Windows PowerShell function that contains the capability of several commands. This would allow me to be able to type a single command, and have it perform multiple actions. I used to be able to do things like this in other languages. Can it be accomplished in Windows PowerShell?<\/p>\n<p>&#8212; EJ<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" border=\"0\" align=\"left\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" height=\"34\" title=\"Hey, Scripting Guy! Answer\" \/> Hello EJ, <\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. This is going to entail quite a bit of detail to answer, so I am going to get out of the way and let James get to work on your answer. <\/p>\n<p>James Brundage is the founder of Start-Automating (<a href=\"http:\/\/www.start-automating.com\">http:\/\/www.start-automating.com<\/a>), a company dedicated to saving people time and money by helping them automate. Start-Automating offers Windows PowerShell training and custom Windows PowerShell and .NET Framework development. James formerly worked on the Windows PowerShell team at Microsoft, and he is the author of the <a href=\"http:\/\/code.msdn.microsoft.com\/PowerShellPack\">PowerShellPack<\/a>, a collection of Windows PowerShell scripts to enable building user interfaces, interact with RSS feeds, get system information, and more.<\/p>\n<p>&nbsp;<\/p>\n<h4>A Series on Splatting (and Stuff)<\/h4>\n<h5>Part 3 &ndash; Bridging Commands Together with Splatting and CommandMetaData<\/h5>\n<p>In the <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/10\/19\/automatically-create-custom-powershell-functions.aspx\">previous post<\/a>, I covered how to use splatting to create commands that wrap other commands. Wrapper commands allowed us to take something unwieldy (such as <strong>Get-Counter &lsquo;\\Processor(_total)\\% Processor Time&rsquo;<\/strong>) into something convenient and memorable (such as <strong>Watch-ProcessorPerformance<\/strong>). Today, we learn how to build bridges.<\/p>\n<p>Specifically, we learn how to bridge the functionality of two complicated commands to make one convenient one. Creating wrappers and bridges can help make a mess of long command lines into a neat pile or organized commands. We&rsquo;re also going to learn how to handle wrapping commands with default parameters.<\/p>\n<p>We&rsquo;ll do this by writing a function called <strong>Watch-File<\/strong>. <strong>Watch-File<\/strong> will merge two commands, <a href=\"http:\/\/www.bing.com\/visualsearch?g=powershell_cmdlets&amp;qpvt=Windows+PowerShell&amp;FORM=Z9GE36#category=2&amp;r=4\">Register-ObjectEvent<\/a> and <strong>Get-ChildItem<\/strong>. It will also add one parameter that will let us choose which events to watch for, which will effectively map to the <strong>&ndash;EventName<\/strong> parameter of <strong>Register-ObjectEvent<\/strong>.<\/p>\n<p><strong>Watch-File<\/strong> is a great candidate because: <\/p>\n<ul>\n<li>There are a lot of valuable parameters we&#8217;ll probably want to use in <strong>Get-ChildItem<\/strong> (<strong>-Filter<\/strong>, <strong>-Recurse<\/strong>, <strong>-Include<\/strong>, and <strong>-Exclude<\/strong> come to mind).<\/li>\n<li>There are a lot of parameters in <strong>Register-Object<\/strong> event that might prove useful as well (such as <strong>-SourceIdentifier<\/strong> and <strong>-Action<\/strong>).<\/li>\n<li><strong>Register-ObjectEvent<\/strong> has only one parameter set (this makes this exercise simpler).<\/li>\n<\/ul>\n<p>To write this command, we&rsquo;ll need to understand a little more about the stuff that surrounds splatting, <strong>CommandMetaData<\/strong> and <strong>ProxyCommands<\/strong>. You used both of these things in the last article, but <strong>New-ScriptCmdlet<\/strong> hid them so that you didn&rsquo;t have to deal with them. Now that we&rsquo;re writing a more complex command, we won&rsquo;t be able to avoid the inner workings.<\/p>\n<p>Remember how proxy commands were designed to wrap other commands in Windows PowerShell so that they can be called remotely? Well, in order for this to work, the <strong>ProxyCommands<\/strong> had to be able to get a lot more information about the command than was available in the <strong>CommandInfo<\/strong> object (what comes back from <strong>Get-Command<\/strong>). In Windows PowerShell 1.0, there were a couple of internal classes that had this extra information, <strong>CommandMetaData<\/strong> and <strong>ParameterMetaData<\/strong>. In Windows PowerShell 2.0, these classes were made public and had a little bit added onto them. The <strong>ProxyCommand<\/strong> class takes this information and generates a parameter block and cmdlet binding.<\/p>\n<p>You can add or remove items to the command and parameter metadata, so if you&rsquo;re looking at wrapping commands with a few parameters, you can often approach writing it in terms of manipulating this metadata.<\/p>\n<p>To get the right parameter block for these commands, we&#8217;ll use some <strong>ParameterMetaData<\/strong> magic. Every command in Windows PowerShell has a <strong>CommandMetaData<\/strong> object, and that in turn contains several <strong>ParameterMetaData<\/strong> objects. To make this function, we need to collect all the parameters from <strong>Register-Object<\/strong> event, omit the two parameters we won&#8217;t be wanting anymore, and then add one for the type of file change we want.<\/p>\n<p>When you&#8217;re using a programming language to write other programs, this is called metaprogramming. While this walkthrough covers a lot of ground about how to use splatting to fuse two functions together, it also contains a lot of very useful information about techniques you can use anytime you want to write scripts that write other scripts in Windows PowerShell.<\/p>\n<p>Let&#8217;s start by getting all of the parameters from <strong>Register-Object<\/strong> event. The command to do this is shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">([Management.Automation.CommandMetaData](<\/span><span style=\"color: #0000ff\">Get-Command<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Register-ObjectEvent)).Parameters.Values<\/span> <\/div>\n<\/blockquote>\n<p>Now let&rsquo;s filter out the parameters we don&rsquo;t want:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">|<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">Where-Object<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$_<\/span><span style=\"color: #000000\">.Name<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">-ne<\/span><span style=\"color: #808080\"> &#8220;InputObject&#8221; <\/span><span style=\"color: #0000ff\">-and<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$_<\/span><span style=\"color: #000000\">.Name<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">-ne<\/span><span style=\"color: #808080\"> &#8220;EventName&#8221;       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>To get the right parameter block for these commands, we&#8217;ll use some <strong>ParameterMetaData<\/strong> magic.<\/p>\n<p>In order to use the same underlying tricks that the <strong>New-ScriptCmdlet<\/strong> does (the <strong>New-ScriptCmdlet<\/strong> was discussed in <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/10\/19\/automatically-create-custom-powershell-functions.aspx\">yesterday&rsquo;s Hey, Scripting Guy! post<\/a>), we need to add these new parameters to a command metadata object. The command to do this is shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$getChildItemMetaData<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">[Management.Automation.CommandMetaData](<\/span><span style=\"color: #0000ff\">Get-Command<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">Get-ChildItem<\/span><span style=\"color: #000000\">)<\/span> <\/div>\n<\/blockquote>\n<p>Now let&#8217;s add the parameters from <strong>Register-ObjectEvent<\/strong>. To do this, use the <strong>add<\/strong> method:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #0000ff\">foreach<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$parameter<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">in<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$null<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$getChildItemMetaData<\/span><span style=\"color: #000000\">.Parameters.Add(<\/span><span style=\"color: #2b91af\">$parameter<\/span><span style=\"color: #000000\">.Name,<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$parameter<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">       <br \/><\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>We&#8217;ll need to add one more parameter to the combined list, but that parameter is a lot harder to build from scratch with command metadata than it is to type, so let&rsquo;s turn what we&#8217;ve got now into a parameter block. We can do this with a nifty method on a class that Windows PowerShell uses to make Import\/<a href=\"http:\/\/www.bing.com\/visualsearch?g=powershell_cmdlets&amp;qpvt=Windows+PowerShell&amp;FORM=Z9GE38#category=9&amp;r=10\">Export-PSSession<\/a> work: <strong>[Management.Automation.ProxyCommand]::GetParamBlock()<\/strong>, as shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$combinedParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">[Management.Automation.ProxyCommand]::GetParamBlock(<\/span><span style=\"color: #2b91af\">$getChildItemMetaData<\/span><span style=\"color: #000000\">)<\/span> <\/div>\n<\/blockquote>\n<p>Now to add our new parameter. Our new parameter will be called <strong>-For<\/strong>, and it will accept as input any valid event name on the class <strong>IO.FileSystemWather<\/strong>. By default, it will watch for the events: <strong>Deleted<\/strong>, <strong>Changed<\/strong>, and <strong>Renamed<\/strong>. To make sure the arbitrary string that we give the function is actually an event name, we&#8217;ll use the <strong>ValidateScript<\/strong> attribute. <strong>ValidateScript<\/strong> is a really great tool to have in your scripting repertoire, especially when you want to constrain strings to be a particular sort of information. Here&#8217;s what the parameter would look like on its own:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$newParameter<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\"> &#8216;       <br \/>&nbsp;&nbsp;&nbsp; [ValidateScript({        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (-not ([IO.FileSystemWatcher].GetEvent($_))) {        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $possibleEvents = [IO.FileSystemWatcher].GetEvents() |&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ForEach-Object { $_.Name }&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw &#8220;$_ is not an event on [IO.FileSystemWatcher].&nbsp; Possible values are: $possibleEvents&#8221;        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $true        <br \/>&nbsp;&nbsp;&nbsp; })]        <br \/>&nbsp;&nbsp;&nbsp; [string[]]        <br \/>&nbsp;&nbsp;&nbsp; $For = (&#8220;Deleted&#8221;, &#8220;Changed&#8221;, &#8220;Renamed&#8221;)        <br \/>&#8216;<\/span> <\/div>\n<\/blockquote>\n<p>Making one combined parameter block is now just one little string with a couple of variables:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$paramBlock<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\"> &#8220;$combinedParameters,       <\/p>\n<p>$newParameter&#8221;<\/span> <\/div>\n<\/blockquote>\n<p>In order to use splatting to join the commands and the default values, we&#8217;ll need to keep creating <strong>hashtables<\/strong> to provide the input. The technique I&#8217;ve learned to use for this is pretty simple. Find all of the variables that have a name that matches the input for a command, and put them into a <strong>hashtable<\/strong>. To make sure we do this efficiently, we&#8217;ll collect the parameter names from <strong>Get-ChildItem<\/strong> and <strong>Register-ObjectEvent <\/strong>in the begin block. This technique is illustrated here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$beginBlock<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$getChildItemParameterNames<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #0000ff\">Get-Command<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">Get-ChildItem<\/span><span style=\"color: #000000\">).Parameters.Keys<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$registerObjectEventParameterNames<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #0000ff\">Get-Command<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Register-ObjectEvent).Parameters.Keys<\/span><span style=\"color: #808080\">&nbsp;&nbsp;&nbsp;&nbsp; <br \/><\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>You might notice that the <strong>$paramblock<\/strong> variable I created earlier holds a string. The <strong>$beginBlock<\/strong> I created above holds a script block. This is done purely for the ease of authoring. When writing scripts that will in turn write other scripts, I find that it is helpful to put any portion of the code that will not change into a script block. As script block, as you may recall, is delineated by braces (curly brackets). This does a number of things for us, such as the ones listed here:<\/p>\n<ul>\n<li>It gives you nice syntax highlighting for the portion of the script you&#8217;re working on.<\/li>\n<li>It shows you any syntax errors you have in the script block, instead of seeing it in the finished script.<\/li>\n<li>It makes sure you don&#8217;t accidentally try to evaluate the variable within the string, which can be the source of pretty insidious bugs.<\/li>\n<\/ul>\n<p>We&#8217;re almost done. The Process block is the last piece of the function about which we need to worry. After this is completed, stringing the whole thing together is pretty trivial. The Process block needs to collect the parameters for <strong>Get-ChildItem<\/strong> and <strong>Register-ObjectEvent<\/strong> cmdlets. To do this, it will look for any variable that is declared that also has a value. Then it needs to loop through the results of <strong>Get-ChildItem<\/strong>, create a <strong>FileSystemWatcher<\/strong> <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/ee198910.aspx\">for each<\/a> item, and run <strong>Register-ObjectEvent<\/strong> once for each <strong>&ndash;For<\/strong> provided. The following code accomplishes all these tasks:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$processBlock<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Declare<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">a<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">hashtable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">to<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">store<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">each<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">set<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">of<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">parameters<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$getChildItemParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">@{}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">@{}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Walk<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">over<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">list<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">of<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">parameter<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">names<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">from<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">Get-ChildItem<\/span><span style=\"color: #000000\">.<\/span><span style=\"color: #808080\">&nbsp; <\/span><span style=\"color: #000000\">Any<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">variable<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">that<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">is<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">found<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">will<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">be<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">put<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">into<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">hashtable<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">foreach<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">in<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$getChildItemParameterNames<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">Get-Variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-Name<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-ErrorAction<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">SilentlyContinue<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">if<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">-and<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #000000\">.Value)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$getChildItemParameters<\/span><span style=\"color: #000000\">[<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #000000\">]<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #000000\">.Value<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Do<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">same<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">thing<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">for<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Register-ObjectEvent<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">foreach<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">in<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$registerObjectEventParameterNames<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">Get-Variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-Name<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-ErrorAction<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">SilentlyContinue<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;n\nbsp; <\/span><span style=\"color: #0000ff\">if<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">-and<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #000000\">.Value)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$registerObjectEventParameters<\/span><span style=\"color: #000000\">[<\/span><span style=\"color: #2b91af\">$parameterName<\/span><span style=\"color: #000000\">]<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$variable<\/span><span style=\"color: #000000\">.Value<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">Get-ChildItem<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">@GetChildItemParameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">|<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">ForEach-Object<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Store<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">away<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$_<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">into<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">its<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">own<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">variable<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$file<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$_<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Create<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">a<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">FileSystemWatcherObject<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">to<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">watch<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">for<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">event<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$watcher<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">New-Object<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">IO.FileSystemWatcher<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-Property<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">@{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">Path<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$file<\/span><span style=\"color: #000000\">.Directory<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">Filter<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$file<\/span><span style=\"color: #000000\">.Name<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">#<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Pack<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$watcher<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">into<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">the<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">hashtable<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">of<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">parameters<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">for<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">Register-ObjectEvent<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$RegisterObjectEventParameters<\/span><span style=\"color: #000000\">[<\/span><span style=\"color: #808080\">&#8220;InputObject&#8221;<\/span><span style=\"color: #000000\">]<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$Watcher<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">foreach<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #2b91af\">$f<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">in<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$for<\/span><span style=\"color: #000000\">)<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$RegisterObjectEventParameters<\/span><span style=\"color: #000000\">[<\/span><span style=\"color: #808080\">&#8220;EventName&#8221;<\/span><span style=\"color: #000000\">]<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #2b91af\">$f<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">Register-ObjectEve\nnt<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">@RegisterObjectEventParameters<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span><span style=\"color: #808080\">       <\/p>\n<p><\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>To combine it all, we need to simply add the <strong>param<\/strong>, begin, and process blocks together. We also need to add the <strong>CmdletBindingBlock<\/strong> from whatever command we&#8217;re primarily wrapping (in this case, <strong>Get-ChildItem<\/strong>):<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #2b91af\">$watchFileFunction<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #808080\"> &#8221;       <br \/>function Watch-File {&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; $([Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($getChildItemMetaData))        <br \/>&nbsp;&nbsp;&nbsp; param(&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; $paramBlock        <br \/>&nbsp;&nbsp;&nbsp; )        <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; begin {        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $beginBlock        <br \/>&nbsp;&nbsp;&nbsp; }        <br \/>&nbsp;&nbsp;&nbsp;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; process {        <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $processBlock        <br \/>&nbsp;&nbsp;&nbsp; }        <br \/>}        <br \/>&#8220;<\/span> <\/div>\n<\/blockquote>\n<p>Let&rsquo;s take it for a quick spin. The command to do this is really easy, as shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #000000\">.<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">([ScriptBLock]::Create(<\/span><span style=\"color: #2b91af\">$watchFileFunction<\/span><span style=\"color: #000000\">))<\/span> <\/div>\n<\/blockquote>\n<p>Let&rsquo;s create 10 test files. These new files will be used to test the file system watcher:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #800000\">1<\/span><span style=\"color: #000000\">..<\/span><span style=\"color: #800000\">10<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">|<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">ForEach-Object<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #2b91af\">$_<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">&gt;<\/span><span style=\"color: #808080\"> &#8220;${_}.test.txt&#8221;&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>Now let&rsquo;s watch for the deletion of those files, with an <strong>Action<\/strong> that should tell us which file was deleted. The code to do this is shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #000000\">Watch-File<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-Filter<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">*.test.txt<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-For<\/span><span style=\"color: #808080\"> &#8220;Deleted&#8221; <\/span><span style=\"color: #000000\">-Action<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\">       <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">Write-Host<\/span><span style=\"color: #808080\"> &#8220;File Deleted &#8211; $($eventArgs.FullPath)&#8221; <\/span><span style=\"color: #000000\">-ForegroundColor<\/span><span style=\"color: #808080\"> &#8220;Red&#8221;&nbsp; <br \/><\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>To make things more interesting, let&#8217;s pick a random file to delete.<\/p>\n<p>There&#8217;s a nifty Windows PowerShell trick used here: <strong>-Path<\/strong> is a parameter that can be supplied from the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/topics\/winpsh\/manual\/pipe.mspx\">pipeline<\/a> by a property name. This means that if a magic object came along with a <strong>path<\/strong> property, <strong>Get-ChildItem<\/strong> would use this property for <strong>-Path<\/strong>. It also means that you can supply a script block to figure out the path each time, which is what we do here.<\/p>\n<p>When you run this pipeline, a random file will be deleted and you should see a message in red telling you which one was deleted. The code to delete the random file is shown here:<\/p>\n<blockquote>\n<div class=\"code\"><span style=\"color: #800000\">1<\/span><span style=\"color: #000000\">..<\/span><span style=\"color: #800000\">10<\/span><span style=\"color: #808080\">&nbsp; <\/span><span style=\"color: #000000\">|<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000\">Get-Random<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">|<\/span><span style=\"color: #808080\">&nbsp; <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff\">Remove-Item<\/span><span style=\"color: #808080\">&nbsp;<\/span><span style=\"color: #000000\">-Path<\/span><span style=\"color: #808080\">&nbsp; <\/span><span style=\"color: #000000\">{<\/span><span style=\"color: #808080\"> &#8220;$_.test.txt&#8221; <\/span><span style=\"color: #000000\">}<\/span> <\/div>\n<\/blockquote>\n<p>The message from running the previous command that deletes the random file is shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5633.HSG-10-20-10-1_0B73EF50.jpg\"><img decoding=\"async\" border=\"0\" width=\"604\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0827.HSG-10-20-10-1_thumb_50401384.jpg\" alt=\"Image of message from running command\" height=\"342\" style=\"border-right: 0px;padding-right: 0px;border-top: 0px;padding-left: 0px;border-left: 0px;padding-top: 0px;border-bottom: 0px\" title=\"Image of message from running command\" \/><\/a><\/p>\n<p>Great! Now you know how to make wrapper functions that wrap a single command, and bridge functions to wrap more than one command. This enables you to create quickly, complicated functions for things that already have a command. In the next article, we&rsquo;ll see how you can use splatting and private commands to take something messy in .NET Framework and turn it into something simpler in Windows PowerShell.<\/p>\n<p>EJ, that is all there is to creating wrapper functions that wrap a single command and bridge functions that wrap more than one command. Guest Blogger Week will continue tomorrow when James talks about using splatting to simplify messy .NET Framework code. <\/p>\n<p>We invite you to follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to us at <a href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Summary: Learn how to use Windows PowerShell 2.0 to combine multiple commands into new custom functions and simplify your scripting. &nbsp; Hey, Scripting Guy! I do a lot of work from the Windows PowerShell command line. In fact, I write very few scripts, but I run lots of commands. I would like to create [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,56,184,3,4,170,45],"class_list":["post-16761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-guest-blogger","tag-james-brundage","tag-scripting-guy","tag-scripting-techniques","tag-splatting","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Summary: Learn how to use Windows PowerShell 2.0 to combine multiple commands into new custom functions and simplify your scripting. &nbsp; Hey, Scripting Guy! I do a lot of work from the Windows PowerShell command line. In fact, I write very few scripts, but I run lots of commands. I would like to create [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=16761"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/16761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=16761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=16761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=16761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}