<?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 'Windows PowerShell', 'Microsoft Excel', and 'guest blogger'</title><link>http://powershell.com/cs/search/SearchResults.aspx?q=app:weblogs&amp;tag=Windows+PowerShell,Microsoft+Excel,guest+blogger&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'Windows PowerShell', 'Microsoft Excel', and 'guest blogger'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Use PowerShell to Work with Pictures in Microsoft Excel</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/08/12/use-powershell-to-work-with-pictures-in-microsoft-excel.aspx</link><pubDate>Fri, 12 Aug 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:11833</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Guest Blogger Robert Robelo shows how to use Windows PowerShell to work with images in Microsoft Excel.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. Our guest blogger today is Robert Robelo. First, I want to give Robert a chance to tell us a little bit about himself.&lt;/p&gt;
&lt;p&gt;I live in Nicaragua. I have been an incomplete quadriplegic (paralyzed from the chest down, but have limited mobility in upper limbs) for more than twenty years. Because of that I have not had a job since then. Before I got shot, I was an officer in the Nicaraguan Resistance Army, better known as Contras. One of my multiple responsibilities was to train, support, and maintain the IT structure (guess that would be a chief information officer), which was no more than twenty individual machines. My other responsibilities included intelligence, counterintelligence, and friendly forces liaison officer; obviously, before becoming an officer, I was an infantry and artillery soldier. I later became a sniper.&lt;/p&gt;
&lt;p&gt;Robert is going to talk to us about working with images in Microsoft Excel via Windows PowerShell. Take it away, Robert!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Inserting an image in an Excel spreadsheet with Windows PowerShell is not an everyday chore for IT pros, but there very well may come a time where it would be useful to know how to do such a task.&lt;/p&gt;
&lt;p&gt;An Excel spreadsheet has a &lt;b&gt;Shapes&lt;/b&gt; property; it holds a collection of objects in the drawing layer, such as AutoShapes, freeforms, OLE objects, and images. To insert an image in the spreadsheet, use the &lt;b&gt;Shapes &lt;/b&gt;collection&amp;#39;s &lt;b&gt;AddPicture &lt;/b&gt;method. This method takes seven required arguments, which are shown in the following figure.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The &lt;b&gt;AddPicture&lt;/b&gt; method returns a &lt;b&gt;Shape&lt;/b&gt; object, which should be assigned to a variable. The &lt;b&gt;Shape&lt;/b&gt; can then be relocated, resized, rotated, transformed, cropped, formatted, duplicated, and so on.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s fire up an Excel instance, get a new workbook, and grab the ever-present Sheet1. Before we do that, let&amp;#39;s set up a few &lt;b&gt;Constant&lt;/b&gt; variables. First, the &lt;b&gt;MsoTriState&lt;/b&gt; constants that apply to the &lt;b&gt;AddPicture&lt;/b&gt; method and then a couple &lt;b&gt;Constant&lt;/b&gt; variables of our own. These will hold the default width and height of a cell; they can be very useful to place and size the image we are going to insert. However, they are not necessary if you prefer to place and size the image with greater accuracy. In this sample, we will place the image&amp;#39;s upper left corner in cell C3&amp;#39;s upper left corner&amp;mdash;that is two cells from the left and two cells from the top of the sheet, and we will make the image two cells wide and four cells tall. (&lt;b&gt;Note&lt;/b&gt;&amp;nbsp; &amp;nbsp;The image path is set to C:\Ensign.jpg; you can substitute this with your own image or &lt;a href="https://skydrive.live.com/embedicon.aspx/.Public/PowerShell/Blog/TestExcelDemo.zip?cid=1d7fe2f4a61d31e1"&gt;download the .zip file&lt;/a&gt; that contains that image as part of a test kit. Read more below.)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# Excel Constants&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# MsoTriState&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Variable msoFalse 0 -Option Constant -ErrorAction SilentlyContinue&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Variable msoTrue 1 -Option Constant -ErrorAction SilentlyContinue&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# own Constants&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# cell width and height in points&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Variable cellWidth 48 -Option Constant -ErrorAction SilentlyContinue&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Set-Variable cellHeight 15 -Option Constant -ErrorAction SilentlyContinue&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$xl = New-Object -ComObject Excel.Application -Property @{&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;Visible = $true&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;DisplayAlerts = $false&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;}&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wb = $xl.WorkBooks.Add()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$sh = $wb.Sheets.Item(&amp;#39;Sheet1&amp;#39;)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# arguments to insert the image through the Shapes.AddPicture Method&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$imgPath = &amp;#39;C:\Ensign.jpg&amp;#39;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$LinkToFile = $msoFalse&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$SaveWithDocument = $msoTrue&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Left = $cellWidth * 2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Top = $cellHeight * 2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Width = $cellWidth * 2&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$Height = $cellHeight * 4&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# add image to the Sheet&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$img = $sh.Shapes.AddPicture($imgPath, $LinkToFile, $SaveWithDocument,&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;$Left, $Top, $Width, $Height)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$xl.Speech.Speak(&amp;#39;Add an image to the Sheet through the Add Picture Method.&amp;#39;)&lt;/p&gt;
&lt;p&gt;Pretty easy, isn&amp;#39;t it? You can examine the &lt;b&gt;Shape &lt;/b&gt;object with the &lt;a href="http://technet.microsoft.com/en-us/library/dd315351.aspx"&gt;&lt;b&gt;Get-Member&lt;/b&gt;&lt;/a&gt; cmdlet to see the different methods and properties it has. There are too many to explore in one blog post anyway.&lt;/p&gt;
&lt;p&gt;Now, let&amp;#39;s close the workbook without saving it, quit Excel, and clean up its insubordinate instance with the &lt;a href="http://wp.me/p15IqD-2Y"&gt;&lt;b&gt;Remove-ComObject&lt;/b&gt; function&lt;/a&gt;. Basically, the &lt;b&gt;Remove-ComObject&lt;/b&gt; function collects all variables that were assigned &lt;b&gt;System.__ComObject&lt;/b&gt; objects within the caller scope and are not &lt;b&gt;Constant&lt;/b&gt; or &lt;b&gt;Read-Only&lt;/b&gt; variables:&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;# close without saving the workbook&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$wb.Close($false)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$xl.Quit()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;Remove-ComObject&lt;/p&gt;
&lt;p&gt;There are many techniques that attempt to release these defiant &lt;b&gt;System.__ComObject&lt;/b&gt; objects. Some do get the job done eventually, but they look chaotic or involve repeated calls to &lt;b&gt;Runtime.Interopservices.Marshal&lt;/b&gt;&amp;#39;s &lt;b&gt;ReleaseComObject&lt;/b&gt; method. Using the &lt;a href="http://technet.microsoft.com/en-us/library/dd347612.aspx"&gt;&lt;b&gt;Remove-Variable&lt;/b&gt;&lt;/a&gt; cmdlet the traditional way to get rid of these vestigial &lt;b&gt;System.__ComObject&lt;/b&gt; objects will not suffice either, but using it as I do in the &lt;b&gt;Remove-ComObject&lt;/b&gt; function, this capricious cmdlet does its job very well with a little help from its friends.&lt;/p&gt;
&lt;p&gt;First, the &lt;b&gt;Remove-ComObject&lt;/b&gt; function briefly pauses for half a second to let Windows PowerShell mark the &lt;b&gt;System.__ComObject&lt;/b&gt; object as &lt;b&gt;Disposed&lt;/b&gt; and ready to be collected by the &lt;b&gt;Garbage Collector&lt;/b&gt;. Next, a variable is set with the &lt;b&gt;Management.Automation.ScopedItemOptions&lt;/b&gt; &lt;b&gt;ReadOnly&lt;/b&gt; and &lt;b&gt;Constant&lt;/b&gt; enumerations. This variable will be the second half of the filter that will be applied in the following step. Then, the &lt;a href="http://technet.microsoft.com/en-us/library/dd315260.aspx"&gt;&lt;b&gt;Get-Variable&lt;/b&gt;&lt;/a&gt; cmdlet fetches all variables in the caller scope (&lt;b&gt;-Scope 1&lt;/b&gt;) and pipes them to the &lt;a href="http://technet.microsoft.com/en-us/library/dd315399.aspx"&gt;&lt;b&gt;Where-Object&lt;/b&gt;&lt;/a&gt; cmdlet, where a filter is applied to exclude &lt;b&gt;Constant&lt;/b&gt; or &lt;b&gt;Read-Only&lt;/b&gt; variables, but whose value are of type &lt;b&gt;System.__ComObject&lt;/b&gt;. This first half of the filter is done by comparing the value&amp;#39;s &lt;b&gt;PSTypeNames&lt;/b&gt; collection against the string &lt;b&gt;&lt;i&gt;System.__ComObject&lt;/i&gt;&lt;/b&gt; with the &lt;b&gt;Contains&lt;/b&gt; operator. The unfortunate and rebellious variables that go through are then piped to the &lt;a href="http://technet.microsoft.com/en-us/library/dd347612.aspx"&gt;&lt;b&gt;Remove-Variable&lt;/b&gt;&lt;/a&gt; cmdlet and are slyly shredded to oblivion. Finally, the &lt;b&gt;Garbage Collector&lt;/b&gt; gets a call to sanitize the area and collect the scraps.&lt;/p&gt;
&lt;p&gt;The &lt;b&gt;Remove-ComObject&lt;/b&gt; function is an advanced function because it has common parameters, which permits the user to use its &lt;b&gt;Verbose&lt;/b&gt; flag to divulge which variables were removed. I do want to point out a very important fact: the &lt;b&gt;Remove-ComObject&lt;/b&gt; function removes all variables declared in the function&amp;#39;s caller scope. It is safer to use it within scripts, functions, or modules, but you can also call it from the command line. Just beware that you may wipe out other &lt;b&gt;System.__ComObject&lt;/b&gt; objects. This is the reason the function excludes &lt;b&gt;Constant&lt;/b&gt; or &lt;b&gt;Read-Only&lt;/b&gt; variables. It is up to you to declare those precious variables as such.&lt;/p&gt;
&lt;p&gt;I have set up a test that demonstrates the efficacy of my technique to successfully release &lt;b&gt;System.__ComObject &lt;/b&gt;objects before they become ghosts in your machine. You can download the test kit &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/0243fe68-4c55-4018-bf66-7f5498c10bbd"&gt;here&lt;/a&gt;; the results are displayed in the console. The test will show RAM usage and Excel processes running before and after the execution of two scripts, one that cleans up with a &lt;b&gt;Remove-ComObject&lt;/b&gt; call and another that does not. These scripts also demonstrate other image manipulation that you might find interesting. Unzip the contents to your favorite test directory, run &lt;b&gt;TestExcelDemo.ps1&lt;/b&gt;, watch and listen. It is less than five minutes. Excel 2010 or Excel 2007 is required.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Robert, I want to thank you for writing a really cool script, and for sharing your Windows PowerShell goodness with us.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3445205" width="1" height="1" alt="" /&gt;</description></item><item><title>Use a PowerShell Module to Easily Export Excel Data to CSV</title><link>http://powershell.com/cs/blogs/hey-scriptingguy/archive/2011/07/21/use-a-powershell-module-to-easily-export-excel-data-to-csv.aspx</link><pubDate>Thu, 21 Jul 2011 05:00:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:11493</guid><dc:creator>Anonymous</dc:creator><description>&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: Learn how to use a Windows PowerShell module to easily import and export Excel data.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Microsoft Scripting Guy Ed Wilson here. Jeremy Engel has joined us today to talk about using a Windows PowerShell module to easily import and export Excel data.&lt;/p&gt;
&lt;p&gt;Take it away, Jeremy!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I started coding at the age of 10, writing games in BASIC for my lightning-fast Commodore 64. From there I ventured into the high-tech world of text-based online gaming, affectionately known as MUDs&amp;mdash;specifically EverDark, where I learned to write C++ code. Later, I made the jump to systems engineering, and it was there that I discovered scripting. I loathe repetitive tasks and have a great love for efficiency (I&amp;rsquo;m lazy). Therefore, I can find ways to incorporate Windows PowerShell into almost every project and task I do as a systems engineer. I am also known to write the occasional application or service in &lt;a href="http://www.microsoft.com/express/vcsharp/Default.aspx" target="_blank"&gt;&lt;b&gt;Visual C#&lt;/b&gt;&lt;/a&gt;, which is mutually reinforcing with Windows PowerShell because they are essentially different expressions of the same language. Now for today&amp;rsquo;s blog post. Hope you like it.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;br /&gt;Excel to Windows PowerShell and Back Again&lt;/b&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ever wish you could import from and export to Excel just like you can using CSV files? So did I, and so did a lot of other people, as I discovered.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Back during Tech∙Ed this year, it seemed like I spent an entire day griping about this blatant disparity between reality and my imagination. Not that I kept bringing it up (I swear I did not!), but that it kept coming up in conversation. You know, like one of those weird days where the same esoteric word finds its way into a multitude of conversations, only to then never be heard of again until the next cosmic kink in the space-time continuum.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Anyway, during dinner that night, it came up again. I casually blurt out that it is ridiculous that there are not any such functions, and how I could code them in a single night! Then it struck me&amp;mdash;I actually think I &lt;i&gt;could&lt;/i&gt; code them in a single night. Before I realized it, I was announcing my plans to the group of fellow Windows PowerShell scripters. So realizing I was losing hours, I dashed home by 8:30 P.M. and set to work. By 1:00 A.M., I had two fairly well fleshed-out cmdlets, but more importantly, they worked!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The complete &lt;a href="http://gallery.technet.microsoft.com/scriptcenter/7b2fdc8f-a528-4f19-b9ef-f5af349dc906"&gt;Excel module can be downloaded&lt;/a&gt; from the Scripting Guys Script Repository.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As a basis for understanding how the conversion between Excel and Windows PowerShell works, think of each row in an Excel spreadsheet as an object in Windows PowerShell with the names of each column in Excel being a property name of the object in Windows PowerShell.&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/6886.HSG_2D00_7_2D00_21_2D00_11_2D00_1.jpg"&gt;&lt;img style="border:0px;" title="Image of how Excel spreadsheets correlate to objects in Windows PowerShell" alt="Image of how Excel spreadsheets correlate to objects in Windows PowerShell" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6886.HSG_2D00_7_2D00_21_2D00_11_2D00_1.jpg" width="523" height="193" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So if the value for A1 is &lt;b&gt;Example1&lt;/b&gt; and the value for A2 is &lt;b&gt;test&lt;/b&gt;, in PowerShell:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$row.Example1 = &amp;ldquo;test&amp;rdquo;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If the value for A3 is &lt;b&gt;ubu&lt;/b&gt;, in Windows PowerShell:&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$row.Example1 = &amp;ldquo;ubu&amp;rdquo;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Each row object is then appended to an array of these objects, eventually representing the entire spreadsheet in Windows PowerShell object form.&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/6102.HSG_2D00_7_2D00_21_2D00_11_2D00_2.jpg"&gt;&lt;img style="border:0px;" title="Image of spreadsheet in Windows PowerShell object form" alt="Image of spreadsheet in Windows PowerShell object form" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6102.HSG_2D00_7_2D00_21_2D00_11_2D00_2.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Got it? When you understand this, it becomes easy to see how we could move from Excel to Windows PowerShell and back again. All that is left then is to work out the mechanics.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I really wanted this to be Excel-independent, meaning that I wanted to read an Excel document as an XML file and vice versa. I was able to get the export cmdlet to work fine writing to XML, but I was not able to figure out how to get the Excel XML to do an import&amp;mdash;it was all just a jumbled mess. So unfortunately, I had to stick with the &amp;ldquo;wonderful&amp;rdquo; COM object.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Honestly, COM objects are not that bad. They just look really bad when you&amp;rsquo;re expecting them to be as flexible, transparent, fast, and disposable as Windows PowerShell objects. That aside, they do have a fair amount of useful methods and properties, which I make use of in these two cmdlets. I will not elucidate them all here, but just show you some of the important ones.&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$excel = New-Object -ComObject Excel.Application&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$workbook = $excel.Workbooks.Open($Path)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$sheet = $workbook.Worksheets.Item(1)&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see, I am creating an instance of the &lt;b&gt;Excel.Application&lt;/b&gt; object and then opening the workbook located at &lt;b&gt;$Path&lt;/b&gt; and from there retrieving the first worksheet. What do you mean you have Excel workbooks with more than one worksheet? Okay, I&amp;rsquo;ll work on an enhancement later. When, you ask? Later.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here is another quirk about COM objects. If you take those first two lines of Windows PowerShell code shown above and open up Excel workbook, you&amp;rsquo;ll notice that typing $workbook.Worksheets in Windows PowerShell looks like it shows you an array of worksheet objects. Alas, no, it is actually another COM object. So I couldn&amp;rsquo;t just pull the object for sheet 1 by doing &lt;b&gt;$workbook.Worksheets[0]&lt;/b&gt;; I had to use a COM method called &lt;b&gt;Item()&lt;/b&gt;. Fun, huh?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One last bit on COM objects. Apparently, COM objects are like that quasihomeless guy who sleeps on your couch. They are extremely hard to get rid of. I alluded to the problem in the preceding paragraph, which is that COM objects like to return more COM objects, rather than property values. So you think you may be querying a value, when what you&amp;rsquo;re getting is a sneaky cockroach of a COM object.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Because of that, in each cmdlet I had to go through and try to repeatedly wipe out each object of the COM before finally killing the mothership. And wow, in doing my previous example on the worksheets, I just realized that even though I wasn&amp;rsquo;t saving the COM object references for workbooks and worksheets to Windows PowerShell variables, they were still lying out there. That is why I was sometimes having trouble killing the Excel process. So I had to adjust my script slightly to release those as well!&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$workbooks = $excel.Workbooks&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$workbook = $workbooks.Open($Path)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$worksheets = $workbook.Worksheets&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$sheet = $worksheets.Item(1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($columns) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($rows) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($range) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($sheet) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($worksheets) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$workbook.Close($false)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($workbook) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($workbooks) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;$excel.Quit()&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;do { $o = [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) } while($o -gt -1)&lt;/p&gt;
&lt;p style="padding-left:30px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It isn&amp;rsquo;t pretty, but it gets the job done.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I tried to make the &lt;b&gt;Import-Excel&lt;/b&gt; cmdlet as flexible as possible, knowing how people often have messy spreadsheets. So I needed to account for situations when all of the columns were missing headers (the &lt;b&gt;NoHeaders&lt;/b&gt; switch), or if only some of the columns had no headers. Under the latter situation, could also fall stray cells out in the middle of nowhere. I didn&amp;rsquo;t want to make value-judgments on any of that data; I just wanted to make sure I could logically ingest it into Windows PowerShell. To do that, the &lt;b&gt;Import-Excel&lt;/b&gt; script creates generic property names for missing headers.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the previous screen shots, did you notice how the Excel document had no header for column B? The cmdlet noticed that too and gave it a generic property name, in this case: &lt;b&gt;Column2&lt;/b&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After you have imported the spreadsheet, you can manipulate the objects just like any other in Windows PowerShell. In the following figure, I fill in item 3&amp;rsquo;s &lt;b&gt;Example1&lt;/b&gt; value.&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/4846.HSG_2D00_7_2D00_21_2D00_11_2D00_3.jpg"&gt;&lt;img style="border:0px;" title="Image of manipulating the object" alt="Image of manipulating the object" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/4846.HSG_2D00_7_2D00_21_2D00_11_2D00_3.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the following figure, I add an entirely new item to the object array.&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/1307.HSG_2D00_7_2D00_21_2D00_11_2D00_4.jpg"&gt;&lt;img style="border:0px;" title="Image of adding new item to object array" alt="Image of adding new item to object array" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/1307.HSG_2D00_7_2D00_21_2D00_11_2D00_4.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Converse to &lt;b&gt;Import-Excel&lt;/b&gt; is &lt;b&gt;Export-Excel&lt;/b&gt;, which takes an array of objects and writes them to an Excel file. For a little flare, I added in the ability to make the header row bold, and also gave you three choices of bottom border, if so desired.&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/6560.HSG_2D00_7_2D00_21_2D00_11_2D00_5.jpg"&gt;&lt;img style="border:0px;" title="Image of writing objects to an Excel file" alt="Image of writing objects to an Excel file" src="http://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/6560.HSG_2D00_7_2D00_21_2D00_11_2D00_5.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And that, my friends, is how a self-imposed dare is won!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thank you, Jeremy, this is a great post, and I look forward to using your new Excel module.&lt;/p&gt;
&lt;p&gt;I invite you to follow me on &lt;a href="http://bit.ly/scriptingguystwitter" target="_blank"&gt;Twitter&lt;/a&gt; and &lt;a href="http://bit.ly/scriptingguysfacebook"&gt;Facebook&lt;/a&gt;. If you have any questions, send email to me at &lt;a href="mailto:scripter@microsoft.com" target="_blank"&gt;scripter@microsoft.com&lt;/a&gt;, or post your questions on the &lt;a href="http://bit.ly/scriptingforum" target="_blank"&gt;Official Scripting Guys Forum&lt;/a&gt;. See you tomorrow. Until then, peace.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Ed Wilson, Microsoft Scripting Guy&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3441747" width="1" height="1" alt="" /&gt;</description></item></channel></rss>