<?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 'Scripting Guy!' and 'Weekend Scripter'</title><link>http://powershell.com/cs/search/SearchResults.aspx?q=app:weblogs&amp;tag=Scripting+Guy!,Weekend+Scripter&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'Scripting Guy!' and 'Weekend Scripter'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Weekend Scripter: Add Power and Functionality to the PowerShell ISE Part 2</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/19/weekend-scripter-add-power-and-functionality-to-the-powershell-ise-part-2.aspx</link><pubDate>Sun, 19 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23598</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, adds more power and functionality to the Windows PowerShell ISE with a modified module.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This is Part 2 of a two part series where I edit my Windows PowerShell ISE module and add five new functions. The five new functions are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add-RemarkedText&lt;/li&gt;
&lt;li&gt;Remove-MarkedText&lt;/li&gt;
&lt;li&gt;Edit-Module&lt;/li&gt;
&lt;li&gt;Import-EveryModule&lt;/li&gt;
&lt;li&gt;Switch-OutLineView&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Yesterday, in &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/18/weekend-scripter-add-power-and-functionality-to-the-powershell-ise.aspx"&gt;Add Power and Functionality to the PowerShell ISE Part 1&lt;/a&gt;, I talked about the &lt;strong&gt;Add-RemarkedText&lt;/strong&gt; and the &lt;strong&gt;Remove-MarkedText&lt;/strong&gt; functions. Today I am going to talk about the remaining three functions.&lt;/p&gt;
&lt;h2&gt;The Edit-Module function&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Edit-Module&lt;/strong&gt; function is a function that I have wanted to write for a long time. The scenario goes like this: I am in the Windows PowerShell ISE working on a script. I realize I want to add or to edit something to an installed Windows PowerShell module. So I have to click around and find the module, and then open it in the Windows PowerShell ISE so I can check something or edit something in the module.&lt;/p&gt;
&lt;p&gt;Granted, it is not a huge problem, but it does slow things down a bit. Slow no longer&amp;mdash;not with my &lt;strong&gt;Edit-Module&lt;/strong&gt; function. To use it, all I need to do is type &lt;strong&gt;Edit-Module&lt;/strong&gt; (&lt;strong&gt;em&lt;/strong&gt; is an alias), and provide enough of the module name to distinguish it to Windows PowerShell. Yes, this function uses wildcard characters. For example, if I want to edit my PowerShellIseModule.psm1 file, I can type all of that, or I can just type &lt;strong&gt;PowerShell*&lt;/strong&gt; (on my system) to gain access to the file. This technique 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/2867.hsg_2D00_5_2D00_19_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/2867.hsg_2D00_5_2D00_19_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is the complete &lt;strong&gt;Edit-Module&lt;/strong&gt; function:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Edit-Module&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Edit-Module&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; &amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Synopsis&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This opens a module stored in the $env:PSModulePath location on a new tab in ISE&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Description&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function uses Get-Module to retrieve a module from $env:PSModulePath and then&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; it opens the module from that location into a new tab in ISE for editing. Wildcard&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; characters that resolve to a single module are supported.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit-Module PowerShellISEModule&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit-Module PowerShellISEModule opens the PowerShellISEModule into a new tab in the&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ISE for editing&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit-Module PowerShellISE*&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Edit-Module PowerShellISE* opens the PowerShellISEModule into a new tab in the&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ISE for editing by using a wild card character for the module name&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Parameter Name&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; The name of the module. Wild cards that resolve to a single module are supported&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Notes&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME:&amp;nbsp; Edit-Module&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AUTHOR: ed wilson, msft&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LASTEDIT: 05/16/2013 18:14:19&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KEYWORDS: Scripting Techniques, Modules&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HSG: WES-5-18-2013&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Link&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Http://www.ScriptingGuys.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#Requires -Version 2.0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Param($name)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;ISE (Get-Module -ListAvailable $name).path&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} #end function Edit-Module&lt;/p&gt;
&lt;h2&gt;Importing every module&lt;/h2&gt;
&lt;p&gt;Yes, there are times when I need to import every module in Windows PowerShell. I used to type the following command:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Module &amp;ndash;ListAvailable | Import-Module&lt;/p&gt;
&lt;p&gt;Even with aliases such as &lt;strong&gt;gmo&lt;/strong&gt; and &lt;strong&gt;ipmo&lt;/strong&gt;, the command got a bit tedious. So I finally decided to quit typing that command by creating my &lt;strong&gt;Import-EveryModule&lt;/strong&gt; function. The previous code is the gist of the function,&amp;mdash;he remainder is the gravy. Here is the complete function:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Import-EveryModule&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Import-EveryModule&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; &amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Synopsis&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This imports all modules from the $env:PSModulePath&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Description&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function imports all modules from $env:psmodulepath&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Import-EveryModule&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Import-EveryModule imports all modules from $env:psmodulepath&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Notes&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME:&amp;nbsp; Import-EveryModule&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AUTHOR: ed wilson, msft&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LASTEDIT: 05/16/2013 18:24:26&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KEYWORDS: Scripting Techniques, Modules&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HSG: Wes-5-18-2013&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Link&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Http://www.ScriptingGuys.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#Requires -Version 2.0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Get-Module -ListAvailable |&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Import-Module -Force&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} #end function Import-Everymodule&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:12px;"&gt;To make it easier to call this useful bit of code, I create an alias &lt;/span&gt;&lt;strong style="font-size:12px;"&gt;iem&lt;/strong&gt;&lt;em style="font-size:12px;"&gt; &lt;/em&gt;&lt;span style="font-size:12px;"&gt;for &lt;/span&gt;&lt;strong style="font-size:12px;"&gt;Import-EveryModule&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Toggling the Outline view in the Windows PowerShell ISE&lt;/h2&gt;
&lt;p&gt;The last function I want to talk about is the &lt;strong&gt;Switch-OutlineView&lt;/strong&gt; function. What this function does is toggle the Outline view in the current Windows PowerShell ISE script pane. This function is very helpful when working on a long script (such as the 500+ line PowerShellISEModule.PSM1 file). The best way to show this is to show you the script pane with the Outline view set to On:&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/3146.hsg_2D00_5_2D00_19_2D00_13_2D00_02.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/3146.hsg_2D00_5_2D00_19_2D00_13_2D00_02.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now I can expand the Outline view to full code mode by typing &lt;strong&gt;Switch-OutlineView&lt;/strong&gt; in the execution pane (&lt;strong&gt;sov&lt;/strong&gt; is an alias that I created for this).&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/3326.hsg_2D00_5_2D00_19_2D00_13_2D00_03.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/3326.hsg_2D00_5_2D00_19_2D00_13_2D00_03.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is the complete text of the &lt;strong&gt;Switch-OutlineView&lt;/strong&gt; function:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Switch-OutlineView&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Switch-OutlineView&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; &amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Synopsis&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function toggles the outline view in the ISE&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Description&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function toggles the outline view in the ISE. It will expand&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; or collapse all functions in the current script pane.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Switch-OutlineView&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Switch-OutlineView will either expand or collapse all functions&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Notes&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME:&amp;nbsp; Switch-OutlineView&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AUTHOR: ed wilson, msft&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LASTEDIT: 05/16/2013 19:28:37&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KEYWORDS: Scripting Techniques, Modules&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HSG: wes-5-18-2013&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Link&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Http://www.ScriptingGuys.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#Requires -Version 3.0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;$psise.CurrentFile.Editor.ToggleOutliningExpansion()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} #end function switch-outlineview&lt;/p&gt;
&lt;p&gt;The revised PowerShellISEModule and profile is available via the Scripting Guys Script Repository:&amp;nbsp;&lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Windows-PowerShell-ISE-ff235827" target="_blank"&gt;Windows PowerShell ISE Profile and Modules&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;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=3573407" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Add Power and Functionality to the PowerShell ISE Part 1</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/18/weekend-scripter-add-power-and-functionality-to-the-powershell-ise-part-1.aspx</link><pubDate>Sat, 18 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23600</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, begins a revision of his Windows PowerShell ISE Module by adding five new functions.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. I decided to block off the weekend to work on my Windows PowerShell ISE module. There are several things that I want to add to it because the &amp;ldquo;annoyance&amp;rdquo; factor has finally caught up with me. In fact my criteria, when a repetitive task gets to the point that it annoys me, I will write a bit of code and solve the annoying problem. I have a list of five functions that I want to write and add to my Windows PowerShell ISE module. Here are the functions I want to add:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add-RemarkedText&lt;/li&gt;
&lt;li&gt;Remove-MarkedText&lt;/li&gt;
&lt;li&gt;Edit-Module&lt;/li&gt;
&lt;li&gt;Import-EveryModule&lt;/li&gt;
&lt;li&gt;Switch-OutLineView&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So after I make a pot of Gunpowder Green Tea with jasmine, lemon grass, and a half spoonful of spearmint, I head back to my office, and my laptop is busy blaring &lt;a href="http://en.wikipedia.org/wiki/Willie_Nelson" target="_blank"&gt;Willie Nelson&lt;/a&gt;.&amp;nbsp; I look over at the Scripting Wife and say, &amp;ldquo;I thought I was playing &lt;a href="http://en.wikipedia.org/wiki/Mott_the_Hoople" target="_blank"&gt;Mott the Hoople&lt;/a&gt; when I left. What happened?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The Scripting Wife said, &amp;ldquo;You shouldn&amp;rsquo;t have left your computer unattended.&amp;rdquo; I guess she has a point, after all. Today I am going to talk about the first two functions: &lt;strong&gt;Add-RemarkedText&lt;/strong&gt; and &lt;strong&gt;Remove-MarkedText&lt;/strong&gt;. Tomorrow I will talk about the other three functions.&lt;/p&gt;
&lt;h2&gt;Comment (remark) out a block of selected script code&lt;/h2&gt;
&lt;p&gt;When I have a block of code that I want to comment (or remark) out, I generally use the Windows PowerShell&amp;nbsp;2.0 block quote feature of the &lt;strong&gt;&amp;lt;#&lt;/strong&gt; to open the comment and &lt;strong&gt;#&amp;gt;&lt;/strong&gt; to close the comment.&amp;nbsp; This technique is shown here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;this is my code&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;that I want to comment (remark) out&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;for now&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;#&amp;gt;&lt;/p&gt;
&lt;p&gt;The problem with this is that one way I troubleshoot my scripts is by commenting out sections of my code. In the Windows PowerShell ISE, I would like to be able to use the mouse (or keyboard shortcuts) to select a block of code and then to comment it out. Using the &lt;strong&gt;&amp;lt;# &lt;/strong&gt;and &lt;strong&gt;#&amp;gt;&lt;/strong&gt; seems to be a bit cumbersome for me.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt; &amp;nbsp;&amp;nbsp;If I am going to make major changes to a script, I use my &lt;strong&gt;Copy-ScriptToNewTab&lt;/strong&gt; function, which is already in my Windows PowerShell ISE module.&lt;/p&gt;
&lt;p&gt;My solution for this dilemma is my new &lt;strong&gt;Add-RemarkedText&lt;/strong&gt; function. To use it, I simply select a portion of the code in the current tab in the Windows PowerShell ISE, and in the command pane, I type &lt;strong&gt;Add-RemarkedText&lt;/strong&gt;. 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/2727.hsg_2D00_5_2D00_18_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/2727.hsg_2D00_5_2D00_18_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When the &lt;strong&gt;Add-RemarkedText&lt;/strong&gt; function runs, the selected code is now commented (remarked) out, and it will not execute when the script runs. The commented section 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/4064.hsg_2D00_5_2D00_18_2D00_13_2D00_02.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/4064.hsg_2D00_5_2D00_18_2D00_13_2D00_02.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is the complete &lt;strong&gt;Add-RemarkedText&lt;/strong&gt; function.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;ADD-RemarkedText function&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Add-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Synopsis&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function will add a remark # character to beginning of line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Description&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function will add a remark character # to selected text in the ISE.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; These are comment characters, and is great when you want to comment out&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a section of PowerShell code.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Add-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; adds the comment / remark character to beginning of each selected line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Notes&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME:&amp;nbsp; Add-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AUTHOR: ed wilson, msft&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LASTEDIT: 05/16/2013&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; KEYWORDS: Windows PowerShell ISE, Scripting Techniques&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HSG: wes-5-18-13&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Link&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Http://www.ScriptingGuys.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#Requires -Version 2.0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;$text = $psISE.CurrentFile.editor.selectedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;foreach ($l in $text -split [environment]::newline)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; $newText += &amp;quot;{0}{1}&amp;quot; -f (&amp;quot;#&amp;quot; + $l),[environment]::newline&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; $psISE.CurrentFile.Editor.InsertText($newText)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} #End function add-remarkedtext&lt;/p&gt;
&lt;h2&gt;Removing a commented section of code&lt;/h2&gt;
&lt;p&gt;After I have remarked out a portion of code, and I have completed my troubleshooting/testing scenario, it is time to remove the comments. In the past, this meant using the down arrow and the delete key, and hoping the mind numbing repetition did not lull me to sleep and cause me to delete a critical portion of the script.&lt;/p&gt;
&lt;p&gt;With my &lt;strong&gt;Remove-RemarkedText&lt;/strong&gt; function, this is no longer a problem. First I highlight (select) the commented out portion of the script, and then in the execution pane of the Windows PowerShell ISE, I type &lt;strong&gt;Remove-RemarkedText&lt;/strong&gt; (&lt;strong&gt;rr&lt;/strong&gt; is an alias). This technique 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/6562.hsg_2D00_5_2D00_18_2D00_13_2D00_03.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/6562.hsg_2D00_5_2D00_18_2D00_13_2D00_03.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When I press ENTER, the comment character (remarked out code) is removed 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/8540.hsg_2D00_5_2D00_18_2D00_13_2D00_04.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/8540.hsg_2D00_5_2D00_18_2D00_13_2D00_04.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Keep in mind that the code is still selected, and you should click away to remove the selection to protect yourself from accidently deleting the section of your script.&lt;/p&gt;
&lt;p&gt;Here is the complete text of the &lt;strong&gt;Remove-RemarkedText&lt;/strong&gt; function.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Remove-RemarkedText&lt;/strong&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Function Remove-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;lt;#&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Synopsis&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function will remove a remark # character to beginning of line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Description&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; This function will remove a remark character # to selected text in the ISE.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; These are comment characters, and is great when you want to clean up a&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; previously commentted out section of PowerShell code.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Example&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Remove-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Removes the comment / remark character to beginning of each selected line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Notes&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; NAME:&amp;nbsp; Add-RemarkedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AUTHOR: ed wilson, msft&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LASTEDIT: 05/16/2013&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;KEYWORDS: Windows PowerShell ISE, Scripting Techniques&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HSG: wes-5-18-13&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; .Link&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Http://www.ScriptingGuys.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#Requires -Version 2.0&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;#&amp;gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;$text = $psISE.CurrentFile.editor.selectedText&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;foreach ($l in $text -split [environment]::newline)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; &amp;nbsp;$newText += &amp;quot;{0}{1}&amp;quot; -f ($l -replace &amp;#39;#&amp;#39;,&amp;#39;&amp;#39;),[environment]::newline&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp; $psISE.CurrentFile.Editor.InsertText($newText)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;} #End function remove-remarkedtext&lt;/p&gt;
&lt;p&gt;Join me tomorrow when I will complete my discussion of the other three new ISE functions for my Windows PowerShell ISE module. Tomorrow I will also share the link to the Windows PowerShell ISE module project in the Scripting Guys Script Repository.&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=3573402" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Playing with PowerShell's Get-Variable Cmdlet</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/05/11/weekend-scripter-playing-with-powershell-s-get-variable-cmdlet.aspx</link><pubDate>Sat, 11 May 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23434</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, spends some time playing around with the &lt;/span&gt;&lt;strong style="font-size:12px;"&gt;Get-Variable&lt;/strong&gt;&lt;span style="font-size:12px;"&gt; cmdlet.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This morning I am doing something a little different. Instead of drinking English Breakfast tea, I woke up feeling like I wanted Oolong tea instead. So I made a pot of Oolong tea with a spoonful of jasmine buds, a half spoon of peppermint leaves, three juniper berries, and half of a crushed cinnamon stick. It is quite invigorating, without being too overbearing.&lt;/p&gt;
&lt;h2&gt;Checking the value of a variable&lt;/h2&gt;
&lt;p&gt;So I am sitting on the lanai in my porch swing, and I just finished checking the email for the &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt; email alias. I received an email asking why I would bother using the &lt;strong&gt;Get-Variable&lt;/strong&gt; cmdlet, when I can simply reference the variable to see the value? The reason is that there are many more things I need to do with variables than simply see the value contained inside the variable. The following example assigns a directory listing to the &lt;strong&gt;$dir&lt;/strong&gt; variable:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$dir = dir -Directory | ? lastwritetime -gt $([datetime]&amp;#39;4/1/13&amp;#39;)&lt;/p&gt;
&lt;p&gt;To see the value that is contained in the &lt;strong&gt;$dir&lt;/strong&gt; variable, I can type &lt;strong&gt;$dir&lt;/strong&gt;. The command and the 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/7144.hsg_2D00_5_2D00_11_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/7144.hsg_2D00_5_2D00_11_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Use Get-Variable&lt;/h3&gt;
&lt;p&gt;I can also do this by using the &lt;strong&gt;Get-Variable&lt;/strong&gt; cmdlet. When use &lt;strong&gt;Get-Variable&lt;/strong&gt;, both the name and the value appear. To return only the value, I group the expression, and get the &lt;strong&gt;Value&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;property as shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;(Get-Variable dir).value&lt;/p&gt;
&lt;p&gt;This command 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/8308.hsg_2D00_5_2D00_11_2D00_13_2D00_02.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/8308.hsg_2D00_5_2D00_11_2D00_13_2D00_02.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Use the Variable provider&lt;/h3&gt;
&lt;p&gt;But there are other ways to retrieve values from Windows PowerShell variables. For example, I can use the &lt;strong&gt;Variable&lt;/strong&gt; provider and access the value from the Windows PowerShell Variable drive. I do this by using the command shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$variable:dir&lt;/p&gt;
&lt;p&gt;The command and the 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/1781.hsg_2D00_5_2D00_11_2D00_13_2D00_03.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/1781.hsg_2D00_5_2D00_11_2D00_13_2D00_03.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Because the &lt;strong&gt;Variable&lt;/strong&gt; provider creates a PSDrive named &lt;strong&gt;Variable&lt;/strong&gt;, I can use the standard Windows PowerShell cmdlets to work with the variable. For example, I can use &lt;strong&gt;Get-Item &lt;/strong&gt;as shown in this example:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Item -Path Variable:\dir&lt;/p&gt;
&lt;p&gt;But if I only want the value of the &lt;strong&gt;Dir&lt;/strong&gt; variable, I need to select the &lt;strong&gt;Value&lt;/strong&gt; property:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;(Get-Item -Path Variable:\dir).value&lt;/p&gt;
&lt;p&gt;The commands and 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/2746.hsg_2D00_5_2D00_11_2D00_13_2D00_04.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/2746.hsg_2D00_5_2D00_11_2D00_13_2D00_04.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;One of the cooler things to do is to use the &lt;strong&gt;Get-Content&lt;/strong&gt; cmdlet to obtain the contents of the variable. When using this technique, only the first value from the array returns. This is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-Content variable:\dir&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Directory: C:\&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Mode&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; LastWriteTime&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Length Name&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; ------ ----&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;d----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4/23/2013&amp;nbsp; 12:41 PM&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fso&lt;/p&gt;
&lt;h2&gt;Examining the type of a variable&lt;/h2&gt;
&lt;p&gt;I am sure you know that there are different types of variables in Windows PowerShell. If I use the &lt;strong&gt;Get-Variable&lt;/strong&gt; cmdlet, pipe the results to the &lt;strong&gt;Format-List&lt;/strong&gt; cmdlet, and choose all of the properties, I obtain some pretty interesting information. This is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-Variable dir | fl *&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PSPath&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\Variable::dir&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PSDrive&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Variable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PSProvider&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.PowerShell.Core\Variable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PSIsContainer : False&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : dir&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Description&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Value&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {fso, fsox, Program Files, Program Files (x86)...}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Visibility&amp;nbsp;&amp;nbsp;&amp;nbsp; : Public&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Module&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;ModuleName&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Options&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : None&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Attributes&amp;nbsp;&amp;nbsp;&amp;nbsp; : {}&lt;/p&gt;
&lt;p&gt;If I take the &lt;strong&gt;$dir&lt;/strong&gt; variable and pipe it to the &lt;strong&gt;Get-Member&lt;/strong&gt; cmdlet, it returns information about the objects that are contained in the variable, and not about the variable itself.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$dir | get-member&lt;/p&gt;
&lt;p&gt;The command and output from the command 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/3056.hsg_2D00_5_2D00_11_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/3056.hsg_2D00_5_2D00_11_2D00_13_2D00_05.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To find information about the variable itself, I use &lt;strong&gt;Get-Variable&lt;/strong&gt; to return the variable, and then I pipe the result to the &lt;strong&gt;Get-Member&lt;/strong&gt; cmdlet:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Variable dir | Get-Member&lt;/p&gt;
&lt;p&gt;The command and output from the command 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/1768.hsg_2D00_5_2D00_11_2D00_13_2D00_06.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/1768.hsg_2D00_5_2D00_11_2D00_13_2D00_06.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Finding different types of variables&lt;/h2&gt;
&lt;p&gt;Unfortunately, this does not return anything about the type of Windows PowerShell variable. So what is the easy way to find the variable type? Use the &lt;strong&gt;Get-Variable&lt;/strong&gt; cmdlet and pipe the returned objects to the &lt;strong&gt;Get-Member&lt;/strong&gt; cmdlet. Next, I select only the &lt;strong&gt;TypeName&lt;/strong&gt; property, and I use the &lt;strong&gt;Unique&lt;/strong&gt; switch to ensure only unique instances return. Here is the command and the results:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-Variable | Get-Member | select typename -Unique&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;TypeName&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;--------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;System.Management.Automation.PSVariable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;System.Management.Automation.QuestionMarkVariable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;System.Management.Automation.LocalVariable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;System.Management.Automation.SessionStateCapacityVariable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;System.Management.Automation.NullVariable&lt;/p&gt;
&lt;p&gt;When I know the different types of variables, I can use Windows PowerShell to list a particular type of variable. To do this, I pipe the results of &lt;strong&gt;Get-Variable&lt;/strong&gt; to the &lt;strong&gt;Where-Object&lt;/strong&gt;. In my &lt;strong&gt;Where-Object&lt;/strong&gt; filter, I use the &lt;strong&gt;PSObject&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;property so I can reference the underlying type. This technique is shown here where I find all variables of the type &lt;strong&gt;LocalVariable&lt;/strong&gt;&lt;em&gt;. &lt;/em&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Variable | where {$_.psobject.typenames -match &amp;#39;local&amp;#39;}&lt;/p&gt;
&lt;p&gt;The command and output from the command 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/0755.hsg_2D00_5_2D00_11_2D00_13_2D00_07.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/0755.hsg_2D00_5_2D00_11_2D00_13_2D00_07.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Join me tomorrow for the exciting conclusion to the Windows PowerShell and Security series by Yuri Diogenes and Tom Schinder. To catch up, read &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/yuri+diogenes/"&gt;the two previous posts in this series&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=3570611" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Use PowerShell to Upload a New File Version to SharePoint</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/28/weekend-scripter-use-powershell-to-upload-a-new-file-version-to-sharepoint.aspx</link><pubDate>Sun, 28 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23107</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 PowerShell MVP, Niklas Goude, talks about using Windows PowerShell to upload a new version of a file to SharePoint.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Today Niklas Goude is our guest blogger. You can read more from Niklas in his &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/niklas+goude/" target="_blank"&gt;past Hey, Scripting Guy! Blog posts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Take it away Niklas&amp;hellip;&lt;/p&gt;
&lt;p&gt;In a previous post, &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/04/30/3354785.aspx" target="_blank"&gt;Use PowerShell Cmdlets to Manage SharePoint Document Libraries&lt;/a&gt;, we talked about uploading files to a share in SharePoint 2010.&amp;nbsp;&lt;span style="font-size:12px;"&gt;Now we&amp;#39;ll take this a step further and update a minor or a major version of an existing document.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a quick recap of the code used to upload the file:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Add the Snapin&lt;br /&gt; Add-PSSnapin Microsoft.SharePoint.PowerShell&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Retrieve specific Site&lt;br /&gt; $spWeb = Get-SPWeb http://SP01&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Create instance of Folder&lt;br /&gt; $spFolder = $spWeb.GetFolder(&amp;quot;Shared Documents&amp;quot;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Get the file on Disk that we want to upload&lt;br /&gt; $file = Get-Item C:\Documents\MyDoc.docx&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# upload the file.&lt;br /&gt; $spFolder.Files.Add(&amp;quot;Shared Documents/MyDoc.docx&amp;quot;,$file.OpenRead(),$false)&lt;/p&gt;
&lt;p&gt;What we&amp;rsquo;ve done so far is to upload a single document to a document library in SharePoint 2010. The file used in this example is stored on drive C:&amp;nbsp;&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/7041.wes_2D00_4_2D00_28_2D00_13_2D00_1.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/7041.wes_2D00_4_2D00_28_2D00_13_2D00_1.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The document contains a single line:&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/5165.wes_2D00_4_2D00_28_2D00_13_2D00_2.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/5165.wes_2D00_4_2D00_28_2D00_13_2D00_2.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After we run the Windows PowerShell code, the document gets uploaded to a document library in SharePoint 2010.&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/8551.wes_2D00_4_2D00_28_2D00_13_2D00_3.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8551.wes_2D00_4_2D00_28_2D00_13_2D00_3.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We can check the versioning for the document by clicking Version History in SharePoint:&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/0066.wes_2D00_4_2D00_28_2D00_13_2D00_4.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/350x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0066.wes_2D00_4_2D00_28_2D00_13_2D00_4.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll see that the version number is set to 0.1:&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/8802.wes_2D00_4_2D00_28_2D00_13_2D00_5.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8802.wes_2D00_4_2D00_28_2D00_13_2D00_5.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s open the file that is stored on drive C and modify it:&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/0602.wes_2D00_4_2D00_28_2D00_13_2D00_6.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0602.wes_2D00_4_2D00_28_2D00_13_2D00_6.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Back in Windows PowerShell, we use &lt;strong&gt;SPFileCollection&lt;/strong&gt; to pick up the document we just uploaded. In this example, we are going to filter out the document where the name is equal to MyDoc.docx by using the &lt;strong&gt;Where-Object&lt;/strong&gt; cmdlet.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Retrieve specific Site&lt;br /&gt; $spWeb = Get-SPWeb http://SP01&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Create instance of Folder&lt;br /&gt; $spFolder = $spWeb.GetFolder(&amp;quot;Shared Documents&amp;quot;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Retrieve a Specific File.&lt;br /&gt; $spFile = $spFolder.Files | Where-Object { $_.Name -eq &amp;quot;MyDoc.docx&amp;quot; }&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;We pick up the file because we want to use some of its properties for the new version that we want to upload. When we upload a new version of the document, we still use the &lt;strong style="font-size:12px;"&gt;Add&lt;/strong&gt; method that is provided by the Microsoft.SharePoint.SPFileCollection, but with a different overload definition. Here&amp;rsquo;s the definition on MSDN: &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms448353.aspx" target="_blank"&gt;SPFileCollection.Add method (String, Stream, SPUser, SPUser, DateTime, DateTime)&lt;/a&gt;&lt;span style="font-size:12px;"&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The parameters we want to use are: &lt;strong&gt;urlOfFile&lt;/strong&gt;, &lt;strong&gt;File&lt;/strong&gt;, &lt;strong&gt;CreatedBy&lt;/strong&gt;, &lt;strong&gt;ModifiedBy&lt;/strong&gt;, &lt;strong&gt;TimeCreated&lt;/strong&gt;, and &lt;strong&gt;TimeLastModified&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We can get the following values from the existing document in SharePoint 2010: &lt;strong&gt;UrlOfFile&lt;/strong&gt;, &lt;strong&gt;CreatedBy&lt;/strong&gt;, &lt;strong&gt;ModifiedBy&lt;/strong&gt;, and &lt;strong&gt;TimeCreated&lt;/strong&gt;. We can get &lt;strong&gt;File&lt;/strong&gt; by using &lt;strong&gt;Get-Item&lt;/strong&gt;, and we can get &lt;strong&gt;TimeLastModified&lt;/strong&gt; by simply using &lt;strong&gt;Get-Date&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s get the modified MyDoc.docx from drive C:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$file = Get-Item C:\Documents\MyDoc.docx&lt;/p&gt;
&lt;p&gt;Next we run the method:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$newVersion = $spFolder.Files.Add($spFile.Name, $file.OpenRead(), $spFile.Author, $spFile.ModifiedBy, $spFile.TimeCreated, (Get-Date))&lt;/p&gt;
&lt;p&gt;If we open the SharePoint document library again, we&amp;rsquo;ll see that we have a new minor version of our document, .02.&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/6710.wes_2D00_4_2D00_28_2D00_13_2D00_7.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6710.wes_2D00_4_2D00_28_2D00_13_2D00_7.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And finally, if we want to add the modified document as a major version, we use the &lt;strong&gt;Publish&lt;/strong&gt; method:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$newVersion.Publish(&amp;quot;&amp;quot;)&lt;/p&gt;
&lt;p&gt;Now we have a new major version, 1.0, instead.&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/8357.wes_2D00_4_2D00_28_2D00_13_2D00_8.jpg"&gt;&lt;img style="border:0px currentColor;" title="Image of menu" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8357.wes_2D00_4_2D00_28_2D00_13_2D00_8.jpg" alt="Image of menu" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;~Niklas&lt;/p&gt;
&lt;p&gt;Thank you, Niklas, for taking your time to share your knowledge.&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=3569353" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Improve Performance When Combining PowerShell Arrays</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/27/weekend-scripter-improve-performance-when-combining-powershell-arrays.aspx</link><pubDate>Sat, 27 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:23109</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;span style="font-size:12px;"&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Microsoft premier field engineer, Chris Wu, talks about combining Windows PowerShell arrays.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Chris Wu, a Microsoft PFE, is back to share his knowledge. See &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/chris+wu/http:/blogs.technet.com/b/heyscriptingguy/archive/tags/chris+wu/" target="_blank"&gt;previous Hey, Scripting Guy! Blog guest posts&lt;/a&gt; from Chris.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Here is contact information for Chris:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Twitter: &lt;a href="https://twitter.com/chwu_ms"&gt;https://twitter.com/chwu_ms&lt;/a&gt;&lt;br /&gt; Facebook: &lt;a href="https://www.facebook.com/mschwu"&gt;https://www.facebook.com/mschwu&lt;/a&gt;&lt;br /&gt; LinkedIn: &lt;a href="http://ca.linkedin.com/in/mschwu"&gt;http://ca.linkedin.com/in/mschwu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take it away Chris&amp;hellip;&lt;/p&gt;
&lt;p&gt;While teaching a Windows PowerShell workshop, I was asked about how to combine two arrays of different objects (which share one key property) into one that contains objects with properties from both source objects. One real world scenario is to merge information retrieved from Active Directory (a list of Active Directory users and their properties) and Exchange Server (mailboxes).&lt;/p&gt;
&lt;p&gt;The current approach by the student is to use two-level loops, which has seen performance issues when source arrays become huge in size (the following code snippet uses dummy data for demonstration purposes).&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$ADList = @&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;chwu,chwu@microsoft.com,Chris Wu&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst1,,Test User1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst2,tst2@contoso.com,Test User2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;@ | ConvertFrom-Csv -Header Name,mail,CN&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$EXList = @&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;chwu,ex1.contoso.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst2,ex2.contoso.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;@ | ConvertFrom-Csv -Header Name,MailServer&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Result = @()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;foreach($ad in $ADList) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; $Match = $false&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; foreach($ex in $EXList) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if ($ad.Name -eq $ex.Name) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Result += New-Object PSObject -Property @{Name=$ad.Name; mail=$ad.mail; CN=$ad.CN; MailServer=$ex.MailServer}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Match = $true&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; if(-not $Match) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $Result += New-Object PSObject -Property @{Name=$ad.Name; mail=$ad.mail; CN=$ad.CN}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/3716.wes_2D00_4_2D00_27_2D00_13_2D00_1.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/3716.wes_2D00_4_2D00_27_2D00_13_2D00_1.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this post, I will explore several options to improve the performance and cleanness of this code snippet.&lt;/p&gt;
&lt;p&gt;The first thing we can do is remove the use of the &lt;strong&gt;$Result&lt;/strong&gt; array, which has two drawbacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every assignment operation will create a new array in memory with data copied from the source, which is inefficient.&lt;/li&gt;
&lt;li&gt;It defeats the streaming benefit of the WindowsPowerShell pipeline because it returns all objects as a whole at the end of the processing. A best practice in Windows PowerShell is to emit an individual object whenever it&amp;rsquo;s ready.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another performance issue stems from the use of an inner loop to search for a matching record in the second array, which basically multiplies the total number of iterations. We can utilize a hash table for faster lookup. The &lt;strong&gt;Group-Object&lt;/strong&gt; cmdlet offers a convenient &lt;strong&gt;AsHashTable &lt;/strong&gt;parameter that can be used 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/8512.wes_2D00_4_2D00_27_2D00_13_2D00_2.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/8512.wes_2D00_4_2D00_27_2D00_13_2D00_2.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please be warned that the value portion of each entry is an array of matching records. If we are grouping records by using a property with unique values (such as &lt;strong&gt;SamAccountName&lt;/strong&gt;), those arrays will apparently contains one single element each.&lt;/p&gt;
&lt;p&gt;So an enhanced version of the code snippet is like this (with the constructing source arrays removed):&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$h = $EXList | Group-Object -Property Name -AsHashTable&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$ADList | %{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; if($h[$_.Name]) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-Object PSObject -Property @{Name=$_.Name; mail=$_.mail; CN=$_.CN; MailServer=$h[$_.Name][0].MailServer}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; } else {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-Object PSObject -Property @{Name=$_.Name; mail=$_.mail; CN=$_.CN}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;The last (but not the least) idea is to sort both arrays based on the key property (user name) beforehand, then we can pair records in a single iteration. Note that in this particular example, users found in Active Directory is a superset of users in Exchange, so we need a pointer variable to deal with this little quirk.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$ADList = @&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;chwu,chwu@microsoft.com,Chris Wu&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst1,,Test User1&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst2,tst2@contoso.com,Test User2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;@ | ConvertFrom-Csv -Header Name,mail,CN | Sort-Object -Property Name&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$EXList = @&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;chwu,ex1.contoso.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;tst2,ex2.contoso.com&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;quot;@ | ConvertFrom-Csv -Header Name,MailServer | Sort-Object -Property Name&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$ADList | % {$p = 0} {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; if($_.Name -eq $EXList[$p].Name) {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-Object PSObject -Property @{Name=$_.Name; mail=$_.mail; CN=$_.CN; MailServer=$EXList[$p].MailServer}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; $p++&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; } else {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; New-Object PSObject -Property @{Name=$_.Name; mail=$_.mail; CN=$_.CN}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;The last two snippets perform much better than the original one, but which one is faster remains a question (I haven&amp;rsquo;t tested them against large arrays just yet). I would like to hear about your results, and I welcome your thoughts and ideas.&lt;/p&gt;
&lt;p&gt;~Chris&lt;/p&gt;
&lt;p&gt;Thanks Chris excellent blog post. Join me tomorrow for 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;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=3566535" width="1" height="1" alt="" /&gt;</description></item><item><title>Use PowerShell to modify WMI data such as drive label</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/20/use-powershell-to-modify-wmi-data-such-as-drive-label.aspx</link><pubDate>Sat, 20 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22935</guid><dc:creator>Anonymous</dc:creator><description>Summary: The Scripting Wife learns how to use the CIM cmdlets and Windows PowerShell to assign a new drive label by modifying WMI data 
 Weekend Scripter: Changing WMI information 
 Microsoft Scripting Guy, Ed Wilson, is here. Well yesterday, after...(&lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/21/use-powershell-to-modify-wmi-data-such-as-drive-label.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3568085" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Use PowerShell to Find the Version of Windows</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/20/weekend-scripter-use-powershell-to-find-the-version-of-windows.aspx</link><pubDate>Sat, 20 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22937</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;: The Scripting Wife learns about using Windows PowerShell to find computer hardware information in prep for the 2013 Scripting Games.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. This morning did not start with a nice leisurely cup of tea on the lanai at home. Instead, it started by rushing around to get packed, loading up the vehicle, vying for a parking place at the airport, taking a shuttle from parking to the Charlotte terminal, standing in line for an hour for a security screen that was more intimate than my last physical exam, putting shoes and belt back on and repacking my suitcase, and standing in another really long line to buy an overpriced cup of warm milk with a shot of acidic coffee in it. Then another long line to board a really, really cramped airplane. Luckily, the Scripting Wife is with me, and she helps make the entire process a little more pleasant. Yep, we are finally on our way to Seattle for the Windows PowerShell Summit.&lt;/p&gt;
&lt;h2&gt;Scripting Wife uses WMI&lt;/h2&gt;
&lt;p&gt;After takeoff, I open my laptop and the Windows PowerShell console and start playing around. Before long the Scripting Wife is poking me in my shoulder.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Yes,&amp;rdquo; I say.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;So I think this would be the perfect time for you to talk to me about using WMI with Windows PowerShell,&amp;rdquo; she stated.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK, good idea,&amp;rdquo; I said as I slid my laptop over to allow her to use it.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;So what now?&amp;rdquo; she asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well the first thing to know about WMI is that there are lots of WMI classes. They are also arranged into different namespaces, but we will not get into that right now. To find WMI classes, use the &lt;strong&gt;Get-CimClass&lt;/strong&gt; cmdlet in Windows PowerShell&amp;nbsp;3.0,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, that makes sense. So what do I do if I need to find the name of my operating system?&amp;rdquo; she asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Why don&amp;rsquo;t you try it? Use the &lt;strong&gt;Get-CimClass&lt;/strong&gt; cmdlet, and put &lt;strong&gt;os&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;into a pair of wildcard characters,&amp;rdquo; I suggested.&lt;/p&gt;
&lt;p&gt;She typed the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Cimc&amp;lt;tab&amp;gt;&amp;lt;Space&amp;gt;*os*&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The command is shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-CimClass *os*&lt;/p&gt;
&lt;p&gt;The command and the 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/7028.hsg_2D00_4_2D00_20_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/7028.hsg_2D00_4_2D00_20_2D00_13_2D00_01.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, that did not do what I expected it to do,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;So, you have found out that WMI does not really have a class named OS, or anything similar to OS. What are you really looking for?&amp;rdquo; I asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I want to know the version of Windows,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The cool thing about &lt;strong&gt;Get-CimClass&lt;/strong&gt; is that you can search for classes that contain a specific property. So why don&amp;rsquo;t you look for WMI classes that contain a property of &lt;strong&gt;version&lt;/strong&gt;?&amp;rdquo; I suggested.&lt;/p&gt;
&lt;p&gt;The Scripting Wife typed the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Cimc&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;-p&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;version&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The following is the command she created.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-CimClass -PropertyName version&lt;/p&gt;
&lt;p&gt;The command and the output associated with the command 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/0601.hsg_2D00_4_2D00_20_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/0601.hsg_2D00_4_2D00_20_2D00_13_2D00_02.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It is still a lot of stuff,&amp;rdquo; she complained.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well one of the things you need to know about WMI is that there are abstract and dynamic classes,&amp;rdquo; I began.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;And why do I need to know that?&amp;rdquo; she interrupted.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Maybe you do not need to know all that, but keep in mind you want to use dynamic classes,&amp;rdquo; I began again.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Why?&amp;rdquo; she asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Because dynamic WMI classes go off and get information. So they are the ones that you want to use. The abstract classes are more used by developers,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well OK. So I only need to remember to use dynamic classes. I got it. Now what?&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The &lt;strong&gt;Get-CimClass&lt;/strong&gt; cmdlet has a &lt;strong&gt;QualifierName &lt;/strong&gt;parameter. You can specify that you only want &lt;strong&gt;dynamic&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;WMI classes returned. It will give you a better output,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Cool. So let&amp;rsquo;s do it,&amp;rdquo; she said energetically.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Use the Up arrow to retrieve your previous command. Go to the end of the command and add the &lt;strong&gt;QualifierName &lt;/strong&gt;parameter,&amp;rdquo; I said. &amp;ldquo;And don&amp;rsquo;t forget to use tab completion to help you.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The Scripting Wife typed:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;uparrow&amp;gt;&amp;lt;space&amp;gt;-q&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;dynamic&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;Here is the command she created:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-CimClass -PropertyName version -QualifierName dynamic&lt;/p&gt;
&lt;p&gt;The command and 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/8308.hsg_2D00_4_2D00_20_2D00_13_2D00_03.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/8308.hsg_2D00_4_2D00_20_2D00_13_2D00_03.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Cool,&amp;rdquo; she said. &amp;ldquo;So where do I find the version?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Look at the output. See the Win32_OperatingSystem?&amp;rdquo; I started.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Oh yeah, I get it,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Now use &lt;strong&gt;Get-CimInstance&lt;/strong&gt; to retrieve the operating system information,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;She typed the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Cimi&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;Win32_Op&amp;lt;tab&amp;gt;&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;Here is the command:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-CimInstance Win32_OperatingSystem&lt;/p&gt;
&lt;p&gt;Here is the command and the output from the command:&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/2844.hsg_2D00_4_2D00_20_2D00_13_2D00_04.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/2844.hsg_2D00_4_2D00_20_2D00_13_2D00_04.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well ain&amp;rsquo;t that just special,&amp;rdquo; she said as she pushed the laptop back over to me. She then opened her Surface and began reading a book that she had downloaded.&lt;/p&gt;
&lt;p&gt;I returned to my Windows PowerShell console, and tried to make sense of life.&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=3567971" width="1" height="1" alt="" /&gt;</description></item><item><title>Use PowerShell to Modify WMI Data Such as Drive Labels</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/20/use-powershell-to-modify-wmi-data-such-as-drive-labels.aspx</link><pubDate>Sat, 20 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22998</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;Summary: The Scripting Wife learns how to use the CIM cmdlets and Windows PowerShell to assign a new drive label by modifying WMI data.&lt;/p&gt;
&lt;h3&gt;Weekend Scripter: Changing WMI information&lt;/h3&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Well yesterday, after we got through an extremely long security line at the airport, and we jiggled around in a very cramped airplane for over five hours on our flight to Seattle for the Windows PowerShell summit, we met up with Windows PowerShell MVP Jeff Wouters at the SEATAC airport. We gave him a ride into Redmond and spent some time hanging out. Here is a picture of Jeff and the Scripting Wife I took near the Seattle Space Needle. You see, Jeff has never been to Seattle, and so we thought we would show him around.&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-metablogapi/4621.clip_5F00_image002_5F00_6052A62B.jpg"&gt;&lt;img style="margin:0px;display:inline;background-image:none;" title="clip_image002" src="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18-metablogapi/2577.clip_5F00_image002_5F00_thumb_5F00_39185CF6.jpg" alt="clip_image002" width="179" height="222" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Windows PowerShell summit has already been a success, in my mind, and the first session has not even kicked off. Of course, the biggest thing for the summit for me is not the sessions, but the chance to talk and to interact with members of the community. In this regard, the summit has already exceeded expectations.&lt;/p&gt;
&lt;p&gt;I decided to head down to the lobby of the hotel to grab something to eat this morning. It is still very early for people from the West Coast, but for the Scripting Wife and I it is already late due to the three time zone change for us. Of course, for our European friends the change is twice as great. I am sipping a cup of English Breakfast tea, munching on a croissant, and checking my email, when a loud thudding sound accompanied by a sudden shaking of the table woke me from my revelry&amp;ndash;it is the Scripting Wife.&lt;/p&gt;
&lt;p&gt;I hazard a query, &amp;ldquo;Why are you are up so early?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Hey, it is nearly noon back in Charlotte&amp;ndash;I am ready to go,&amp;rdquo; she chirped.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Go? Go where?&amp;rdquo; I ventured.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Out. We are getting together a group, and we are heading out,&amp;rdquo; she explained.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Where is out? Have you no specific destination in mind?&amp;rdquo; I asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, maybe downtown Seattle. There is great shopping there, a cool aquarium, ferry terminals, and wonderful restaurants. We are in a &lt;em&gt;real &lt;/em&gt;city my friend, and I for one am not going to let the opportunity pass,&amp;rdquo; she pontificated.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I can appreciate that. But before you go, let me show you something you might need to know for the 2013 Scripting Games,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK, but make it quick, because when the group shows up, I am out of here,&amp;rdquo; she said.&lt;/p&gt;
&lt;h2&gt;Using the CIM cmdlets to set a WMI property&lt;/h2&gt;
&lt;p&gt;I opened the Windows PowerShell console with admin rights by right clicking the Windows PowerShell console icon and selecting &lt;strong&gt;Run As Administrator&lt;/strong&gt; from the action menu. Admin rights are required to modify WMI objects.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK. Look over here,&amp;rdquo; I directed. &amp;ldquo;Find WMI classes related to disks.&amp;rdquo;&lt;/p&gt;
&lt;h3&gt;Find disk classes&lt;/h3&gt;
&lt;p&gt;The Scripting Wife thought for a few minutes, and typed the following.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Cimc&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;*disk*&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The command she typed appears here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Get-CimClass *disk*&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Get dynamic classes&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;Now, narrow your output to only dynamic WMI classes,&amp;rdquo; I instructed.&lt;/p&gt;
&lt;p&gt;She used the Up arrow to retrieve the previous command and she added the &lt;strong&gt;Dynamic&lt;/strong&gt; qualifier to her command. Here is what she typed:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;up arrow&amp;gt;&amp;lt;space&amp;gt;-q&amp;lt;tab&amp;gt;dynamic&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The command looks like this when complete.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Get-CimClass *disk* -QualifierName dynamic&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Get logical disk info&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;Cool. Now what we want to do is to find out information about&lt;em&gt;&amp;nbsp;&lt;/em&gt;drive C. To do this use the &lt;strong&gt;Get-CimInstance&lt;/strong&gt; cmdlet and retrieve information about the Win32_LogicalDisk WMI class,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;The Scripting Wife thought for a second, and then she began to type. Here is what she did:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-CimI&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;Win32_LogicalDisk&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The command looks like the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Get-CimInstance win32_logicaldisk&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK, now look at the output and see if you can tell the property that indicates that it references the drive names,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;She looked at the laptop screen. The output looks like the following:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-CimInstance win32_logicaldisk&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;DeviceID DriveType ProviderName VolumeName Size FreeSpace&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-------- --------- ------------ ---------- ---- ---------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C: 3 159486308352 10707682...&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;D: 3 System Reserved 366997504 113971200&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;F: 3 ExtraDisk 499738734592 43558884...&lt;/p&gt;
&lt;h3&gt;Narrow down the drives by letter&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;So you did a good job. You found information about all of the logical disks. What I want you to do now, is to return only drive C&lt;em&gt;&amp;nbsp;&lt;/em&gt;. To do that you will need to use the F&lt;strong&gt;ilter&lt;/strong&gt; property,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;It did not take the Scripting Wife long at all before she used the Up arrow to retrieve her previous command and to add the &lt;strong&gt;Filter&lt;/strong&gt; parameter. Here is what she typed.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;up arrow&amp;gt;&amp;lt;space&amp;gt;-f&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;&amp;rsquo;DeviceID=&amp;rsquo;c:&amp;rsquo;&amp;rdquo;&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;Here is the command she created.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Get-CimInstance win32_logicaldisk -Filter &amp;quot;deviceid=&amp;#39;c:&amp;#39;&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The command and output from the command are shown here:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;PS C:\&amp;gt; Get-CimInstance win32_logicaldisk -Filter &amp;quot;deviceid=&amp;#39;c:&amp;#39;&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;DeviceID DriveType ProviderName VolumeName Size FreeSpace&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-------- --------- ------------ ---------- ---- ---------&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;C: 3 159486308352 10707628...&lt;/p&gt;
&lt;h3&gt;Setting a WMI property&lt;/h3&gt;
&lt;p&gt;&amp;ldquo;Notice that you have no label, or &lt;strong&gt;VolumeName&lt;/strong&gt;&lt;em&gt;,&lt;/em&gt;&amp;rdquo; I said. &amp;ldquo;To set that you will use the &lt;strong&gt;Set-CimInstance&lt;/strong&gt; cmdlet and use a hash table for the &lt;strong&gt;Property&lt;/strong&gt; parameter,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Huh?&amp;rdquo; she asked. &amp;ldquo;You know that I do not speak geek.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;It makes more sense when you just do it,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, hurry up. I just got an email on my phone and they will be here in a few minutes,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK. First of all, you need to use the Up arrow and retrieve your previous command. Then you need to pipe the command to the &lt;strong&gt;Set-CimInstance&lt;/strong&gt; cmdlet. Do that, but do not press ENTER because there is more to the command than that,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;The Scripting Wife thought for a few minutes, and then began typing. Here is what she typed.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;lt;Up Arrow&amp;gt;&amp;lt;space&amp;gt;Set-Cimi&amp;lt;tab&amp;gt;&lt;/p&gt;
&lt;p&gt;She paused.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;OK, now you need to add the &lt;strong&gt;Property&lt;/strong&gt; parameter and an ampersand and an opening and a closing curly bracket. Do not press ENTER,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;This time, she did not hesitate. Here is what she typed:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-p&amp;lt;tab&amp;gt;&amp;lt;space&amp;gt;@{}&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Good. Now inside the two curly brackets you add your &amp;#39;property name equals new value&amp;#39; statement. Here, you are going to set a value for the &lt;strong&gt;VolumeName&lt;/strong&gt;&lt;em&gt;. &lt;/em&gt;Give it a value of &lt;strong&gt;SSD_Drive&lt;/strong&gt;,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;Here is what she typed:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;volumename=&amp;#39;SSD_Drive&amp;#39;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Awesome. You are nearly there. Add the &lt;strong&gt;PassThru&lt;/strong&gt; parameter so the modified WMI object returns to the Windows PowerShell line, and press ENTER,&amp;rdquo; I said.&lt;/p&gt;
&lt;p&gt;Here is what she typed:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;-p&amp;lt;tab&amp;gt;&amp;lt;enter&amp;gt;&lt;/p&gt;
&lt;p&gt;The complete command is shown here. (This is a one-line command,broken at the pipe so it is more readable.)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Get-CimInstance -ClassName win32_Logicaldisk -Filter &amp;quot;deviceid=&amp;#39;c:&amp;#39;&amp;quot; | &lt;/span&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="background-color:#cccccc;"&gt;Set-CimInstance -Property @{volumename=&amp;#39;SSD_Drive&amp;#39;} &amp;ndash;PassThru&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The command and the 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-metablogapi/1581.clip_5F00_image004_5F00_6B0FFD80.gif"&gt;&lt;img style="display:inline;background-image:none;" title="clip_image004" src="http://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18-metablogapi/3162.clip_5F00_image004_5F00_thumb_5F00_63F0C108.gif" alt="clip_image004" width="244" height="63" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, isnt that special,&amp;rdquo; she mocked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Actually, I think it is pretty cool,&amp;rdquo; I said somewhat defensively.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;I do too. I was just giving you a hard time,&amp;rdquo; She said.&lt;/p&gt;
&lt;p&gt;At that instant, the automatic doors to the lobby swung open and in walked a couple of obvious PowerShellers. I could tell by the T-shirts, but the Scripting Wife obviously knew them.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Well, I am outta here. Have fun working on your presentation,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;So when will I see you again?&amp;rdquo; I asked.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;We&amp;rsquo;re meeting Don Jones and others at Azteca at 5:00,&amp;rdquo; she said.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Zulu?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Without missing a beat, she said &amp;ldquo;No. Pacific Standard Time.&amp;rdquo; And she was gone.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter"&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"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum"&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=3568085" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Use PowerShell to Clean Out Temp Folders</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/14/weekend-scripter-use-powershell-to-clean-out-temp-folders.aspx</link><pubDate>Sun, 14 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22791</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;: Guest blogger, Bob Stevens, talks about using Windows PowerShell to clean out temporary folders on desktops following a malware infection.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Today, we welcome back our newest guest blogger, Bob Stevens. Yesterday Bob wrote about a quick script that he developed to pick out comments from a Windows PowerShell script: &lt;a href="http://blogs.technet.com/b/heyscriptingguy/archive/2013/04/13/weekend-scripter-pick-comments-from-a-powershell-script.aspx" target="_blank"&gt;Weekend Scripter: Pick Comments from a PowerShell Script&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I made Bob&amp;rsquo;s virtual acquaintance recently when I did a Live Meeting presentation to the &lt;a href="http://www.tcposhug.com/" target="_blank"&gt;Twin Cities PowerShell User Group.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is Bob&amp;rsquo;s contact information:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Blog: &lt;a href="http://stuckinmypowershell.blogspot.com/" target="_blank"&gt;Help! I&amp;rsquo;m Stuck In My Powershell!&lt;/a&gt;&lt;br /&gt; Twitter: &lt;a href="https://twitter.com/B_stevens6" target="_blank"&gt;@B_stevens6&lt;/a&gt;&lt;br /&gt; LinkedIn: &lt;a href="http://www.linkedin.com/profile/edit?trk=hb_tab_pro_top" target="_blank"&gt;Robert Stevens&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Take it away, Bob&amp;hellip;&lt;/p&gt;
&lt;p&gt;For a local service desk systems analyst, nothing is more frustrating than malware. Not only is it a time sink&amp;mdash;it also has the indented potential to cause irreparable damage. No network that connects to the Internet is immune to it.&lt;/p&gt;
&lt;p&gt;Most organizations have their own standard operating procedures regarding malware removal. Even so, individuals technician have their special tweaks and tricks to increase the likelihood of success. I like to target the malware where it resides: Temp Folders. And after cleaning and clearing a number of workstations, it occurred to me that I could use a Windows PowerShell script to do just that, saving myself five minutes of hoping that the computer will let me open a folder.&lt;/p&gt;
&lt;p&gt;I started by creating a list of the locations that temporary files are automatically placed by the Windows&amp;nbsp;XP operating system (starting with Windows Vista, they are in the C:\Users folder):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-size:small;"&gt;C:\Windows\Temp&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:small;"&gt;C:\Windows\Prefetch&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:small;"&gt;C:\Documents and Settings\*\Local Settings\Temp&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-size:small;"&gt;C:\Users\*\Appdata\Local\Temp&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that I have defined our locations, I need to define what I want to do. For this, I create a flowchart:&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/6472.1.PNG"&gt;&lt;img style="border:0px currentColor;" title="Image of flowchart" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6472.1.PNG" alt="Image of flowchart" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I start with the &lt;strong&gt;Set-Location&lt;/strong&gt; command and define the location as &lt;strong&gt;&amp;ldquo;C:\Windows\Temp&amp;rdquo;&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set-Location &amp;ldquo;C:\Windows\Temp&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Now that I am located in the Windows temp folder, I need to delete the files. This can be done with the old DOS command &lt;strong&gt;Del&lt;/strong&gt;, but I prefer using the Windows Powershell cmdlet &lt;strong&gt;Remove-Item&lt;/strong&gt; to standardize the script. The items need to be removed indiscriminately, so I use a wildcard character. A wildcard character is a special character that represents one or more other characters. The question mark (&lt;strong&gt;?&lt;/strong&gt;) wildcard stands for one character and the asterisk (&lt;strong&gt;*&lt;/strong&gt;) wildcard stands for any number of characters. Because I do not want to discriminate between different files, I use the asterisk.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;Remove-Item *&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Next I tell the &lt;strong&gt;Remove-Item&lt;/strong&gt; cmdlet to also remove all files in subdirectories with the &lt;strong&gt;-recurse&lt;/strong&gt; switch:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;Remove-Item * -recurse&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And I tell it to select hidden files with the &lt;strong&gt;-force&lt;/strong&gt; switch:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;Remove-Item * -recurse -force&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Together the two lines looked like this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\Windows\Temp&amp;rdquo;&lt;br /&gt; Remove-Item * -recurse -force&lt;/p&gt;
&lt;p&gt;I do the same for the rest of the folders and the complete script begins to take shape:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\Windows\Temp&amp;rdquo;&lt;br /&gt; Remove-Item * -recurse -force&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\Windows\Prefetch&amp;rdquo;&lt;br /&gt; Remove-Item * -recurse -force&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\Documents and Settings&amp;rdquo;&lt;br /&gt; Remove-Item &amp;ldquo;.\*\Local Settings\temp\*&amp;rdquo; -recurse -force&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\Users&amp;rdquo;&lt;br /&gt; Remove-Item &amp;ldquo;.\*\Appdata\Local\Temp\*&amp;rdquo; -recurse -force&lt;/p&gt;
&lt;p&gt;Wait. Why is there an asterisk in the middle of the last path? You can use wildcard characters to do this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;Remove-Item &amp;ldquo;.\*\Appdata\Local\Temp\*&amp;rdquo; -recurse -force&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This says, &amp;ldquo;Look in all folders in this directory with the path structure that matches this.&amp;rdquo; In my case, this is all of the user profile Local Settings\temp folders.&lt;/p&gt;
&lt;p&gt;But this looks very busy, so at Ed Wilson&amp;rsquo;s suggestion, an array would prevent all the unnecessary jumping around with the &lt;strong&gt;Set-Location&lt;/strong&gt; command. So we change our flowchart to look something like this:&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/0218.2.PNG"&gt;&lt;img style="border:0px currentColor;" title="Image of flowchart" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/0218.2.PNG" alt="Image of flowchart" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:12px;"&gt;Arrays are a nifty programming feature that groups a number of strings together into one variable, while remaining individual strings. They are defined much like a normal variable&amp;mdash;they start with the variable (&lt;/span&gt;&lt;strong style="font-size:12px;"&gt;$&lt;/strong&gt;&lt;span style="font-size:12px;"&gt;) indicator followed by the array name:&lt;/span&gt;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;$tempfolders&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Just like a variable, I use the equal sign (&lt;strong&gt;=&lt;/strong&gt;) to define it.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;$tempfolders =&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here is where the arrays and variables differ when defining. I start with the array indicator (&lt;strong&gt;@&lt;/strong&gt;):&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;$tempfolders = @&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And I follow it with parentheses to group strings together:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;$tempfolders = @()&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;What you put inside the parentheses is your choice. For my purposes, I fill it with temp folder paths:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$tempfolders = @( &amp;quot;C:\Windows\Temp\*&amp;quot;, &amp;quot;C:\Windows\Prefetch\*&amp;quot;, &amp;quot;C:\Documents and Settings\*\Local Settings\temp\*&amp;quot;, &amp;quot;C:\Users\*\Appdata\Local\Temp\*&amp;quot; )&lt;/p&gt;
&lt;p&gt;Notice that each string is neatly encapsulated by double quotation marks (&lt;strong&gt;&amp;ldquo; &amp;rdquo;&lt;/strong&gt;) and separated by a comma and a space (&lt;strong&gt;, &lt;/strong&gt;). The quotation marks are necessary for any string with a space in it, and the comma with a space separates the values. Both are essential to define an array. Additionally you can see that each string ends with a wildcard character. This is going to remove the necessity for me to define exactly what to remove in the next line.&lt;/p&gt;
&lt;p&gt;Now I use the &lt;strong&gt;Remove-Item&lt;/strong&gt; cmdlet again; but this time for the &lt;strong&gt;-path&lt;/strong&gt; operator, I use the &lt;strong&gt;$tempfolders&lt;/strong&gt; array variable:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:small;"&gt;Remove-Item $tempfolders -force -recurse&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;This line instructs Windows Powershell to do exactly the same as previously, but for every item in the array.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;Side-by-side, here are the two versions of the script:&lt;/span&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1 Set-Location &amp;ldquo;C:\Windows\Temp&amp;rdquo;&lt;/p&gt;
&lt;p&gt;2 Remove-Item * -recurse -force&lt;/p&gt;
&lt;p&gt;3 Set-Location&lt;/p&gt;
&lt;p&gt;4 &amp;ldquo;C:\Windows\Prefetch&amp;rdquo;&lt;/p&gt;
&lt;p&gt;5 Remove-Item * -recurse -force&lt;/p&gt;
&lt;p&gt;6 Set-Location &amp;ldquo;C:\Documents and Settings&amp;rdquo;&lt;/p&gt;
&lt;p&gt;7 Remove-Item &amp;ldquo;.\*\Local&lt;/p&gt;
&lt;p&gt;8 Settings\temp\*&amp;rdquo; -recurse -force&lt;/p&gt;
&lt;p&gt;9 Set-Location &amp;ldquo;C:\Users&amp;rdquo;&lt;/p&gt;
&lt;p&gt;10 Remove-Item &amp;ldquo;.\*\Appdata\Local\Temp\*&amp;rdquo; -recurse -force&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1 $tempfolders = @(&amp;quot;C:\Windows\Temp\*&amp;quot;, &amp;quot;C:\Windows\Prefetch\*&amp;quot;, &amp;quot;C:\Documents and Settings\*\Local Settings\temp\*&amp;quot;, &amp;quot;C:\Users\*\Appdata\Local\Temp\*&amp;quot;)&lt;/p&gt;
&lt;p&gt;2 Remove-Item $tempfolders -force -recurse&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;With two lines of code, I was able to save myself between three minutes and 30 minutes of work. This is the purpose of scripting at its finest: automate repetitive tasks to allow the technician to do more in-depth work. Thank you all for reading, and as always, let me know if you have developed a better way!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size:small;"&gt;~Bob&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Bob, thanks again for a real world example and a great suggestion. Join us tomorrow for a blog post by Boe Prox about installing WSUS on Windows Server 2012. It is a great blog and I am sure you will enjoy 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=3564151" width="1" height="1" alt="" /&gt;</description></item><item><title>Weekend Scripter: Pick Comments from a PowerShell Script</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2013/04/13/weekend-scripter-pick-comments-from-a-powershell-script.aspx</link><pubDate>Sat, 13 Apr 2013 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:22793</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;: Guest blogger, Bob Stevens, shares a script to pick out comments from a Windows PowerShell script.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy, Ed Wilson, is here. Today we have a new guest blogger, Bob Stevens. I made Bob&amp;rsquo;s virtual acquaintance recently when I did a Live Meeting presentation to the &lt;a href="http://www.tcposhug.com/" target="_blank"&gt;Twin Cities PowerShell User Group.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is Bob&amp;rsquo;s contact information:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;span style="font-size:12px;"&gt;Blog: &lt;/span&gt;&lt;a href="http://stuckinmypowershell.blogspot.com/" target="_blank"&gt;Help! I&amp;rsquo;m Stuck in My Powershell!&lt;/a&gt;&lt;br /&gt; Twitter: &lt;a href="https://twitter.com/B_stevens6" target="_blank"&gt;@B_stevens6&lt;/a&gt;&lt;br /&gt; LinkedIn: &lt;a href="http://www.linkedin.com/profile/edit?trk=hb_tab_pro_top" target="_blank"&gt;Robert Stevens&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The floor is yours, Bob&amp;hellip;&lt;/p&gt;
&lt;p&gt;As a local Help Desk technician, I run into many repetitive support tasks. From low toners to Internet Explorer issues, I have done it all. About three months ago I discovered that I could use PowerShell to automate a number of these tasks, thereby freeing my time for some of the more unusual issues. Fortunately, all of the computers at my site have Windows PowerShell&amp;nbsp;2.0 installed, so it was a matter of ensuring that they can run scripts. This can be done by changing the &lt;strong&gt;Set-ExecutionPolicy&lt;/strong&gt; cmdlet to &lt;strong&gt;Unrestricted&lt;/strong&gt; in the following manner:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-ExecutionPolicy Unrestricted&lt;/p&gt;
&lt;p&gt;When the work is done, switch it back to the organization default with:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-ExecutionPolicy Remote-Signed&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Set-ExecutionPolicy&lt;/strong&gt; governs which scripts can be run on any given system. By setting it as &lt;strong&gt;Unrestricted&lt;/strong&gt;, I am removing all restrictions. I switch it back to &lt;strong&gt;Remote-Signed&lt;/strong&gt; to prevent users from running scripts that can potentially damage a system, thereby presenting a potential for data loss.&lt;/p&gt;
&lt;p&gt;Fast forward three months and multiple scripts later&amp;hellip;&lt;/p&gt;
&lt;p&gt;It dawned on me that I would need to create documentation for each of these scripts. Documentation provides my coworkers with the insight they need to understand the purpose and functionality of my work and to pick up where I left off should the script need to be altered. Thankfully, like a good Windows PowerShell scripter, I commented liberally throughout my scripts to ensure that I knew where I would need to alter it in the future. To this end I started working on a script to pull comments. I knew that I habitually use single line comments for documentation and block comments for commenting out blocks of code. Happy accident because the script I devised only pulls the first and the last lines of a block comment.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&lt;strong&gt;Note&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;For simplicity, I name all directories a variation of &lt;strong&gt;&amp;ldquo;foo&amp;rdquo;&lt;/strong&gt; and all input files a variation of &lt;strong&gt;&amp;ldquo;foo.*&amp;rdquo;&lt;/strong&gt;. You can set foo as whatever you want.&lt;/p&gt;
&lt;p&gt;As usual I started with setting my location:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;ldquo;C:\foo&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Next we set our source script file as a variable. I use variables in my scripts to enable me to change one line of code, rather than five lines, thereby reducing the chance of an error. Variables are defined by the dollar sign (&lt;strong&gt;$&lt;/strong&gt;).&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$script = &amp;ldquo;foo.ps1&amp;rdquo;&lt;/p&gt;
&lt;p&gt;We need to define an output variable as &lt;strong&gt;$out&lt;/strong&gt;. Note that I used the &lt;strong&gt;$script&lt;/strong&gt; variable in the variable value. This will result in the file name of &lt;strong&gt;foo.ps1 comments.txt&lt;/strong&gt;. This is to differentiate between output files. For this to work, there must be a space between &lt;strong&gt;$script&lt;/strong&gt; and &lt;strong&gt;comments.txt&lt;/strong&gt;:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$out = &amp;ldquo;$script comments.txt&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Now that we have defined the output file name, we need to create the output file itself, and I do this with the &lt;strong&gt;New-Item&lt;/strong&gt; cmdlet. Of course, we need to define the object as a file&amp;mdash;otherwise we get a dialog box asking us if it&amp;rsquo;s a file or folder:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Item &amp;ldquo;out&amp;rdquo; -ItemType File&lt;/p&gt;
&lt;p&gt;Now our preparation is complete:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;quot;c:\foo&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$script = &amp;quot;foo.ps1&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$out = &amp;quot;$script comments.txt&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Item &amp;quot;$out&amp;quot; -ItemType File&lt;/p&gt;
&lt;p&gt;We need to pull the content of our source file with the &lt;strong&gt;Get-Content&lt;/strong&gt; cmdlet:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Content $script&lt;/p&gt;
&lt;p&gt;The next line is to prevent Windows PowerShell from appending the output to output that already exists in the variable by creating an array, this is done with the array (&lt;strong&gt;@&lt;/strong&gt;) operator, followed by both parentheses:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments = @()&lt;/p&gt;
&lt;p&gt;This is where the magic takes place. We need to use the &lt;strong&gt;Select-String&lt;/strong&gt; cmdlet. This command requires two parameters: &lt;strong&gt;Pattern&lt;/strong&gt; and &lt;strong&gt;File&lt;/strong&gt;. Both values need to be quoted if you are not using a variable to define it. As we are searching for comments, we are going to select strings that contain &lt;strong&gt;&amp;ldquo;#&amp;rdquo;&lt;/strong&gt;:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String -Pattern &amp;ldquo;#&amp;rdquo; $script&lt;/p&gt;
&lt;p&gt;This is a bit more complex, and it requires stringing three commands together, so we use the pipe (&lt;strong&gt;|&lt;/strong&gt;) operator. The pipe operator merely states do &amp;ldquo;this&amp;rdquo; and then do &amp;ldquo;that&amp;rdquo; with the output of &amp;ldquo;this.&amp;rdquo; Pipe operators must always have a space preceding and succeeding it:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String -Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p&gt;For our purposes, we are going to say, &amp;ldquo;For each object, do this.&amp;rdquo; Coincidentally (or not), Microsoft decided to add a &lt;strong&gt;Foreach-Object&lt;/strong&gt; cmdlet for just this purpose! And everything that you are doing with &lt;strong&gt;Foreach-Object&lt;/strong&gt; must be in braces to group them together:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String - Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {}&lt;/p&gt;
&lt;p&gt;When we string commands like this together, formatting is important&amp;mdash;not for functionality, but for readability. Now we need to comment the full line where &lt;strong&gt;&amp;ldquo;#&amp;rdquo;&lt;/strong&gt; appears. It is important to note that you must use &lt;strong&gt;&amp;ldquo;+=&amp;rdquo;&lt;/strong&gt;, or you will end up with an empty file:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String - Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;We need to tell Windows PowerShell to grab everything after &lt;strong&gt;&amp;ldquo;#&amp;rdquo; &lt;/strong&gt;in that string. This is tricky, but it can be done with the &lt;strong&gt;context.postcontext&lt;/strong&gt; definition:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String - Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.context.postcontext&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p&gt;We now need to tell Windows PowerShell to extract everything that we just defined within the &lt;strong&gt;Foreach-Object&lt;/strong&gt; curly brackets:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String - Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.context.postcontext&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments&lt;/p&gt;
&lt;p&gt;Finally, we dump our output into the output file &lt;strong&gt;$out&lt;/strong&gt; with the &lt;strong&gt;Set-Content&lt;/strong&gt; cmdlet:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String - Pattern &amp;ldquo;#&amp;rdquo; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.context.postcontext&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments | Set-Content $out&lt;/p&gt;
&lt;p&gt;The complete script looks something like this:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Location &amp;quot;c:\foo&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$script = &amp;quot;foo.ps1&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$out = &amp;quot;$script comments.txt&amp;quot;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;New-Item &amp;quot;$out&amp;quot; -ItemType File&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Get-Content $script&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments = @()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Select-String -Pattern &amp;quot;#&amp;quot; $script |&lt;/p&gt;
&lt;p style="padding-left:60px;"&gt;Foreach-Object {&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.line&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments += $_.context.postcontext&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$comments | Set-Content $out&lt;/p&gt;
&lt;p&gt;The result should take the following input:&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/3426.wes_2D00_4_2D00_13_2D00_13_2D00_1.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/3426.wes_2D00_4_2D00_13_2D00_13_2D00_1.png" alt="Image of script" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And give you the following output (&lt;strong&gt;Select-String -pattern &amp;ldquo;#&amp;rdquo;&lt;/strong&gt; shows up because it contains a &lt;strong&gt;&amp;ldquo;#&amp;rdquo;&lt;/strong&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/5773.wes_2D00_4_2D00_13_2D00_13_2D00_2.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/5773.wes_2D00_4_2D00_13_2D00_13_2D00_2.png" alt="Image of command output" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This saved me an hour now and countless future hours that I would spend extracting comments for documentation.&lt;/p&gt;
&lt;p&gt;When I was verifying my work, I ran across the following note to myself stating that I referenced a Rob Campbell in another script. Some of the code made it in here.&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Rob Campbell, Mjolinor: &lt;a href="http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/b41bfe7f-2ec3-428e-8a79-962afa076067/" target="_blank"&gt;How do you extract data from a txt file with powershell&lt;/a&gt;. As always, input is always appreciated.&lt;/p&gt;
&lt;p&gt;Thank you for your time.&amp;nbsp;I uploaded the complete script to the Script Center Repository: &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/Extracting-comments-from-a-149af1ea" target="_blank"&gt;Extracting Comments from a Script with PowerShell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;~Bob&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Thank you, Bob, for sharing your script and your insight with us today. Join us tomorrow when Bob talks about a script he wrote to clean up user profiles. It is 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;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=3564133" width="1" height="1" alt="" /&gt;</description></item></channel></rss>