Search code examples
windowspowershellbatch-filecmdgroup-policy

Create SymLink with GPO


I have a BATCH script that makes symlinks with mklink. When I run it as an administrator or as a system account (with psexec -s -e) it works as it should. But when I try to use it in a GPO as a startup script it gives me an error "you do not have sufficient privilege to perform this operation" on a target computer. Windows 7 Pro SP1 x64. UAC is disabled.

Batch example:

mklink C:\log\cmd.link.exe C:\Windows\System32\cmd.exe >> C:\log\symlink.log 2>&1

I also tried to wrap it into a powershell script:

Start-Process -FilePath "$env:windir\system32\cmd.exe" -ArgumentList "/c mklink C:\log\cmd.link.exe C:\Windows\System32\cmd.exe >> C:\log\symlink.txt 2>&1" -Verb RunAs

but got the same error. What am I doing wrong?

Maybe there's another way to create a SymLink with GPO or PowerShell?


Solution

  • It appeared that the Group Policy Client (gpsvc) service (since GPO scripts runs with its privilegies) does not contain the privilege to create symolic links (SeCreateSymbolicLinkPrivilege):

    C:\>sc qprivs gpsvc
    [SC] QueryServiceConfig2 SUCCESS
    
    SERVICE_NAME: gpsvc
            PRIVILEGES       : SeTakeOwnershipPrivilege
                             : SeIncreaseQuotaPrivilege
                             : SeAssignPrimaryTokenPrivilege
                             : SeSecurityPrivilege
                             : SeChangeNotifyPrivilege
                             : SeCreatePermanentPrivilege
                             : SeShutdownPrivilege
                             : SeLoadDriverPrivilege
                             : SeRestorePrivilege
                             : SeBackupPrivilege
    

    If I want to use this privilege I should at first grant this privelege to the service. It can be done with this command:

    sc privs gpsvc SeTakeOwnershipPrivilege/SeIncreaseQuotaPrivilege/SeAssignPrimaryTokenPrivilege/SeSecurityPrivilege/SeChangeNotifyPrivilege/SeCreatePermanentPrivilege/SeShutdownPrivilege/SeLoadDriverPrivilege/SeRestorePrivilege/SeBackupPrivilege/SeCreateSymbolicLinkPrivilege
    

    After that you will be able to use mklink inside GPO scripts.

    There are several caveats:

    1. You should list all permissions (current + new). Otherwise you risk to replace all permissions with one.
    2. The command needs System account permission to set privileges so you'll need to use psexec or GPO script (not sure).
    3. If you intend to use psexec it will throw you an error about argument being too long. So you should save this command as a .bat file and then run it with psexec.

    Many thanks to @PetSerAl who helped me to find this out.