rlucas.net: The Next Generation Rotating Header Image

Don’t bother with symlinks in Windows 7

Yes, in theory, Windows has rocketed into the 21st century with symbolic links. However, you can’t make them in Windows 7 unless you’re an Administrator, or unless you manage to give yourself “SeCreateSymbolicLinkPrivilege.”

Giving yourself this privilege is possible with Professional/Ultimate versions of Windows, but not Home Premium, via secpol.msc, which just doesn’t exist (and can’t be downloaded). (Funny, I don’t recall the comparison chart having a checkbox for “can actually use computer” that was missing from Home Premium.)

If you try to set this for yourself, don’t bother trying to use C# or PowerShell. You’ll need to manually wrap the unmanaged C++ advapi32 APIs, and pass all kinds of structs and pointers back and forth.

In the end, just give up on whatever it was you wanted to use symlinks for.


  1. Dan Shapiro says:

    Huh? I used mklink all the time, and it’s great – easiest way to get My Docs off your C: drive (in my case a small SSD) and move it elsewhere. Also works for other magic directories like PROGRAMDATA.

  2. rlucas says:

    1. Technically, it’s “cmd /c mklink”, because mklink is a cmd.exe builtin and not its own program. (This will save PowerShell users the confusion.)
    2. Yes, you can use it as you described, but only if: A. you’re Administrator (effectively), or B. your local security policy gives normal users the SeCreateSymbolicLinkPrivilege.
    3. If you don’t have the “professional” or “server” versions of Win 7, you won’t have the required program(s) such as secpol.msc that let you manipulate your own security policy.
    4. Hence, if you want a more repeatable and reliable solution than “start PowerShell as Administrator manually with some right-clicking,” you’re up Shit’s Creek. (Example: you might want to run a script to set up everyone’s development sandbox with appropriate local env vars and config files, all of which are version controlled, but only one of which should be the local active copy on any individual box. You can rely only upon the standard facilities of PowerShell. Symlinks are right out because you can’t guarantee that SeCreateSymbolicLinkPrivilege is enabled, or even *can be* enabled, on each dev’s box.)

    Yes, I know, one could always “runas /user:Administrator”, but then by doing that we’ve effectively destroyed the “least privilege” principle, because the answer to any hurdle becomes to adopt the *most* privilege.

  3. Jan-Erik Finnberg says:

    You can give your normal user account the permission with polsedit:


  4. kika says:

    You are forgetting that most people run standard in admin mode. So its not a problem for those.

    Most people I know run with a hacked code, so they all have ultimate of course.

    It’s not an issue.

  5. Kika is wrong here. It is an issue. Just because it’s not an issue for a subset of users (power users), the “workaround” violates good security principles (not running common commands as administrator) and doesn’t account for some environments where the workaround is simply not viable.

    Rlucas is right that if the privilege to create symbolic links is not present by default, it should at least be possible to enable it in as straightforward fashion with no more than one (built-in) command (or powershell script), but as he points out, it is not.

    Finally, I wanted to add that this is not the only surprise regarding symbolic links. Did you know that if you try to delete a directory tree using Powershell and that tree contains a symbolic link to another directory, Powershell will _traverse_ that symbolic link and recursively delete its content too?

    Let’s hope our friend Dan Shapiro doesn’t try to remove one of his symbolic links using Powershell and accidentally delete all of his Documents.

    If you think that’s ugly, please vote for the issue in MS Connect: https://connect.microsoft.com/PowerShell/feedback/details/727149/powershell-rm-rec-traverses-symbolic-links-and-removes-items-in-target

  6. John Guidry says:

    Not sure if you found a workaround for this, but I finally did. I also share your deep seated rage that something so fundamental requires jumping through hoops if you didn’t upgrade to Win7 Pro — ridiculous! The fix is a two-parter.

    First, cygwin ships with editrights.exe which handles at least some of the missing secpol snap-in’s duties. Start your cygwin term as administrator and issue the command:

    editrights -a SeCreateSymbolicLinkPrivilege -u [USERNAME]

    The command should work without an error. If your user is not an administrator, then you should be set now. You can verify your privilege list by opening cmd and issuing `whoami /priv`. If you are an administrator (likely), there’s more to do. You can read all the low-level details at StackOverflow.


    Since I don’t consider disabling UAC a valid solution, I created a new user named root to be my administrator account and made my primary account a standard user. Now try `whoami /priv` again. SeCreateSymbolicLinkPrivilege should now be listed and mklink should function without elevating your permissions.

    Hope this helps!

  7. rlucas says:

    Wow, great, meaty comment. Thank you. I give thanks this Thanksgiving holiday that I am not in a work situation that requires any obligate Windows operating system usage. ;)

  8. Sz. says:

    Oh dear, I wish I found you rant yesterday… A full day has just been robbed from me again by Windows. I finally decided to move my venerable portable app partition from plain old (& stupid) Fat32 to NTFS, exactly for the refreshment Win7 native symlink support was supposed to mean…

    This is (a legal…) Pro/64 here, and guess what, it’s still a pain to use symlinks!

    Even if I get over the stupid admin requirement (man, they shouldn’t allow regular users the del command either, huh?) and even if I avoid PowerShell, and even if I solve the issue that the secpol grant doesn’t seem to take effect after re-login (I might just need a reboot for this “fundamental” config change), the real deal-breaker for me is this:

    YOU CAN’T EASILY PACK your freakin’ symlinks for backups?! No native Windows (dir-level!) archiver?! And neither InfoZip, nor 7Zip, nor tar (whichever windows ports), or anything I came across with could just pack up my NTFS dirs so I can write them out to whatever filesystem is available for backup. Not even the “official” Windows Git port does it (which I’d call a surprising gap.) (Note: robocopy et al. are not *archivers* but file copy tools, and can’t pack up NTFS dirs for storing on Fat32, which is a requirement here.)

    Perhaps RAR can do it? But I certainly haven’t found a free (let alone open-source) one.

  9. rlucas says:

    Bummer. I think the “answer” to this stuff is: the *NIX-ish concept of a filesystem (what is a file, inode vs. link, hard vs. soft link, what is a directory, what is removal, what is moving, what is copying, what is an mtime/ctime/atime, etc. etc. etc.) is its own thing. Calling something else a “filesystem” is just not going to meet the expectations of someone looking for a *NIX “filesystem” unless a great deal of work has gone into making it *NIXy.

    So if you are raised in the *NIX tradition, and you want to use something called a “file” or that seems to kind of be like a “file” in some other world, be prepared to re-learn that culture and set of expectations. In fact, treat it like an unreliable unknown database with its own API. Because that’s what it is.

    (This applies equally to e.g. S3 as to Windows filesystems [and probably to just about everything else that doesn't claim POSIX]. Not an anti-Windows rant per se.)

Leave a Reply