UAC, Logon Scripts, and the Launchapp.wsf workaround

UAC, Logon Scripts, and the Launchapp.wsf workaround

  • Comments 12
  • Likes

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

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 (  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.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • <p>Thank you. Works great.... </p>

  • <p>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?</p>

  • <p>Brett,</p> <p>I know of a few customers using this successfully, so this may be due to Sysvol permissions in your environment. &nbsp;Can your standard users launch the script directly from the Sysvol folder?</p> <p>Michael Murgolo</p>

  • <p>I&#39;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. &nbsp;I know it&#39;s not working in Windows XP right now.</p>

  • <p>Heath,</p> <p>I updated the script to handle the case when running on a legacy OS (XP/2003). &nbsp;Give it a try.</p> <p>Michael Murgolo</p>

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

  • <p>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...</p> <p>Any idea of a work around?</p>

  • <p>Tim Bernhardson,</p> <p>Perhaps making the task name user-specific will help for the terminal services scenario. &nbsp;Try the following change and let me know if it works. &nbsp;If it does I&#39;ll change the download.</p> <p>Change this:</p> <p>&nbsp; &nbsp;strTaskName = &quot;Launch App As Interactive User&quot;</p> <p>to this:</p> <p>&nbsp;&nbsp;&nbsp; Set objWshNetwork = CreateObject(&quot;Wscript.Network&quot;)<br />&nbsp;&nbsp;&nbsp; strUser = objWshNetwork.UserName<br />&nbsp;&nbsp;&nbsp; strDomain = objWshNetwork.UserDomain<br />&nbsp;&nbsp;&nbsp; strNTUserPath = strDomain &amp; &quot;\&quot; &amp; strUser<br />&nbsp;&nbsp;&nbsp; strTaskName = &quot;Launch App As Interactive User - &quot; &amp; strNTUserPath</p> <p>Thanks,</p> <p>Michael Murgolo</p>

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

  • <p>Changing your GPO Login script to Inject directly into registry seems to work without this messing about.</p> <p>Example:</p> <p>$sLetter = &quot;K&quot;</p> <p>$sUNC = &quot;\\Server1\MyServer&quot;</p> <p>New-Item -Path Registry::HKCU\Network\$sLetter</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;RemotePath&quot; -PropertyType String -Value $sUNC</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;UserName&quot; -PropertyType String -Value &quot;&quot;</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;ProviderName&quot; -PropertyType String -Value &quot;Microsoft Windows Network&quot;</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;ProviderType&quot; -PropertyType Dword -Value 0x00020000</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;ConnectionType&quot; -PropertyType Dword -Value 0x00000002</p> <p>New-ItemProperty -Path Registry::HKCU\Network\$sLetter -Name &quot;DeferFlags&quot; -PropertyType Dword -Value 0x00000004</p>

  • <p>Hi,</p> <p>I tryed to use the new version of launchapp.wsf you provided for launch a logon script for mapping drive and printers that I have made.</p> <p>The script that reported on this page works greate untill I use XP and with some Windows 7 pcs..</p> <p>I cannot understand why on some pc the launchapp.wsf goes into this part of the script:</p> <p>&#39;***********************************************************</p> <p> &nbsp; &nbsp;&#39; Create the action for the task to execute.</p> <p> &nbsp; &nbsp;&#39;***********************************************************</p> <p> &nbsp; &nbsp;&#39; Add an action to the task. The action executes the app.</p> <p> &nbsp; &nbsp;Dim Action</p> <p> &nbsp; &nbsp;Set Action = taskDefinition.Actions.Create( ActionTypeExecutable )</p> <p> &nbsp; &nbsp;Action.Path = strAppPath</p> <p> &nbsp; &nbsp;WScript.Echo &quot;Task definition created. About to submit the task...&quot;</p> <p>and</p> <p> &nbsp; &#39;***********************************************************</p> <p> &nbsp; &nbsp;&#39; Register (create) the task.</p> <p> &nbsp; &nbsp;&#39;***********************************************************</p> <p> &nbsp; &nbsp;call rootFolder.RegisterTaskDefinition(strTaskName, taskDefinition, FlagTaskCreate, ,, LogonTypeInteractive)</p> <p> &nbsp; &nbsp;WScript.Echo &quot;Task submitted.&quot;</p> <p>But after if cannot runs the logon.vbs that I created.</p> <p>I run the launchapp.wsf with a gropu policy and set as startupscritp (for user) with my logon.vbs as a parameter.</p> <p>What is really strange is that on some pc works and on others don&#39;t works.</p> <p>Could you pls help me? </p> <p>Sorry to trouble you, hope you can help me.</p> <p>Eugenio</p>

  • <p>Found the problem.</p> <p>I created a GPO that RUN as logon script the LAUNCHAPP.WSF in the parameter I wrote only the name of the script that is located in the same directory of the gpo.</p> <p>The problem is that I have to locate the logon.vbs (my vbs logon script) in a netowrk path and I have to put in the parameter the entire path.</p> <p>Thanks for you launchapp.wsf that works greate.</p> <p>Thx</p>