OpenVPN as non privileged user

The entire process that is described here be watched at youtube here. These days a lot of users do not work as privileged user, they do not have administrative rights on their computers. If such a user needs to establish an OpenVPN connection (OpenVPN and OpenVPN-GUI are already installed) the connection will be established but the necessary routes are not set. Setting routes in Windows has some requirements:

| Operating System   | ADM | NCO | RHP |
| Windows XP         |  X  |     |     |
| Windows XP         |     |  X  |     |
| Windows 7          |  X  |     |     |
| Windows 7          |     |  X  |  X  |
| Windows 8          |  X  |     |     |
| Windows 8          |     |  X  |  X  |
RHP = run with highest privileges but in context of a non-administrative user
ADM = Member of group "Administrators"
NCO = Member of group "Network Configuration Operators"

Note: Since Windows 7 being only a member of the "Network Configuration Operators" group is not enough to be able to set routes.

There are some OpenVPN-Clients that are able to establish connections and setting routes without administrative privileges but they are either unstable SecurePoint SSL VPN) or do not have all necessary features (OpenVPN MI GUI). They both use a service (running as administrator) and communicate with the service from user mode. But sometimes your configuration does not allow "service mode" and so you are stuck.

Solution for Windows XP

Add the non privileged user (e.g. bob) to the group

Network Configuration Operators

You can do this with the following command

net localgroup "Network Configuration Operators" bob /add

and OpenVPN-GUI will perfectly work without administrative privileges.

This solution does no longer work with Windows 7 and above.

New and working solution for Windows 7 (and above)

In July 2013 I had an idea. Why not creating a scheduled task at logon of any user that automatically creates another Scheduled Task for the non privileged user that is currently logging on. This automatically created task will put the user in the group "Network Configuration Operators" and then start OpenVPN GUI automatically at the next logon of this (non privileged) user (with highest privileges).

You need to walk through some small steps to achieve this goal.

2 scripts that help us

Script 1 create_main_task_only_runonce.cmd


REM Detect current user (should be an administrator)
SET TASKNAME=OpenVPN Logon Task Creator (main)

REM Where to store the created XML-File
SET XML=%temp%\%RANDOM%_temp.xml

REM What to start via the generated task
SET TOSTART=C:\ProgramData\OpenVPN\create_usertask.cmd

ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%"
ECHO ^<Task version="1.3" xmlns=""^> >> "%XML%"
echo.   ^<RegistrationInfo^> >> "%XML%"
echo.     ^<Date^>2001-01-01T01:01:01.01^</Date^> >> "%XML%"
echo.     ^<Author^>Der PCFreak^</Author^> >> "%XML%"
echo.     ^<Description^>This task will be executed at logon of any user. The script will then determine the username and domain/computer of this user. The user will then added to the group "Network Configuration Operators" and additionally a new scheduled task with name "%DOM%_%USER%_openvpn" will be created. The automatically created task will be set up to only run when the specific, detected user logs on. This task will then start OpenVPN-GUI with highest privileges at logon.^</Description^> >> "%XML%"
echo.   ^</RegistrationInfo^> >> "%XML%"

echo.   ^<Triggers^> >> "%XML%"
echo.     ^<LogonTrigger^> >> "%XML%"
echo.       ^<StartBoundary^>2001-01-01T01:01:01^</StartBoundary^> >> "%XML%"
echo.       ^<Enabled^>true^</Enabled^> >> "%XML%"
echo.     ^</LogonTrigger^> >> "%XML%"
echo.   ^</Triggers^> >> "%XML%"

echo.   ^<Principals^> >> "%XML%"
echo.     ^<Principal id="Author"^> >> "%XML%"
echo.       ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
echo.       ^<LogonType^>Password^</LogonType^> >> "%XML%"
echo.       ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%"
echo.     ^</Principal^> >> "%XML%"
echo.   ^</Principals^> >> "%XML%"

echo.   ^<Settings^> >> "%XML%"
echo.     ^<MultipleInstancesPolicy^>IgnoreNew^</MultipleInstancesPolicy^> >> "%XML%"
echo.     ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%"
echo.     ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%"
echo.     ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%"
echo.     ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%"
echo.     ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%"
echo.     ^<IdleSettings^> >> "%XML%"
echo.       ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%"
echo.       ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%"
echo.     ^</IdleSettings^> >> "%XML%"
echo.     ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%"
echo.     ^<Enabled^>true^</Enabled^> >> "%XML%"
echo.     ^<Hidden^>false^</Hidden^> >> "%XML%"
echo.     ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%"
echo.     ^<WakeToRun^>false^</WakeToRun^> >> "%XML%"
echo.     ^<ExecutionTimeLimit^>P3D^</ExecutionTimeLimit^> >> "%XML%"
echo.     ^<Priority^>7^</Priority^> >> "%XML%"
echo.   ^</Settings^> >> "%XML%"

echo.   ^<Actions Context="Author"^> >> "%XML%"
echo.     ^<Exec^> >> "%XML%"
echo.       ^<Command^>"%TOSTART%"^</Command^> >> "%XML%"
echo.     ^</Exec^> >> "%XML%"
echo.   ^</Actions^> >> "%XML%"

echo ^</Task^> >> "%XML%"

REM Create the task using schtasks
REM use /f to make sure we can re-create this task on demand
%windir%\system32\schtasks.exe /create /TN "%TASKNAME%" /XML "%XML%" /RU %ACCOUNT% /RP "" /F

REM Delete temporary XML FILE
DEL /Q "%XML%"

Please verify the variable TOSTART at the beginning of the script. It must represent the physical location of create_usertask.cmd (our second script).

Script 2 create_usertask.cmd


REM Some Variables

REM Where to store the created XML-File
SET XML=%temp%\%RANDOM%_temp.xml

REM Name of the Network Configuration Operators group (without quotes)
SET NGROUP=Network Configuration Operators

REM What to start via the generated task
SET TOSTART=C:\Program Files\OpenVPN\bin\openvpn-gui.exe

REM We need to find the domain/computer and username of the user that is logging on
REM We run under a different user context so we need a trick to do that
REM Session to search, usually "console"
REM Process to search, usually "explorer.exe"
SET PROCESS=explorer.exe
for /f "usebackq tokens=8,9 delims=\ " %%a IN (`tasklist /fi "SESSIONNAME eq %SESSION%" /FI "IMAGENAME eq %PROCESS%" /V /NH`) do (
  SET DOM=%%a
  SET USER=%%b
  SET ACCOUNT=%%a\%%b
echo The detected user was %USER% in domain/computer %DOM% .

ECHO ^<?xml version="1.0" encoding="UTF-16"?^> > "%XML%"

ECHO.  ^<Task version="1.3" xmlns=""^> >> "%XML%"

ECHO. ^<Settings^> >> "%XML%"
ECHO.   ^<MultipleInstancesPolicy^>StopExisting^</MultipleInstancesPolicy^> >> "%XML%"
ECHO.   ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^> >> "%XML%"
ECHO.   ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^> >> "%XML%"
ECHO.   ^<AllowHardTerminate^>true^</AllowHardTerminate^> >> "%XML%"
ECHO.   ^<StartWhenAvailable^>false^</StartWhenAvailable^> >> "%XML%"
ECHO.   ^<RunOnlyIfNetworkAvailable^>false^</RunOnlyIfNetworkAvailable^> >> "%XML%"
ECHO.    ^<IdleSettings^> >> "%XML%"
ECHO.     ^<StopOnIdleEnd^>true^</StopOnIdleEnd^> >> "%XML%"
ECHO.     ^<RestartOnIdle^>false^</RestartOnIdle^> >> "%XML%"
ECHO.    ^</IdleSettings^> >> "%XML%"
ECHO.   ^<AllowStartOnDemand^>true^</AllowStartOnDemand^> >> "%XML%"
ECHO.   ^<Enabled^>true^</Enabled^> >> "%XML%"
ECHO.   ^<Hidden^>false^</Hidden^> >> "%XML%"
ECHO.   ^<RunOnlyIfIdle^>false^</RunOnlyIfIdle^> >> "%XML%"
ECHO.   ^<DisallowStartOnRemoteAppSession^>false^</DisallowStartOnRemoteAppSession^> >> "%XML%"
ECHO.   ^<UseUnifiedSchedulingEngine^>false^</UseUnifiedSchedulingEngine^> >> "%XML%"
ECHO.   ^<WakeToRun^>false^</WakeToRun^> >> "%XML%"
ECHO.   ^<ExecutionTimeLimit^>PT0S^</ExecutionTimeLimit^> >> "%XML%"
ECHO.   ^<Priority^>7^</Priority^> >> "%XML%"
ECHO.  ^</Settings^> >> "%XML%"

ECHO.  ^<Actions Context="Author"^> >> "%XML%"
ECHO.   ^<Exec^> >> "%XML%"
ECHO.   ^<Command^>"%TOSTART%"^</Command^> >> "%XML%"
ECHO.   ^</Exec^> >> "%XML%"
ECHO.  ^</Actions^> >> "%XML%"

ECHO.  ^<RegistrationInfo^> >> "%XML%"
ECHO.   ^<Date^>2013-07-11T11:39:44.2138665^</Date^> >> "%XML%"
ECHO.   ^<Author^>Der PCFreak^</Author^> >> "%XML%"
echo.   ^<Description^>This task will run when the user %ACCOUNT% logs on. It will then start OpenVPN-GUI with in the context of this user with highest privileges at logon of this user.^</Description^> >> "%XML%"
ECHO.  ^</RegistrationInfo^> >> "%XML%"

ECHO.  ^<Principals^> >> "%XML%"
ECHO.   ^<Principal id="Author"^> >> "%XML%"
ECHO.   ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
ECHO.   ^<LogonType^>InteractiveToken^</LogonType^> >> "%XML%"
ECHO.   ^<RunLevel^>HighestAvailable^</RunLevel^> >> "%XML%"
ECHO.   ^</Principal^> >> "%XML%"
ECHO.  ^</Principals^> >> "%XML%"

ECHO.  ^<Triggers^> >> "%XML%"
ECHO.   ^<LogonTrigger^> >> "%XML%"
ECHO.   ^<Enabled^>true^</Enabled^> >> "%XML%"
ECHO.   ^<UserId^>%ACCOUNT%^</UserId^> >> "%XML%"
ECHO.   ^</LogonTrigger^> >> "%XML%"
ECHO.  ^</Triggers^> >> "%XML%"

ECHO. ^</Task^> >> "%XML%"

REM Create the task using schtasks
REM do not use /f since we only want to create this task once!
%windir%\system32\schtasks.exe /create /xml "%XML%" /tn "%DOM%_%USER%_openvpn" /DELAY 0000:25

REM Add the user to the Network Configuration Operators group
net localgroup "%NGROUP%" %ACCOUNT% /add

REM Delete temporary XML FILE
DEL /Q "%XML%"

Take a look at the beginning of the script and change the variables NGROUP and TOSTART to your localized version of the Network Configuration Operators group and your location of openvpn-gui.exe.

Install OpenVPN-GUI

Do a default installation of OpenVPN-GUI and also copy the necessary connection profiles to the target machine. Do this as administrative user.

Prepare and fix Registry Keys

Start OpenVPN-GUI once as an administrative user. This will create the following registry key:


Close OpenVPN-GUI. Open the registry editor (regedit.exe) and take a look at this registry key:


By default it points to

C:\Program Files\OpenVPN\log

This folder is not writeable by nonprivileged users, so they will get error messages when connecting.

Just change it to


With this change, a nonprivileged user logs to his personal temp folder, e.g.


Copy script files to target

Create the folder


and copy the above 2 script files


to this directory. Please double-check and make sure, that this files cannot be changed by non-privileged users!

Setup the main task

Use explorer.exe and jump to the directory where you stored the 2 scripts from above, usually


Right-click create_main_task_only_runonce.cmd and select Run as administrator. A command prompt will open and ask you for the password of the administrative account. Enter it correctly.

If everything went right, you have now a new scheduled task in the Task Scheduler Library with the name

OpenVPN Logon Task Creator (main)

It is setup to run

with the administrators account
with highest privileges
at logon of any user
executing C:\Programdata\OpenVPN\create_usertask.cmd

Verify the automated generation of this task.

Change OpenVPN-GUI shortcut

We now change the shortcut(s) that start OpenVPN to a different target.They are usually located here:

C:\Users\Public\Desktop\OpenVPN GUI.lnk
C:\Users\All Users\Microsoft\Windows\Start Menu\Programs\OpenVPN\OpenVPN GUI.lnk

Change all shortcuts to the following settings (via properties).

Target: %windir%\System32\schtasks.exe /RUN /TN "%USERDOMAIN%_%USERNAME%_openvpn"
Icon  : C:\Program Files\OpenVPN\icon.ico (or any other icon you like)

The rest of the settings can be left to their defaults.

Test it!

Logon as a nonprivileged user, let's assume, the username is user1 and he is logging on to machine win7x64-vm. The following will happen.

First logon

Main scheduled task will execute

The "main" scheduled task OpenVPN Logon Task Creator (main) will run. It will programmatically

add user1 to the localgroup "Network Configuration Operators"
create a userspecific scheduled task with the name win7x64_user1_openvpn

Since we changed the target for the OpenVPN-GUI shortcuts, the user can now already click the OpenVPN-GUI desktop icon, which will then run the scheduled task win7x64_user1_openvpn on demand. win7x64_user1_openvpn will then execute openvpn-gui.exe in the users context but with highest privileges.

Security related information

There are 2 registry keys, that are dangerous and can allow the user to open an administrative prompt on the machine. They are


When using my method and click on View Log or Edit config , by default notepad.exe will open (and of course) with highest privileges. To fix this, you should change the registry to an executable (you created), that shows an error message. I did this with a small AutoIT-Script, that does exactly that. I called it


The source is added to this Wiki page as


Without this change your installation is vulnerable and normal users can get an elevated command prompt, so absolutely change this registry keys!!!!

So I additionally changed the registry for OpenVPN-GUI to

Name : editor
Value: C:\ProgramData\OpenVPN\notallowed.exe

Name : log_viewer
Value: C:\ProgramData\OpenVPN\notallowed.exe 

Here is a screenshot:

When notallowed.exe is executed it just shows this message:

Future logons

Main scheduled task will execute

Since the main task has already run previously, it will NOT recreate the users personal scheduled task. - It does nothing.

User task will execute

Since the user task win7x64_user1_openvpn was present at logon, it get's executed and starts openvpn-gui.exe. So after the user logged in, he/she has the OpenVPN-GUI running in the system tray and is ready to establish connections without administrative privileges


My personal opinion is, that this is a nice workaround for the nonprivileged user problem. It can easily be deployed, it is Open Source and you can change it to your needs. If you use, change or blog it, please keep a line in your code, that refers to me (Der PCFreak) and my Blog (

If I have time, I will add some screenshots and I am planning to create a video on Youtube, that shows exactly how it works.

Since this was the first time I posted to this Wiki, I hope I made no mistakes and no errors.

Thank you for reading!

Last modified 8 years ago Last modified on 07/17/13 13:15:54

Attachments (3)

Download all attachments as: .zip