{"id":15388,"date":"2014-02-11T15:02:02","date_gmt":"2014-02-11T23:02:02","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/setup\/?p=15388"},"modified":"2019-05-03T15:07:46","modified_gmt":"2019-05-03T23:07:46","slug":"how-to-relocate-the-package-cache","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/setup\/how-to-relocate-the-package-cache\/","title":{"rendered":"How to relocate the Package Cache"},"content":{"rendered":"<p>Visual Studio can require a <a href=\"http:\/\/bit.ly\/y84B1u\">lot of space on the system drive<\/a>. Based on years of data collected from customers\u2019 installations from the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=105252\">Customer Experience Improvement Program<\/a>, we took advantage of this feature in Burn \u2013 the <a href=\"http:\/\/wixtoolset.org\">Windows Installer XML (WiX)<\/a> chainer \u2013 to <a href=\"http:\/\/bit.ly\/LQL3LC\">eliminate most errors during repair, servicing, and even uninstall<\/a>. This was not a popular decision with some customers. For years even I pushed against caching Visual Studio deployment packages because of the impact to drive space as well, but as HDD space increased market studies showed little reason not to cache for the increased reliability of deployment.<\/p>\n<p>We understand, however, that many customers have smaller SSDs and while size will increase and cost decrease over time, some customers are blocked from installing Visual Studio or have little space left over after a successful installation.<\/p>\n<p>I have submitted a feature proposal to WiX to allow control over the Package Cache location, but until then there is a workaround that really highlights some of the virtualization features in Windows.<\/p>\n<h3>Disclaimer<\/h3>\n<p>This practice has received some testing and has been running under load for a reasonable amount of time. While it uses documented features of Windows, this is not an officially supported practice and may leave your machine in a corrupted state should you disconnected the secondary drive or fail to properly secure the folder mount point and its contents.<\/p>\n<h3>Workaround<\/h3>\n<p>You can move the contents of the Package Cache to a partition on another drive \u2013 copying the ACL and owner, which is very important for both security and because some programs may not trust any ACL or owner that is different than what is expected \u2013 and then mount that partition into an empty folder. But rather than dedicate an entire partition on a physical disk \u2013 which isn\u2019t always as easy to reconfigure on the fly \u2013 we will create a virtual disk (VHD) on another drive.<\/p>\n<p>By creating an expandable virtual disk we can declare a maximum size that can be much larger than necessary \u2013 even larger than the host drive itself \u2013 but takes up only as much room as necessary and will grow as the content grows. This way, should you ever need to allocate more space you can simply dismount and move the VHD to another disk, then remount it. No need to recopy files.<\/p>\n<p>Mounting a VHD into an empty directory also maintains the mount across reboots \u2013 something not currently supported when mounting a VHD for drive access.<\/p>\n<h4>System requirements<\/h4>\n<p>Support for creating and mounting VHDs was built into Windows Vista with support for VHDs larger than 2TB added in Windows 8 using the newer VHDX format.<\/p>\n<h4>Manual walkthrough<\/h4>\n<p>To show more in depth how this works \u2013 and how you might adapt it for your own use \u2013 I will use a couple of built-in programs: <em>diskpart.exe<\/em> and <em>mountvol.exe<\/em>. We can also do all this in PowerShell with the right Windows Features enabled but I will cover that in the scripted section.<\/p>\n<ol>\n<li>Open an elevated command prompt.<\/li>\n<li>Run <em>diskpart.exe<\/em> to start the disk partitioning utility:\n<code>diskpart<\/code><\/li>\n<li>Create a large (ex: 1TB), expandable VHD on whatever secondary disk (ex: X:) you prefer with security matching the source directory\u2019s security:\n<code>create vdisk file=\"X:Cache.vhd\" type=expandable maximum=1048576 sd=\"O:BAG:DUD:P(A;;FA;;;BA)(A;;FA;;;SY)(A;;FRFX;;;BU)(A;;FRFX;;;WD)\" <\/code><\/li>\n<li>Select the VHD and create a partition using all available space:\nselect vdisk file=&#8221;X:Cache.vhd&#8221;\nattach vdisk\ncreate partition primary<\/li>\n<li>Format the volume that was created automatically and temporarily assign a drive letter (ex: P:):\n<code>format fs=ntfs label=\"Package Cache\" quick\nassign letter=P\nexit<\/code><\/li>\n<li>After exiting <em>diskpart.exe<\/em>, move any existing per-machine payloads from the Package Cache with security:\n<code>robocopy \"%ProgramData%Package Cache\" P: \/e \/copyall \/move \/zb<\/code><\/li>\n<li>Recreate the Package Cache directory and set up the ACL and owner as before:\n<code>mkdir \"%ProgramData%Package Cache\"\necho y | cacls foo \/s:\"O:BAG:DUD:PAI(A;OICIID;FA;;;BA)(A;OICIID;FA;;;SY)(A;OICIID;FRFX;;;BU)(A;OICIID;FRFX;;;WD)\"<\/code><\/li>\n<li>Run <em>mountvol.exe<\/em> without any parameters first and look for the volume name that has the drive letter you assigned to the VHD, then use that with <em>mountvol.exe<\/em> again to mount that volume into the empty Package Cache directory.\n<code>mountvol\nmountvol \"%ProgramData%Package Cache\" \\?Volume{a525b826-8a0c-11e3-be94-00249b0716f5}<\/code><\/li>\n<li>Run <em>diskpart.exe<\/em> again and remove the drive letter assignment from the volume (should be in partition 1 of the VHD):\n<code>select vdisk file=\"X:Cache.vhd\"\nselect partition 1\nremove letter=P\nexit<\/code><\/li>\n<li>Non-boot VHDs are not automatically mounted, so before you reboot you need to make sure the VHD is mounted again whenever the machine is started. Write a simple script for <em>diskpart.exe<\/em> to execute on startup. If you\u2019re doing this on a laptop, you should edit the scheduled task afterward to allow it to run on batteries.\n<code>echo select vdisk file=X:Cache.vhd &gt; X:Cache.txt\necho attach vdisk &gt;&gt; X:Cache.txt\nschtasks \/create \/ru system \/sc onstart \/rl highest \/tn \"Attach Package Cache\" \/tr \"%SystemRoot%System32diskpart.exe \/s X:Cache.txt\"<\/code><\/li>\n<\/ol>\n<p>After exiting <em>diskpart.exe<\/em> you now have mapped a VHD on another drive into the new Package Cache directory. The VHD will be remounted into the directory whenever the machine is rebooted. If you look at the mount point, you will also see its icon, description, and size are different.<\/p>\n<p>The size reported in Windows Explorer is merely the maximum and not how much space is consumed within the virtual disk. In fact, you probably would care less about that than how much space the VHD itself is consuming. Browse to the folder were you created the VHD (ex: X:Cache.vhd) and you will see the actual file size.<\/p>\n<p>When bundles have been uninstalled and packages removed from the Package Cache, you can attempt to compact the VHD to reclaim space on the host disk.<\/p>\n<ol>\n<li>Open an elevated command prompt.<\/li>\n<li>Run <em>diskpart.exe<\/em>:\n<code>diskpart<\/code><\/li>\n<li>Select the VHD and attempt to compact it:\n<code>select vdisk file=\"X:Cache.vhd\ncompact vdisk\nexit<\/code><\/li>\n<\/ol>\n<p>Should you ever need to move the file, you can use <em>mountvol.exe<\/em> to dismount the VHD, copy it to another attached drive, and remount the VHD.<\/p>\n<h4>Scripted solution<\/h4>\n<p>Once the Hyper-V Module for Windows PowerShell is installed on supported Windows platforms, you can easily script this and execute it on remote machines running an elevated WinRM endpoint. <a href=\"http:\/\/bit.ly\/1ekfCGt\">PowerShell<\/a> is a powerful object-oriented shell that provides for the same compositional techniques of any modern programming language.<\/p>\n<p>I have created an <a href=\"http:\/\/bit.ly\/mvcache\">example PowerShell script<\/a> you can use locally on any Windows 7 machine or newer, or run on remote machines using the <code>Invoke-Command<\/code> cmdlet.<\/p>\n<p>When bundles have been uninstalled and packages removed from the Package Cache, you can attempt to compact the VHD to reclaim space on the host disk.<\/p>\n<ol>\n<li>Open an elevated PowerShell prompt.<\/li>\n<li>Run the following command to get and optimize (compact) the VHD you passed as a parameter to <code>Move-WixPackageCache.ps1<\/code> (ex: X:Cache.vhd):\n<code>get-vhd X:Cache.vhd | dismount-vhd -passthru | optimize-vhd -passthru | mount-vhd<\/code><\/li>\n<\/ol>\n<h3>Summary<\/h3>\n<p>Mounting virtual disks hosted on other attached disks can be an effective workaround to reducing space on the system drive. We will continue to explore options for locating more data on the chosen installation drive but there will always be some components that need to be installed to the Windows or Program Files directories. There are some <a href=\"http:\/\/support.microsoft.com\/kb\/929831\">known issues<\/a> when redirecting those and other directories to another drive other than where Windows is installed, so leaving plenty of space on your system drive is always recommended.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Visual Studio can require a lot of space on the system drive. Based on years of data collected from customers\u2019 installations from the Customer Experience Improvement Program, we took advantage of this feature in Burn \u2013 the Windows Installer XML (WiX) chainer \u2013 to eliminate most errors during repair, servicing, and even uninstall. This was [&hellip;]<\/p>\n","protected":false},"author":389,"featured_media":3843,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[20,30,39,45,46,54,55,59,64],"class_list":["post-15388","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-installation","tag-powershell","tag-tip","tag-visual-studio","tag-vs","tag-vs2012","tag-vs2013","tag-vsupdate","tag-wix"],"acf":[],"blog_post_summary":"<p>Visual Studio can require a lot of space on the system drive. Based on years of data collected from customers\u2019 installations from the Customer Experience Improvement Program, we took advantage of this feature in Burn \u2013 the Windows Installer XML (WiX) chainer \u2013 to eliminate most errors during repair, servicing, and even uninstall. This was [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/15388","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/users\/389"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/comments?post=15388"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/posts\/15388\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media\/3843"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/media?parent=15388"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/categories?post=15388"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/setup\/wp-json\/wp\/v2\/tags?post=15388"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}