I need to create a Symlink that lives in user roaming AppData, and points to a folder on another local drive, which is user specific. I have tried both mklink and New-Item -ItemType SymbolicLink in PowerShell 5 and both require admin rights, which makes it pretty useless in this context.
I also tried putting the user environment variable in the path, like this D:\C4R\%username%, but that doesn't work either.
Is there a mechanism for doing SymLinks as a regular user? Or is the whole concept of SymLinks really an admin thing?
- 251
2 Answers
You have to use the /J option
mklink /J <link> <target>
I don't know powershell, but this seems to work as well:
New-Item -Name <link> -ItemType Junction -Value <source>
- 557
Most of the time, the answer provided above by @TNierath is ok, although not technically correct.
The problem is that it suggests using Directory Junctions instead of Symbolic Links
(see: "directory junction" vs "directory symbolic link"?).
While the latter is most of the time a complete replacement for the former, sometimes you really need to create a symlink with an unescalated user.
In Windows, it is managed by SeCreateSymbolicLinkPrivilege privilege.
Granting such permission requires escalation, but you can grant it outside of the current session, and the privilege persists until explicitly revoked. However, to grant it is not as easy.
Option 1: Carbon.Security
To grant privilege, run the following as an admin user.
This WILL INSTALL Carbon.Security external (3rd-party) module, so you are warned.
Install-Module -Name 'Carbon.Security'
Import-Module -Name 'Carbon.Security'
Grant-Privilege -Identity $Env:UserName SeCreateSymbolicLinkPrivilege
Then check with:
Get-CPrivilege -Identity $Env:UserName
After that, you need to log out, restarting terminal won't help.
Finlly, you would be able to create symlinks with either New-Item -Type SymbolicLink or mklink with your current user:
PS C:\Users\Username> New-Item -Type SymbolicLink -Target .\AppData\ -Name AppDataLink
Directory: C:\Users\Username
Mode LastWriteTime Length Name
d----l 2025-05-18 19:11 AppDataLink
Option 2: No external modules
There are several commands in the native Windows environment to work with permissions, most notably ACL-commands and Get-Privilege/Set-Privilege.
There's also a Microsoft-maintained downloadable utilities pack containing accesschk command. However, the Get/Set-Privilege commands are not well-documented, and on my Windows 10 Home only one of them is working:
PS C:\Users\Username> Get-Privilege
Name Status
SeIncreaseQuotaPrivilege Enabled
SeSecurityPrivilege Enabled
SeTakeOwnershipPrivilege Enabled
SeLoadDriverPrivilege Enabled
SeSystemProfilePrivilege Enabled
SeSystemtimePrivilege Enabled
SeProfileSingleProcessPrivilege Enabled
SeIncreaseBasePriorityPrivilege Enabled
SeCreatePagefilePrivilege Enabled
SeBackupPrivilege Enabled
SeRestorePrivilege Enabled
SeShutdownPrivilege Enabled
SeDebugPrivilege Enabled
SeSystemEnvironmentPrivilege Enabled
SeChangeNotifyPrivilege EnabledByDefault, Enabled
SeRemoteShutdownPrivilege Enabled
SeUndockPrivilege Enabled
SeManageVolumePrivilege Enabled
SeImpersonatePrivilege EnabledByDefault, Enabled
SeCreateGlobalPrivilege EnabledByDefault, Enabled
SeIncreaseWorkingSetPrivilege Enabled
SeTimeZonePrivilege Enabled
SeCreateSymbolicLinkPrivilege Enabled
SeDelegateSessionUserImpersonatePrivi... Enabled
↑ Working!
PS C:\Users\Username> Set-Privilege SeCreateSymbolicLinkPrivilege
Set-Privilege : Cannot bind parameter 'Privileges'. Cannot convert the "SeCreateSymbolicLinkPrivilege" value of type "S
ystem.String" to type "Pscx.Interop.TokenPrivilege".
At line:1 char:15
+ Set-Privilege SeCreateSymbolicLinkPrivilege
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Privilege], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Pscx.Commands.Security.SetPrivilegeCommand
PS C:\Users\Username> $oTP = New-Object PSCX.Interop.TokenPriviliege
New-Object : Cannot find type [PSCX.Interop.TokenPriviliege]: verify that the assembly containing this type is loaded.
At line:1 char:8
- $oTP = New-Object PSCX.Interop.TokenPriviliege
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
- FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
↑ Not working!
Unfortunately, as of now, I have not tested this accesschk and cannot provide any useful help regarding it.
See also
- 101