Over the last few days I've started the process of upgrading my test virtual machines to Windows Server 2012 R2, or in the case of my mini Hyper-V server, to the final bits of Windows Hyper-V Server 2012 R2. In many cases I had been running the preview bits. I know I probably should have done clean installs, but I decided to upgrade in-place. The upgrade itself is easy and quick. However, the upgrade comes with a price.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The upgrade process will leave a folder called Windows.old which essentially contains files from the previous installation. As you might expect this file can take up a lot of space. Unfortunately, you can't simply delete the folder as many of the files and folders have special permissions and owners. If you search, you'll find a number of articles that explain the proper way to remove this folder is to use the disk clean up wizard or the Cleanmgr.exe command line tool. But some of my systems are running Server Core which means no GUI for the clean up wizard and no command line tool. Eventually I came across this solution.
His solution requires junction.exe from the Sysinternals website. His solution was also a mix of PowerShell and CMD commands. I decided this could all be done with PowerShell, plus I could take advantage of ShouldProcess so the script supports -WhatIf.
#requires -version 3.0 <# Manually remove windows.old when CleanMgr.exe or disk clean up wizard are not available. Based on a solution from: http://serverfault.com/questions/545579/properly-remove-windows-old-on-hyper-v-server-2012-r2 This requires Junction.exe from Sysinternals in your path. **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** #> [cmdletbinding(SupportsShouldProcess)] Param( [string]$Path="C:\Windows.old") #remove all junction points Write-Verbose "Deleting junction points in $path" junction.exe -s -q $Path | where {$_ -match "^\\\\"} | foreach { $jpath = $_ -Replace "(: JUNCTION)|(: SYMBOLIC LINK)","" if ($PSCmdlet.ShouldProcess($jpath)) { junction.exe -d $jpath } } If ($PSCmdlet.ShouldProcess($path)) { #take ownership Write-Verbose "Taking ownership of $path and subfolders" invoke-expression "takeown /F $path /R /D Y" #reset permissions Write-Verbose "Resetting permissions" invoke-expression "cacls $path /T /G Everyone:F" #remove the folder Write-Verbose "Removing $path and subfolders" Remove-Item -Recurse -Path $Path -Force } #end of script
You will need to make sure junction.exe is somewhere in your path. I put a copy C:\Windows. I've used this a few times and it works pretty well. You will probably get prompted to continue and it will take a few minutes to run. But it gets the job done when other options are not available. I hope you'll let me know how it works for you, but please test in a virtual environment where you can roll back and/or make sure you have a verified backup.
or you could just take ownership of the “windows.old” folder and all sub folders as well as apply yourself as full control permissions and then just right click, and delete it….
I have tried that in the past with mixed results. Plus it requires a GUI.