UAC, Logon Scripts, and the Launchapp.wsf workaround

When UAC is enabled on Windows Vista and higher, logon scripts that map network drives do not appear to work for users who are administrators on their computer.  This is described in the Group Policy Scripts can fail due to User Account Control section of this TechNet article:

Deploying Group Policy Using Windows Vista
https://technet.microsoft.com/en-us/library/cc766208(WS.10).aspx

This happens because logon scripts run with an administrative user’s full token.  The desktop then loads with the user’s limited token.  The split token sessions do not share the view of network resources, so the mapped drives are not visible when the desktop loads.  The workaround in the article above involves using a wrapper script, Launchapp.wsf, as the logon script.  This deletes and recreates a scheduled task to launch the real logon script when the scheduled task is created.  (The schedule trigger is whenever the scheduled task is created or changed.)  This scheduled task is set to run as the logged on user and will launch in the limited token session.  This will allow the drives to be visible to the user in the limited token session.

Unfortunately, an recent customer case pointed out an issue with using Launchapp.wsf.  Launching a logon script in this way can cause the logon script to fail on shared computers, especially on machines where users who are administrators share the machine with users who are standard users.  After an administrative user logs on and off, standard users will not have the permissions necessary to delete the schedule task and the script will fail.

To work around this issue, I have created a new version of Launchapp.wsf (attached below).  I took the existing version of Launchapp.wsf and combined it with code from John Howard’s blog (https://blogs.technet.com/jhoward/archive/2008/11/19/how-to-detect-uac-elevation-from-vbscript.aspx).  If this version of Launchapp.wsf detects it is running elevated, it deletes/creates the scheduled task as the original did.  If it is not running elevated, it simply launches the app or script passed on the command line directly.

- Michael Murgolo, Senior Consultant, Microsoft Services, U.S. East Region.

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use .

Launchapp.zip

Comments

  • Anonymous
    January 01, 2003
    Brett, I know of a few customers using this successfully, so this may be due to Sysvol permissions in your environment.  Can your standard users launch the script directly from the Sysvol folder? Michael Murgolo

  • Anonymous
    January 01, 2003
    Tim Bernhardson, I was just looking at MSDN and you may also have to set the userid for the trigger as well.  So you may need this additional change. Change this:    Set trigger = triggers.Create(TriggerTypeRegistration) To this:     Set trigger = triggers.Create(TriggerTypeRegistration)
        trigger.UserId = strNTUserPath Let me know how it goes. Michael Murgolo

  • Anonymous
    January 01, 2003
    Changing your GPO Login script to Inject directly into registry seems to work without this messing about. Example: $sLetter = "K" $sUNC = "\Server1MyServer" New-Item -Path Registry::HKCUNetwork$sLetter New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "RemotePath" -PropertyType String -Value $sUNC New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "UserName" -PropertyType String -Value "" New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "ProviderName" -PropertyType String -Value "Microsoft Windows Network" New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "ProviderType" -PropertyType Dword -Value 0x00020000 New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "ConnectionType" -PropertyType Dword -Value 0x00000002 New-ItemProperty -Path Registry::HKCUNetwork$sLetter -Name "DeferFlags" -PropertyType Dword -Value 0x00000004

  • Anonymous
    January 01, 2003
    Heath, I updated the script to handle the case when running on a legacy OS (XP/2003).  Give it a try. Michael Murgolo

  • Anonymous
    January 01, 2003
    Works fine on single user computers, however on Servers ( I.E. Terminal Services ) it only works for the first session for Administrative users - the scheduled task always runs in the first session so if you have multiple sessions on the server only the first one gets the maps... Any idea of a work around?

  • Anonymous
    January 01, 2003
    Tim Bernhardson, Perhaps making the task name user-specific will help for the terminal services scenario.  Try the following change and let me know if it works.  If it does I'll change the download. Change this:    strTaskName = "Launch App As Interactive User" to this:     Set objWshNetwork = CreateObject("Wscript.Network")
        strUser = objWshNetwork.UserName
        strDomain = objWshNetwork.UserDomain
        strNTUserPath = strDomain & "" & strUser
        strTaskName = "Launch App As Interactive User - " & strNTUserPath Thanks, Michael Murgolo

  • Anonymous
    July 09, 2010
    Thank you. Works great....

  • Anonymous
    July 26, 2010
    Well, the script appears to half work. While trying to use the LaunchApp helper, things work good for administrators. However, for non-elevated users, the user does not have enough permissions to launch the logon script. Any workaround for this?

  • Anonymous
    August 12, 2010
    I'm not a VB programmer so what could I add to get it to work in a XP, Vista, and Win 7 (both 32 and 64bit) environment.  I know it's not working in Windows XP right now.

  • Anonymous
    August 29, 2010
    when you want to run exe it doesnt run so i changed it  like this: If WScript.Arguments.Length <> 2 Then    WScript.Echo "Usage: cscript launchapp.wsf <AppPath> <Arguments>" WScript.Echo "Usage: if there are no arguments use """""    WScript.Quit End If strAppPath = WScript.Arguments(0) strAppArgs = WScript.Arguments(1) If GetWmiPropertyValue("rootcimv2", "Win32_OperatingSystem", "BuildNumber") >= 6000 Then    ' Running on Vista or higher.  Check if running elevated.    If IsElevated Then        LaunchAsScheduledTask strAppPath,strAppArgs    Else        LaunchDirectly strAppPath,strAppArgs    End If Else    ' Running on legacy OS (XP/2003 or lower).    LaunchDirectly strAppPath,strAppArgs End If Sub LaunchAsScheduledTask(strAppPath,strAppArgs) . . . . . Dim Action    Set Action = taskDefinition.Actions.Create( ActionTypeExecutable )    Action.Path = strAppPath    Action.Arguments = strAppArgs    WScript.Echo "Task definition created. About to submit the task..." . . . . .

  • Anonymous
    November 25, 2013
    The comment has been removed

  • Anonymous
    July 20, 2016
    One more quick update to this for everyone running this mechanism on laptops - the default programmatic scheduled task will NOT run if the laptop is on battery power. Easy fix in the code...set tasksettings = taskDefinition.Settingstasksettings.DisallowStartIfOnBatteries = False