{"id":49663,"date":"2010-05-22T00:01:00","date_gmt":"2010-05-22T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/05\/22\/hey-scripting-guy-weekend-scripter-using-windows-powershell-to-compress-folders\/"},"modified":"2010-05-22T00:01:00","modified_gmt":"2010-05-22T00:01:00","slug":"hey-scripting-guy-weekend-scripter-using-windows-powershell-to-compress-folders","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-weekend-scripter-using-windows-powershell-to-compress-folders\/","title":{"rendered":"Hey, Scripting Guy! Weekend Scripter: Using Windows PowerShell to Compress Folders"},"content":{"rendered":"<p><img decoding=\"async\" height=\"16\" width=\"125\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" alt=\"Bookmark and Share\">\n&nbsp;<\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. It is another beautiful weekend in Charlotte, North Carolina. I enjoy getting up early on the weekend, having a leisurely breakfast, reading for a little while, and then heading up to my office to write some scripts. I have a white board upon which I write down ideas for scripts that I wish to write. The idea for today&rsquo;s script actually came from Twitter a few days ago. The question was &ldquo;How can I use Windows PowerShell to compress a folder?&rdquo; I did a search of the Scripting Guys blog, and found a <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2006\/07\/06\/how-can-i-create-a-compressed-folder-and-add-files-to-it.aspx\"><span style=\"font-family: Segoe\">VBScript that uses the compress method<\/span><\/a> from the <b>Win32_Directory<\/b> WMI class. I decided to play around with that idea, and came up with a pretty cool script. The complete CreateCompressedFolderAndCopyFiles.ps1 script is seen here.<\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>CreateCompressedFolderAndCopyFiles.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"MsoNormal\"><span style=\"background-color: #f1f1ef\">Param(<br \/>&nbsp;$compressedFolder = &#8220;C:compressedFSO&#8221;,<br \/>&nbsp;$pathForFiles = &#8220;C:fso&#8221;,<br \/>&nbsp;$computer = &#8220;localhost&#8221;<br \/>) #end param<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"background-color: #f1f1ef\">function test-andCreateFolder($computer, $compressedFolder)<br \/>{<br \/>&nbsp;if(-not(test-path -Path $compressedFolder))<br \/>&nbsp; {<br \/>&nbsp;&nbsp; New-Item -Path $compressedFolder -ItemType directory<br \/>&nbsp;&nbsp; compress-folder -computer $computer -compressedFolder $compressedFolder<br \/>&nbsp; }<br \/>&nbsp;else { compress-folder -computer $computer -compressedFolder $compressedFolder }<br \/>} #end function test-andCreateFolder<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"background-color: #f1f1ef\">function compress-folder($computer, $compressedFolder)<br \/>{<br \/>&nbsp;$rtn = `<br \/>([wmi]&#8221;<\/span><span style=\"background-color: #f1f1ef\">\\$computerrootcimv2:win32_directory.name=&#8217;$compressedFolder&#8217;<\/span><span style=\"background-color: #f1f1ef\">&#8220;).`<br \/>compress()<br \/>&nbsp;if($rtn.returnvalue -eq 0) { &#8220;$compressedFolder successfully compressed&#8221;}<br \/>&nbsp;else { &#8220;$($rtn.returnvalue) error occurred compressing $compressedFolder&#8221;;exit}<br \/>} #end function compress-folder<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"background-color: #f1f1ef\"># *** entry point to script ***<\/span><\/p>\n<p class=\"MsoNormal\"><span style=\"background-color: #f1f1ef\">test-andCreateFolder -compressedFolder $compressedFolder -computer $computer<br \/>Copy-Item -Path $pathForFiles -Destination $compressedFolder -Include * -Recurse<\/span><\/p>\n<p class=\"MsoNormal\">The CreateCompressedFolderAndCopyFiles.ps1 script accepts three parameters from the command line when it is run. The first parameter is the path to the folder you wish to compress. The second parameter is the path to the source files, and the last parameter is the name of your computer. The parameters are shown here:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">Param(<br \/><span>&nbsp;<\/span>$compressedFolder = &#8220;C:compressedFSO&#8221;,<br \/><span>&nbsp;<\/span>$pathForFiles = &#8220;C:fso&#8221;,<br \/><span>&nbsp;<\/span>$computer = &#8220;localhost&#8221;<br \/>) #end param<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">After the parameters have been created, the script moves to the functions. The first function looks for the folder that will be compressed and that will store the files to be compressed. It initially uses the <b>Test-Path<\/b> cmdlet to see if the folder exists. If the folder does not exist, it creates the folder and calls the <b>compress-folder<\/b> function. If the folder does exist, it simply calls the <b>compress-folder<\/b> function. This function is shown here:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">function test-andCreateFolder($computer, $compressedFolder)<br \/>{<br \/><span>&nbsp;<\/span>if(-not(test-path -Path $compressedFolder))<br \/><span>&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp; <\/span>New-Item -Path $compressedFolder -ItemType directory<br \/><span>&nbsp;&nbsp; <\/span>compress-folder -computer $computer -compressedFolder $compressedFolder<br \/><span>&nbsp; <\/span>}<br \/><span>&nbsp;<\/span>else { compress-folder -computer $computer -compressedFolder $compressedFolder }<br \/>} #end function test-andCreateFolder<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">The <b>compress-folder<\/b> function accepts two parameters. The first is <b>$computer<\/b> and the second is <b>$compressedFolder<\/b>. The main part of the code is the <b>[WMI]<\/b> type accelerator. This is used to connect directly to an instance of a WMI class. In this example, the <b>Win32_Directory<\/b> WMI class refers to every single folder on the entire computer. That is a huge number in most cases. To improve performance, I do not want to search for folders; rather, I want to connect to a specific folder with WMI, and then compress that particular folder. The <b>[WMI]<\/b> type accelerator allows me to do just that. One thing I learned today is that on Windows 7, WMI allows me to connect to a folder without needing to use the double backward slashes. I found this out by accident when I put my folder path into a variable, and then passed the variable to WMI. Normally, I would type the command to connect to a folder as shown here:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:Usersed.NWTRADERS&gt; [wmi]&#8221;\\localhostrootcimv2:win32_directory.name=&#8217;c:\\fso'&#8221;<\/p>\n<p>Hidden<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Archive<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>EightDotThreeFileName : c:fso<br \/>FileSize<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: <br \/>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: c:fso<br \/>Compressed<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Encrypted<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Readable<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: True<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">You might even be tempted to use double quotation marks to surround the path to the folder. In that case, the command would look like this command where the quotation mark is used to escape the quotation marks surrounding the path to the folder:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">PS C:Usersed.NWTRADERS&gt; [wmi]&#8221;\\localhostrootcimv2:win32_directory.name=&#8221;&#8221;c:\\fso&#8221;&#8221;&#8221;<\/p>\n<p>Hidden<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Archive<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>EightDotThreeFileName : c:fso<br \/>FileSize<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: <br \/>Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: c:fso<br \/>Compressed<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Encrypted<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: False<br \/>Readable<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: True<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">I access the returned <b>Win32_Directory<\/b> WMI class by using dotted notation, and I call the <b>compress<\/b> method. The return code is stored in the <b>$rtn<\/b> variable. If the <b>returnvalue<\/b> property is equal to 0, it means no errors occurred during the compress operation. If it is equal to anything else, I display the error number and a message that the error occurred. The WMI return code values are documented on MSDN. <\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">function compress-folder($computer, $compressedFolder)<br \/>{<br \/><span>&nbsp;<\/span>$rtn = `<br \/>([wmi]&#8221;\\$computerrootcimv2:win32_directory.name=&#8217;$compressedFolder'&#8221;).`<br \/>compress()<br \/><span>&nbsp;<\/span>if($rtn.returnvalue -eq 0) { &#8220;$compressedFolder successfully compressed&#8221;}<br \/><span>&nbsp;<\/span>else { &#8220;$($rtn.returnvalue) error occurred compressing $compressedFolder&#8221; ; exit }<br \/>} #end function compress-folder<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">The entry point to the script calls the <b>Test-andCreateFolder<\/b> function that in turn calls the <b>Compress-Folder<\/b> function. After that function has completed, it calls the <b>Copy-Item<\/b> cmdlet to copy the files to the compressed folder. This section of the script is shown here:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">Test-andCreateFolder -compressedFolder $compressedFolder -computer $computer<br \/>Copy-Item -Path $pathForFiles -Destination $compressedFolder -Include * -Recurse<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">The advanced properties of the folder display the compressed state of the folder. This is shown in the following image.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" height=\"347\" width=\"394\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0522\/wes-05-22-10-01.jpg\" alt=\"Image of compressed state of folder\" title=\"Image of compressed state of folder\" style=\"width: 394px;height: 347px\"><\/p>\n<p class=\"MsoNormal\">One thing you may wish to be aware of, is that if you try to copy content from the source folder to the compressed folder, an error will be generated the second time. This is because the destination folder will already exist. You can fix this problem by adding the <b>&ndash;force<\/b> parameter to the <b>Copy-Item<\/b> cmdlet. The line would look like the following:<\/p>\n<p class=\"CodeBlockScreened\"><span style=\"background-color: #f2f2f2\"><span style=\"font-family: Lucida Sans Typewriter\">Copy-Item -Path $pathForFiles -Destination $compressedFolder -Include * -Recurse &ndash;force<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">By using the &#8211;<b>force<\/b> parameter, you will overwrite any existing files with the new ones you are copying over. This may be fine according to your application. The error is seen in the following image.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" height=\"414\" width=\"600\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0522\/wes-05-22-10-02.jpg\" alt=\"Image of error displayed\" title=\"Image of error displayed\" style=\"width: 600px;height: 414px\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/may\/hey0522\/wes-05-22-10-02.jpg\"><span><span style=\"font-family: Segoe\"><\/span><\/span><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">Well, that is about enough fun for one morning. If you want to know exactly what we will be looking at tomorrow, follow us on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send e-mail to us at <a target=\"_blank\" href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><span style=\"font-family: Segoe\">scripter@microsoft.com<\/span><\/a> or post your questions on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\"><span style=\"font-family: Segoe\">Official Scripting Guys Forum<\/span><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/p>\n<p><\/span>\n<b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. It is another beautiful weekend in Charlotte, North Carolina. I enjoy getting up early on the weekend, having a leisurely breakfast, reading for a little while, and then heading up to my office to write some scripts. I have a white board upon which I write down ideas [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[139,3,12,61,45],"class_list":["post-49663","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-compressed-files","tag-scripting-guy","tag-storage","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. It is another beautiful weekend in Charlotte, North Carolina. I enjoy getting up early on the weekend, having a leisurely breakfast, reading for a little while, and then heading up to my office to write some scripts. I have a white board upon which I write down ideas [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49663","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=49663"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49663\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=49663"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=49663"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=49663"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}