Creating Junctions in Windows

A simple guide to making directory junctions in Windows Vista and Windows 7

I like to keep my data on a separate partition to my Operating Systems. This is useful for a few reasons, but it is also a good way of ensuring that if anything ever goes wrong with the Operating System, the personal data, music, pictures, etc. are all safe on it's own partition, allowing you to format and reinstall Windows. In Linux, this is very easy to do, but in Windows it's a little harder.

The first thing you will need to do is install Windows. You will either want to do this on a clean install or make sure you have a good backup of everything! Don't yell at me if this doesn't work for you! Assuming the data partition is created and ready for use, insert the Windows install disc and restart your computer, booting into it when you can. Then follow these simple instructions.

  1. You will need to select your language.
  2. Choose the Repair option.
  3. Choose to use the repair tools on the Windows install.
  4. Open the Command Prompt.

Now this is where the instructions differ very slightly depending on whether you're on Windows Vista or Windows 7. Windows 7 creates two partitions during install, one called System Reserved and the one containing Windows itself, whereas Windows Vista only creates the one partition. This will make the drive letters differ in Windows 7 while you are running the Command Prompt from the disc.

Windows Vista

The partition containing Windows should be C:\ and I will assume the target partition is D:\ (change this if it's not the case). You can use the command dir [driveletter] to check which is which. Type in the following commands to copy C:\Users to D:\Users and create a directory junction.

robocopy C:\Users D:\Users /MIR /E /XJ
rmdir /S /Q C:\Users
rmdir "C:\Documents and Settings"
mklink /J C:\Users D:\Users
mklink /J "C:\Documents and Settings" D:\Users

Windows 7

The System Reserved partition will be C:\ while in the Command Prompt on Windows 7, so Windows will be D:\ and I will assume the target partition is E:\ (change this if it's not the case). You can use the command dir [driveletter] to check which is which. Type in the following commands to copy D:\Users to E:\Users (which in Windows would be C:\Users to D:\Users) and create a directory junction.

robocopy D:\Users E:\Users /MIR /E /XJ
rmdir /S /Q D:\Users
rmdir "D:\Documents and Settings"
mklink /J D:\Users D:\Users
mklink /J "D:\Documents and Settings" D:\Users

NOTE: The mklink commands for Windows 7 both target D:\ on purpose! This is because the junction is used by Windows and therefore should refer to it as Windows does. The target is only E:\ while running from the disc.

Offline StevenP
Joined: 8th Jan 2010
Posted on Sunday 10th January 2010 at 10:07 a.m.

NOTE: This comment relates to windows 7 specifically but is probably relevant for Vista as well - no guarantee with either! Backup everything you can't afford to lose and be prepared to get this process wrong, fiddle with it then put everything back to how it was if it doesn't work for you (there are tips for doing this below).

Hi - Firstly thank you for posting up these very clear instructions. I finally got round to following them after putting it off for a few months (since I emailed you some questions). I have finally been successful (I think). The problems I have encountered may help other folks trying to do this. Like I said in my email I was interested in doing this in order to share a user data partition between separate Windows 7 and Ubuntu system partitions.

It was only after spending the day trying to set this up that I asked myself an important question, which you might know the answer too: Is it possible to "format and reinstall Windows" and get the rebuilt Windows system to work with the existing Users folder in the user data partition? I haven't tried this but in thinking a bit about what is in the Users folder I wonder how this plan would actually execute in anger. How do you get the newly created user to link to the old user profile?

This question aside my experience pointed to some useful extra bits of info not in your article. One of my questions from my email was about permissions. It appears that the /MIR (MIRror) switch on robocopy isn't sufficient to make all permissions the same and it doesn't preserve ownership. To preserve ownership and permissions I found I had to use the /COPYALL switch (this copies all metadata). This switch will only work if you are running as administrator. If you are running a command prompt from the system recovery option on the install DVD, as indicated in the article then you will have admin rights. I noticed that booting from the install DVD I was dropped into the command window as SYSTEM, whereas if I booted from a USB hard drive with the install files on it, I was prompted for user login (from the users of the existing installation of Windows 7) before proceeding to the command window. I haven't checked what the cause of this behaviour is but it's worth being aware that if you run robocopy without the /copyall switch (or the specific owner switch /copy:o) then the ownership of the files seems to be the currently logged in user.

NOTE: loading the install recovery option from a USB drive is many times faster than from a DVD.

There is another issue with hidden junctions and a symlink in the Users directory (and subdirectories) which provide backward compatibility with old (aimed at XP) or badly written (hard coded paths) software. See this link for full details http://msdn.microsoft.com/en-us/library/bb756982.aspx However robocopy can't copy junctions as junctions but rather converts the junction into a full copy of its target. This causes a problem where a circular reference can cause robocopy to go into an infinite loop (and there is one in the Users directory). The /XJ (eXclude Junctions) switch causes robocopy to skip junctions. This shouldn’t present any immediate problem until you try and use some older software or not so well written freeware etc. The only solution to this is to recreate the missing links which is lengthy as a process.

NOTE: If you are reading this before installing Windows 7, in order to make this process easier, I recommend you add an extra step in your installation by creating a user during the install process which isn't going to be used for anything other than running robocopy and creating the junction to the new location of the users folder. Only create your actual users after you have changed the users folder location. New users are created with all the required backward compatibility junctions. Oddly this is the case even if the default user profile (normally hidden) doesn't contain them. Go figure and let me know when you do - I thought the default profile was the template for other profiles. I'm no windows admin - a little knowledge is a dangerous thing as they say.

Even if you are lucky enough to be reading this before installation, if you wish to preserve full backward compatibility you will still have to recreate the junction and symlink directory in Users, UsersDefault (+ sub dirs) and UsersPublicDocuments. This is the list of links I get from running

c:\UsersBackup>dir /al /s

Volume in drive C is WINDOWS 7
Volume Serial Number is 4CFF-BD45

Directory of C:\UsersBackup

14/07/2009  04:53    <SYMLINKD>     All Users [C:\ProgramData]
08/01/2010  19:06    <JUNCTION>     Default User [c:\Users\Default]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\All Users

14/07/2009  04:53    <JUNCTION>     Application Data [C:\ProgramData]
14/07/2009  04:53    <JUNCTION>     Desktop [C:\Users\Public\Desktop]
14/07/2009  04:53    <JUNCTION>     Documents [C:\Users\Public\Documents]
14/07/2009  04:53    <JUNCTION>     Favorites [C:\Users\Public\Favorites]
14/07/2009  04:53    <JUNCTION>     Start Menu [C:\ProgramData\Microsoft\Windows\Start Menu]
14/07/2009  04:53    <JUNCTION>     Templates [C:\ProgramData\Microsoft\Windows\Templates]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Default

14/07/2009  04:53    <JUNCTION>     Application Data [C:\Users\Default\AppData\Roaming]
14/07/2009  04:53    <JUNCTION>     Cookies [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Cookies]
14/07/2009  04:53    <JUNCTION>     Local Settings [C:\Users\Default\AppData\Local]
14/07/2009  04:53    <JUNCTION>     My Documents [C:\Users\Default\Documents]
14/07/2009  04:53    <JUNCTION>     NetHood [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Network Shortcuts]
14/07/2009  04:53    <JUNCTION>     PrintHood [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Printer Shortcuts]
14/07/2009  04:53    <JUNCTION>     Recent [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Recent]
14/07/2009  04:53    <JUNCTION>     SendTo [C:\Users\Default\AppData\Roaming\Microsoft\Windows\SendTo]
14/07/2009  04:53    <JUNCTION>     Start Menu [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu]
14/07/2009  04:53    <JUNCTION>     Templates [C:\Users\Default\AppData\Roaming\Microsoft\Windows\Templates]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Default\AppData\Local

14/07/2009  04:53    <JUNCTION>     Application Data [C:\Users\Default\AppData\Local]
14/07/2009  04:53    <JUNCTION>     History [C:\Users\Default\AppData\Local\Microsoft\Windows\History]
14/07/2009  04:53    <JUNCTION>     Temporary Internet Files [C:\Users\Default\AppData\Local\Microsoft\Windows\Temporary Internet Files]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Default\Documents

14/07/2009  04:53    <JUNCTION>     My Music [C:\Users\Default\Music]
14/07/2009  04:53    <JUNCTION>     My Pictures [C:\Users\Default\Pictures]
14/07/2009  04:53    <JUNCTION>     My Videos [C:\Users\Default\Videos]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Public\Documents

14/07/2009  04:53    <JUNCTION>     My Music [C:\Users\Public\Music]
14/07/2009  04:53    <JUNCTION>     My Pictures [C:\Users\Public\Pictures]
14/07/2009  04:53    <JUNCTION>     My Videos [C:\Users\Public\Videos]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Steven

25/11/2009  13:03    <JUNCTION>     Application Data [C:\Users\Steven\AppData\Roaming]
25/11/2009  13:03    <JUNCTION>     Cookies [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Cookies]
25/11/2009  13:03    <JUNCTION>     Local Settings [C:\Users\Steven\AppData\Local]
25/11/2009  13:03    <JUNCTION>     My Documents [C:\Users\Steven\Documents]
25/11/2009  13:03    <JUNCTION>     NetHood [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Network Shortcuts]
25/11/2009  13:03    <JUNCTION>     PrintHood [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Printer Shortcuts]
25/11/2009  13:03    <JUNCTION>     Recent [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Recent]
25/11/2009  13:03    <JUNCTION>     SendTo [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\SendTo]
25/11/2009  13:03    <JUNCTION>     Start Menu [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Start Menu]
25/11/2009  13:03    <JUNCTION>     Templates [C:\Users\Steven\AppData\Roaming\Microsoft\Windows\Templates]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Steven\AppData\Local

25/11/2009  13:03    <JUNCTION>     Application Data [C:\Users\Steven\AppData\Local]
25/11/2009  13:03    <JUNCTION>     History [C:\Users\Steven\AppData\Local\Microsoft\Windows\History]
25/11/2009  13:03    <JUNCTION>     Temporary Internet Files [C:\Users\Steven\AppData\Local\Microsoft\Windows\Temporary Internet Files]
               0 File(s)              0 bytes

Directory of C:\UsersBackup\Steven\Documents

25/11/2009  13:03    <JUNCTION>     My Music [C:\Users\Steven\Music]
25/11/2009  13:03    <JUNCTION>     My Pictures [C:\Users\Steven\Pictures]
                0 File(s)              0 bytes

     Total Files Listed:
               0 File(s)              0 bytes
              43 Dir(s)   9,032,568,832 bytes free

C:\UsersBackup>

If you have existing user accounts you will have to do this for all the junctions in each user subdirectory. Once you have created them you need to check the permissions are set correctly - particularly the deny listing (see the msdn link above). In order to help me do this, and give me a get out of jail card, I didn't delete the existing user directory from my system drive as suggested in the article but renamed it (don't move it to another partition because this will change the file metadata and junctions - just rename Users to something else (I chose UsersBackup). This has the advantage of giving you a full set-up to switch back to (restart with the restore command window and delete the Users junction and rename the folder to Users) and a reference to check what the permissions are on the junctions. In the default profile and real user profiles, if you have used the robocopy /copyall switch all junctions just need the ownership changed to SYSTEM and the addition of deny read list for Everyone.

I wrote this batch script (there is no doubt a much more graceful way to do this but I don't know it - I set about trying to learn how to write this in PowerShell and gave up as I don't know .NET or COM - any improvement please let me know) to setup users.

NOTE: To run this it needs to be saved as a batch script in the same folder as the new location for Users. For me that was E:\

@echo off

set /p user= "Please enter the user to setup: "

mklink /J "\Users\%user%\Application Data" "C:\Users\%user%\AppData\Roaming"
mklink /J "\Users\%user%\Cookies" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Cookies"
mklink /J "\Users\%user%\Local Settings" "C:\Users\%user%\AppData\Local"
mklink /J "\Users\%user%\My Documents" "C:\Users\%user%\Documents"
mklink /J "\Users\%user%\NetHood" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Network Shortcuts"
mklink /J "\Users\%user%\PrintHood" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Printer Shortcuts"
mklink /J "\Users\%user%\Recent" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Recent"
mklink /J "\Users\%user%\SendTo" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\SendTo"
mklink /J "\Users\%user%\Start Menu" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Start Menu"
mklink /J "\Users\%user%\Templates" "C:\Users\%user%\AppData\Roaming\Microsoft\Windows\Templates"
mklink /J "\Users\%user%\AppData\Local\Application Data" "C:\Users\%user%\AppData\Local"
mklink /J "\Users\%user%\AppData\Local\History" "C:\Users\%user%\AppData\Local\Microsoft\Windows\History"
mklink /J "\Users\%user%\AppData\Local\Temporary Internet Files" "C:\Users\%user%\AppData\Local\Microsoft\Windows\Temporary Internet Files"
mklink /J "\Users\%user%\Documents\My Music" "C:\Users\%user%\Music"
mklink /J "\Users\%user%\Documents\My Pictures" "C:\Users\%user%\Pictures"
mklink /J "\Users\%user%\Documents\My Videos" "C:\Users\%user%\Videos"

attrib +H +S +I "\Users\%user%\Application Data" /L
attrib +H +S +I "\Users\%user%\Cookies" /L
attrib +H +S +I "\Users\%user%\Local Settings" /L
attrib +H +S +I "\Users\%user%\My Documents" /L
attrib +H +S +I "\Users\%user%\NetHood" /L
attrib +H +S +I "\Users\%user%\PrintHood" /L
attrib +H +S +I "\Users\%user%\Recent" /L
attrib +H +S +I "\Users\%user%\SendTo" /L
attrib +H +S +I "\Users\%user%\Start Menu" /L
attrib +H +S +I "\Users\%user%\Templates" /L
attrib +H +S +I "\Users\%user%\AppData\Local\Application Data" /L
attrib +H +S +I "\Users\%user%\AppData\Local\History" /L
attrib +H +S +I "\Users\%user%\AppData\Local\Temporary Internet Files" /L
attrib +H +S +I "\Users\%user%\Documents\My Music" /L
attrib +H +S +I "\Users\%user%\Documents\My Pictures" /L
attrib +H +S +I "\Users\%user%\Documents\My Videos" /L

icacls "\Users\%user%\Application Data" /setowner SYSTEM /L
icacls "\Users\%user%\Cookies" /setowner SYSTEM /L
icacls "\Users\%user%\Local Settings" /setowner SYSTEM /L
icacls "\Users\%user%\My Documents" /setowner SYSTEM /L
icacls "\Users\%user%\NetHood" /setowner SYSTEM /L
icacls "\Users\%user%\PrintHood" /setowner SYSTEM /L
icacls "\Users\%user%\Recent" /setowner SYSTEM /L
icacls "\Users\%user%\SendTo" /setowner SYSTEM /L
icacls "\Users\%user%\Start Menu" /setowner SYSTEM /L
icacls "\Users\%user%\Templates" /setowner SYSTEM /L
icacls "\Users\%user%\AppData\Local\Application Data" /setowner SYSTEM /L
icacls "\Users\%user%\AppData\Local\History" /setowner SYSTEM /L
icacls "\Users\%user%\AppData\Local\Temporary Internet Files" /setowner SYSTEM /L
icacls "\Users\%user%\Documents\My Music" /setowner SYSTEM /L
icacls "\Users\%user%\Documents\My Pictures" /setowner SYSTEM /L
icacls "\Users\%user%\Documents\My Videos" /setowner SYSTEM /L

icacls "\Users\%user%\Application Data" /deny Everyone:(RD) /L
icacls "\Users\%user%\Cookies" /deny Everyone:(RD) /L
icacls "\Users\%user%\Local Settings" /deny Everyone:(RD) /L
icacls "\Users\%user%\My Documents" /deny Everyone:(RD) /L
icacls "\Users\%user%\NetHood" /deny Everyone:(RD) /L
icacls "\Users\%user%\PrintHood" /deny Everyone:(RD) /L
icacls "\Users\%user%\Recent" /deny Everyone:(RD) /L
icacls "\Users\%user%\SendTo" /deny Everyone:(RD) /L
icacls "\Users\%user%\Start Menu" /deny Everyone:(RD) /L
icacls "\Users\%user%\Templates" /deny Everyone:(RD) /L
icacls "\Users\%user%\AppData\Local\Application Data" /deny Everyone:(RD) /L
icacls "\Users\%user%\AppData\Local\History" /deny Everyone:(RD) /L
icacls "\Users\%user%\AppData\Local\Temporary Internet Files" /deny Everyone:(RD) /L
icacls "\Users\%user%\Documents\My Music" /deny Everyone:(RD) /L
icacls "\Users\%user%\Documents\My Pictures" /deny Everyone:(RD) /L
icacls "\Users\%user%\Documents\My Videos" /deny Everyone:(RD) /L

That leaves just the All Users directory symlink and Default User junction in the Users directory and the My Music, My Pictures and My Videos junctions in UsersPublicDocuments.

NOTE: You don't need to create the junctions listed in UsersAll Users as these are already in the target of the All Users directory symlink.

These last 5 junctions have special permissions (all the same thankfully) set which I couldn't recreate using the icacls tool (icacls seems to wipe out the owner of the link when you remove inherited permissions) so I opted to create the directories, set the attributes and owner and the unproblematic full control permissions for SYSTEM and Administrators with a script then set the problem permissions and remove inherited permissions through the computer browser window on a normal boot. This bit of script does the automatic steps:

mklink /D "\Users\All Users" C:\ProgramData
attrib +H +S +I "\Users\All Users" /L
icacls "\Users\All Users" /setowner SYSTEM /L
icacls "\Users\All Users" /grant Administrators:(F) /L
icacls "\Users\All Users" /grant SYSTEM:(F) /L

mklink /J "\Users\Default User" C:\Users\Default
attrib +H +S +I "\Users\Default User" /L
icacls "\Users\Default User" /setowner SYSTEM /L
icacls "\Users\Default User" /grant Administrators:(F) /L
icacls "\Users\Default User" /grant SYSTEM:(F) /L

mklink /J "\Users\Public\Documents\My Music" C:\Users\Public\Music
attrib +H +S +I "\Users\Public\Documents\My Music" /L
icacls "\Users\Public\Documents\My Music" /setowner SYSTEM /L
icacls "\Users\Public\Documents\My Music" /grant Administrators:(F) /L
icacls "\Users\Public\Documents\My Music" /grant SYSTEM:(F) /L

mklink /J "\Users\Public\Documents\My Pictures" C:\Users\Public\Pictures
attrib +H +S +I "\Users\Public\Documents\My Pictures" /L
icacls "\Users\Public\Documents\My Pictures" /setowner SYSTEM /L
icacls "\Users\Public\Documents\My Pictures" /grant Administrators:(F) /L
icacls "\Users\Public\Documents\My Pictures" /grant SYSTEM:(F) /L

mklink /J "\Users\Public\Documents\My Videos" C:\Users\Default\Videos
attrib +H +S +I "\Users\Public\Documents\My Videos" /L
icacls "\Users\Public\Documents\My Videos" /setowner SYSTEM /L
icacls "\Users\Public\Documents\My Videos" /grant Administrators:(F) /L
icacls "\Users\Public\Documents\My Videos" /grant SYSTEM:(F) /L

When you reboot on a normal boot you then need to go into a computer browser, make sure that hidden and system files are visible, navigate to each of these 5 links properties and untick the inherit permissions under the security tab and choose to remove the inherited permissions rather than making them explicit. You then need to add two permissions ACEs for users Everyone. The first allows everyone:

Traverse folder / Execute file
List folder/ read data
Read attributes
Read extended attributes
Read permissions (NOTE: I couldn't find a switch to set this with icacls)

the second denies everyone List folder/ read data. This supersedes the allow permission above. That seems to be the way they have done it on the windows install disk - not for me to reason why.

All in all, as I noted with my question at the start of this comment, I'm not 100% that this process achieves my motivating purpose. It might be better for me to switch back and just use the libraries concept and live with the fact that it will be a few years before Windows software catches up with it.


Offline CWassall Male
Location: England
Joined: 15th Oct 2008
Posted on Tuesday 12th January 2010 at 4:42 a.m.

Thanks for the interest, Steven ;)

I realized fairly recently that the permissions would get in the way... Thanks for taking the time to post what you have found! I mentioned that it was much easier in Linux at the top of the article, those words seem as true as ever ;)

I'll have to update my article soon, I guess, although I'm not entirely sure what with yet. I don't like to make a habit of going through Windows installs ;) I think it's safe to say that simply creating a junction to an existing user from a clean install isn't going to be what I've come to expect from Linux, where my user, my data, my application settings, everything is ready to use as it was before reinstalling.

I was thinking about using Libraries instead, but Application Data and other vital things (for me) are not included in this, which is why I wanted the entire directory moved. I want Windows to be able to be installed and recognize existing users and their data, I don't want to create a new user and move my files across (again). If only there was an option in Windows install, like there is in 99% of the Linux distros...


Edean - Founder of the Forest Guardians of Syrtis

You must log in to post a comment.