23

I have installed Hyper-V Server 2012 R2 on a server that had Hyper-V Server 2012. When I did this, the standard Windows.old folder was created. I now would like to remove that folder safely. The standard way to do that with a full GUI would be to use Disk Cleanup, but of course I don't have that option on Hyper-V Server.

Is there a formal way to remove that folder in this scenario? I know if this was Server Core I could install the full GUI including Desktop Experience, but that would be a lot of nonsense just to cleanly remove a folder.

My primary reason for asking, as opposed to just doing rmdir /s or some such, is that the Windows.old folder has a lot of junctions, and I don't want to break anything in the production OS copy as part of doing this.

MikeBaz - MSFT
  • 1,253
  • 3
  • 15
  • 35
  • I read cleanmgr.exe can run in the command line... Not sure if this applies to server core or 2012??? – john Oct 12 '13 at 22:16

2 Answers2

24

I first tried to copy and run cleanmgr.exe (Disk Cleanup tool), but it has too many dependencies on DLLs which are not present in Core/Hyper-V Server.

So instead I deleted the directory manually.

First I removed all junction points and symbolic links. To do this I used junction.exe from SysInternals. Copy the exe into a directory in your path. I ran it to get a list of all junctions:

c:\tools\junction.exe -s -q C:\windows.old > %temp%\junc.txt

I opened a PowerShell:

start powershell.exe

and ran the following script to find the relevant lines and execute junction.exe again:

 foreach ($line in [System.IO.File]::ReadLines("$env:temp\junc.txt"))
 {
     if ($line -match "^\\\\")
     {
         $file = $line -replace "(: JUNCTION)|(: SYMBOLIC LINK)",""
         & c:\tools\junction.exe -d "$file"
     }
 }

This removed all junction points and the single symbolic link on my system.

back in cmd.exe I now executed three commands to clear permissions and delete all files:

 takeown /F C:\windows.old /R /D Y
 cacls C:\windows.old /T /G Everyone:F
 rd /s /q C:\windows.old

In my test, I installed a new Hyper-V server 2012, then upgraded to 2012 R2, Windows.old is now gone and the system is running fine with all old junction targets intact.

Peter Hahndorf
  • 13,763
  • 3
  • 37
  • 58
  • What was the contents of junc.Txt? Can you post it to pastebin? I'm curious if anything of interest was linked. – longneck Oct 12 '13 at 22:40
  • http://pastebin.com/pYBGR4ap has all the relevant lines from junc.txt – Peter Hahndorf Oct 13 '13 at 06:51
  • This appears to have worked fine, thanks! I also now know `takeown` exists, which I'm slightly embarrassed to admit I didn't know about. – MikeBaz - MSFT Oct 13 '13 at 13:25
  • 1
    Why would one need to manually remove the junction points before deleting the folder? The junction points are stored in the filesystem, so would surely get deleted along with the folder...? – Ashley Oct 15 '13 at 22:01
  • 3
    @AshleySteel - Because when keeping the junctions, commands like takeown fail. Here's the error: INFO: The system cannot find the path specified. ( "C:\windows.old\Documents and Settings\All Users\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Application Data\Microsoft\Windows\SystemData\S-1-5-18\ReadOnly" ) ERROR: The filename, directory name, or volume label syntax is incorrect. - this looks like a recursion problem to me and it stops when the file path gets too long. – Peter Hahndorf Oct 16 '13 at 09:31
  • Sorry for resurrecting an old thread, but 2012r2 still has some life left, right? EDIT: I answered my own question, which was caused by my misreading the powershell script. For those of you who will do this in the future, please know that the command line steps at the end can take a very long time, so go take a break as you execute them. ;) Good luck all, and stay healthy (this was submitted during the Covid-19 crisis). – Gregamatic Mar 23 '20 at 14:08
6

I used Peter H's answer and confirmed it does work, however I needed to do this on multiple servers, so I modified his code into a powershell script that can be executed either locally or via PS remoting from another machine. This is the .ps1 file:

# Script to remove windows.old after an upgrade

# Assumes path to sysinternals is in the PATH env variable


$ErrorActionPreference = "Inquire"

junction.exe -accepteula -s -q C:\windows.old | out-file $env:temp\juncts.txt -force

foreach ($line in [System.IO.File]::ReadLines("$env:temp\juncts.txt"))
 {
     if ($line -match "^\\\\")
     {
         $file = $line -replace "(: JUNCTION)|(: SYMBOLIC LINK)",""
         & junction.exe -d "$file"
     }
 }

 takeown /F C:\windows.old /R /D Y
 echo y | cacls C:\windows.old /T /G Everyone:F

 rm C:\windows.old -recurse -force
 rm "$env:temp\juncts.txt" -force
LikeARock47
  • 71
  • 1
  • 3
  • Yep this one works a treat. Don't forget to elevate powershell.exe privileges ("Run As Administrator") – Nexus Jun 25 '15 at 07:37
  • Line: echo y | cacls C:\windows.old /T /G Everyone:F Should be: echo y| cacls C:\windows.old /T /G Everyone:F No space between y and | – user437960 Oct 02 '17 at 12:53