The Realm of the Verbal Processor

Jarvis's Ramblings

21 Comments »

  1. Do you know how to have the launchapp.wsf to schedule with “Highest Privileges”? I KNOW it’s a weird request, but it will fix a long, complicated problem that I’d rather not go into right now.

    Comment by Kevin | April 16, 2008

  2. I think the info you are looking for can be found on this page.

    That page says that to do this you need to set the runlevel property to “TASK_RUNLEVEL_HIGHEST”.

    I’ll let you figure out how to add that to the script. Once you get the answer, if you could post back what you find it would be appreciated!

    Comment by Jarvis | April 16, 2008

  3. Yeah, I found that page, and have been messing round for awhile. But, since I don’t really know VBScript, all I’ve added is this, following the format of other things in other examples:

    ‘********************************************************
    ‘ Set the principal for the task
    ‘********************************************************
    Dim principal
    Set principal = taskDefinition.Principal
    principal.RunLevel = TASK_RUNLEVEL_HIGHEST

    Or, instead of TASK_RUNLEVEL_HIGHEST, I think it may be 1. The former creates the task, the latter doesn’t, but neither actually have the checkbox marked for “Run with highest privileges.” If I could also just edit it to call from an XML file (which IS possible), would be great, but, even though I see the page on that site for it, I don’t understand it, and they give no examples.

    Comment by Kevin | April 16, 2008

  4. Yeah, I also had a hard time finding information on this as well. It is definitely not well documented…or at least not in such a way that those of us who don’t know what we are doing can do something useful!

    Comment by Jarvis | April 16, 2008

  5. Apparently that does work — however, it requires admin privileges now to run the script, which, of course, defeats the purpose. *sigh* Now if I could find the way to import an XML file, THAT might work.

    Comment by Kevin | April 16, 2008

  6. Oh, and it works with the principal.RunLevel = 1, instead of TASK_RUNLEVEL_HIGHEST

    Comment by Kevin | April 16, 2008

  7. [NOTE from Jarvis: Since this is a script, I felt the need to note that I have not tested this script. I do not know if it works or doesn’t work. I do not know if what Kelderek added is good/bad/ugly/destructive/etc. Any use of this script (or any that I write and post for that matter) are strictly “use at your own risk”. Unless you have personally vetted out every line of this script (or any other script on this site), do not use it in a production environment…which you should be doing anyway. I have actually been holding this as an unapproved comment for nearly a year since Kelderek posted it…because I wanted to ensure that it wasn’t a bad script. Realizing that I will never have the time to properly vet the script myself, I decided to put this disclaimer on it instead. Okay…now that I’ve got that off my chest…Here are Kelderek’s modifications.]

    I have modified the script and wanted to share it. The format function that was being using called a DLL that isn’t installed by default with Windows. Also I modified it to create a unique task name every time so it can be called with multiple scripts and also set it up to delete the task automatically. Hopefully it will let me paste it into this comment….

    ‘———————————————————
    ‘ This sample launches the application as interactive user.
    ‘———————————————————
    const TriggerTypeRegistration = 7 ‘ A constant that specifies a registration trigger.
    const ActionTypeExecutable = 0 ‘ A constant that specifies an executable action.
    const FlagTaskCreate = 2 ‘ A constant that specifies the flag in RegisterTaskDefinition.
    const LogonTypeInteractive = 3 ‘ A constant that specifies an executable action.
    const MaxTaskTime = 5 ‘The length of time in minutes before the task is automatically deleted

    If WScript.Arguments.Length 1 Then
    WScript.Quit
    End If

    strAppPath = WScript.Arguments(0) ‘ This is the script to run.

    ‘********************************************************
    ‘ Is this Vista or XP?
    ‘ Begin the section added by Jarvis
    ‘********************************************************
    ‘ This section that determines OS version is a modified version of code
    ‘ originally posted at the following web page:
    http://blog.eqinox.net/jed/archive/2006/12/05/1270.aspx

    Dim NotVistaClient
    Dim wshShell

    NotVistaClient = False
    Set wshShell = CreateObject(“WScript.Shell”)
    Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2”)
    Set objOSList = objWMIService.ExecQuery(“Select * from Win32_OperatingSystem”)
    For Each os In objOSList
    BuildNumber = OS.BuildNumber
    If BuildNumber < 6000 Then
    NotVistaClient = True
    End If
    Next
    If NotVistaClient = True Then
    wshShell.Run(strAppPath), 0, False ‘ Run the logon script normally
    WScript.Quit
    Else ‘ Run the logon script using launchapp.wsf
    ‘********************************************************
    ‘ The next lines set a string variable that adds time MaxTaskTime to the
    ‘ current date/time to be used to set an expiration to the scheduled task.
    ‘********************************************************
    Dim atb

    atb = “HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias”
    offsetMin = wshShell.RegRead(atb) / 60 ‘get the time offset from the registry and convert it into the hour offset. This script will probably need modification for non-US locales
    cdt = DateAdd(“n”,MaxTaskTime,Now()) ‘Add time to the current date and time so we can set the trigger expiration to that
    ExpireTime = Year(cdt) & “-” & TwoDigit(Month(cdt)) & “-” & TwoDigit(Day(cdt)) &_
    “T” & TwoDigit(Hour(cdt)) & “:” & TwoDigit(Minute(cdt)) & “:” & TwoDigit(Second(cdt)) &_
    “-” & TwoDigit(offsetMin) & “:00”

    Function TwoDigit(vExpression) ‘makes single digit numbers have a leading 0
    If vExpression < 10 Then
    TwoDigit = “0” & vExpression
    Else
    TwoDigit = vExpression
    End If
    End Function

    ‘********************************************************
    ‘********************************************************
    ‘ End the section added by Jarvis
    ‘********************************************************
    ‘********************************************************
    ‘ Create the TaskService object.
    ‘********************************************************
    Set service = CreateObject(“Schedule.Service”)
    call service.Connect()
    Set TypeLib = CreateObject(“Scriptlet.TypeLib”) ‘Used only to generate a GUID
    strTaskName = “Logon script task ” & mid(TypeLib.GUID,2,36) ‘Give it a unique name using the GUID without the { }
    ‘********************************************************
    ‘ Get a folder to create a task definition in.
    ‘********************************************************
    Dim rootFolder
    Set rootFolder = service.GetFolder(“\”)
    ‘Delete the task if already present
    On Error Resume Next
    call rootFolder.DeleteTask(strTaskName, 0)
    Err.Clear
    ‘********************************************************
    ‘ Create the new task
    ‘********************************************************
    Dim taskDefinition
    Set taskDefinition = service.NewTask(0)
    ‘********************************************************
    ‘ Create a registration trigger.
    ‘********************************************************
    Dim triggers
    Set triggers = taskDefinition.Triggers
    Dim trigger
    Set trigger = triggers.Create(TriggerTypeRegistration)
    trigger.EndBoundary = ExpireTime ‘Set the task to expire so it can be deleted automatically
    ‘***********************************************************
    ‘ Create the action for the task to execute.
    ‘***********************************************************
    ‘ Add an action to the task. The action executes the app.
    Dim Action
    Set Action = taskDefinition.Actions.Create( ActionTypeExecutable )
    Action.Path = strAppPath
    ‘***********************************************************
    ‘ Set the settings for the task
    ‘***********************************************************
    Dim settings
    Set settings = taskDefinition.Settings
    settings.DeleteExpiredTaskAfter = “PT0M” ‘Delete the task immediately after the trigger expires
    ‘***********************************************************
    ‘ Register (create) the task.
    ‘***********************************************************
    call rootFolder.RegisterTaskDefinition(strTaskName, taskDefinition, FlagTaskCreate,,, LogonTypeInteractive)
    End If

    Comment by Kelderek | September 19, 2008

  8. Jarvis,

    I am having a couple of issues with this. The code that you added to add the additional time to the taskscheduler requires the file MSSTDFMT.dll be present on the machine. This is not true of my installation. the second issue is that with this and with the sample script provided by Microsoft, the computer still prompts you twice when you login to tell you that it is scheduling the task and that the task has been scheduled. The drive mapping should be transparant at login.

    Any suggestions?

    Comment by Joe | February 18, 2009

  9. I’m pretty sure (could be wrong) that “MSSTDFMT.dll” comes from one of the .NET Framework packages, so you might want to check that.

    I never got the prompts when scheduling the task…it was all silent. Sounds like something particular to your environment/setup that unfortunately I don’t have an answer to. But for that matter…if you don’t have the “MSSTDFMT.dll” file…how are you getting the script to run in the first place?

    Comment by Jarvis | February 18, 2009

  10. I’ll try installing the .Net Framework packages. I imagine you are probably correct on this account.
    As for my environment, i’m running a test computer with a clean installation of Windows Vista Business using default settings loaded at installation.
    As for getting the script to run without the file, I commented out the section that adds the time to try and troubleshoot where the script was failing.

    Comment by Joe | February 18, 2009

  11. The specific two messageboxes that I am getting are:

    Task definition created. About to submit the task…

    Task Submitted.

    Comment by Joe | February 18, 2009

  12. Do you have any idea about the prompts now that I’ve given you some more specifics on my environment?

    Comment by Joe | February 18, 2009

  13. As Jarvis said, it might be environment specific, but the easy fix is to just delete the two lines that start with wscript.echo, as those are what you use to output text in message box format with VBscript.

    On a side note, wscript.echo is an excellent tool when troubleshooting your login scripts as you can insert in places throughout your code so you can see where the code is going, what values are being held in variables, etc.

    Comment by Jon | February 20, 2009

  14. Thanks Jon. I haven’t had time to look at the script myself this week, but after seeing your comment I remembered doing exactly that. I did have the message boxes that Joe mentioned initially, and commenting/deleting those lines in the script is exactly how I got rid of them.

    Great job chief!

    Comment by Jarvis | February 20, 2009

  15. Hey Jarvis, I see you found my posts from 2007 at

    http://mcpradio.com/forums/forum_posts.asp?tid=3604&pn=1
    http://mcpmag.com/forums/forum_posts.asp?tid=3604&pn=1
    http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/Windows_Vista/Q_23844140.html
    http://www.freelists.org/post/gptalk/Vista-logon-scripts-launchappwsf-and-the-other-need-to-know

    I was trying to get the word out back then about Vista/Group Policy/and elevated tokens.

    I should have a copy of the the original launchapp2.wsf at home if you want to compare your script against it. Alot has happened since 2007 so I’m sure yours has added features. The benefit with launchapp2.wsf is that you could incorporate it into all needed GP scripts and it would work with both Vista and XP – so you wouldnt have to have seperate GPO’s for each operating system. I’ll see if I can find it and post it for you.

    Kudos – Thanks for writing the new article and the newer script! Keep it coming….

    Comment by MrMMills | April 15, 2009

  16. Hi Jarvis-
    I have gone through the above post that is recalls me an issue while executing the below vbscript:
    Vbscript to create a Schedule Task:-
    ————————————————————————————————
    Const TASK_TRIGGER_DAILY = 2
    Const TASK_ACTION_EXEC = 0
    Const TASK_CREATE = 2
    Const TASK_RUNLEVEL_HIGHEST = 1

    Set objService = CreateObject(“Schedule.Service”)
    objService.Connect

    Set objFolder = objService.GetFolder(“\”)

    Set objTaskDefinition = objService.NewTask(0)

    Set colTasks = objTaskDefinition.Triggers

    Set objTrigger = colTasks.Create(TASK_TRIGGER_DAILY)

    objTrigger.DaysInterval = 1
    objTrigger.StartBoundary = “2006-06-27T08:00:00-00:00”

    Set colActions = objTaskDefinition.Actions

    Set objAction = colActions.Create(TASK_ACTION_EXEC)
    objAction.ID = “Daily Task Test”
    objAction.Path = “C:\Windows\System32\sdclt.exe”

    Set objInfo = objTaskDefinition.RegistrationInfo

    objInfo.Author = “Administrator”
    objInfo.Description = “Test task that displays Windows Backup Status and Configuration tool daily.”

    Set objSettings = objTaskDefinition.Settings
    objSettings.Enabled = True
    objSettings.Hidden = False

    Set objSecurity = objTaskDefinition.Principal
    objSecurity.RunLevel = TASK_RUNLEVEL_HIGHEST

    objFolder.RegisterTaskDefinition “Test Daily Trigger”, objTaskDefinition, TASK_CREATE, , , 0
    ———————————————————————————————–

    Executing the above script prompts an error message:
    Error:Permission denied
    Code:800A0046
    Source: Microsoft vbscript Runtime error

    Can you please assist if we can create the scheduled task with the above code with any error message???
    Thanks in advance

    Comment by Deepak | April 20, 2009

  17. Sorry chief…I’m swamped…no way I can help with this. Maybe someone else who reads this will help you out.

    Comment by Jarvis | April 21, 2009

  18. When I add the following, the task is not created… Without it, it works.. but I really need the highest level

    Dim principal
    Set principal = taskDefinition.Principal
    taskDefinition.RunLevel = TASK_RUNLEVEL_HIGHEST

    Any ideas???

    Comment by Michael | August 26, 2009

  19. [NOTE from Jarvis: Since this is a script, I felt the need to note that I have not tested this script. I do not know if it works or doesn’t work. I do not know if what urxter added is good/bad/ugly/destructive/etc. Any use of this script (or any that I write and post for that matter) are strictly “use at your own risk”. Unless you have personally vetted out every line of this script (or any other script on this site), do not use it in a production environment…which you should be doing anyway. ]

    Hi Jarvis an Kerderek

    Thanks a lot for the nice script! I’m in Europe and the time zone offset is -60. The negative value was not properly handled and it was neccessary to improve the preparation of the offset string (as mentioned in your comment). The minutes are also taken into account now (“+01:15” will also be possible offset string now). I also added an “On Error GoTo 0” to restore the default error behaviour after trying to delete an existing task.
    I use this script on Windows 7, did not test it on Vista or XP right now. The code was messed up in the prevoius posts, maybe the use of the code tag prevents it for my post:

    '---------------------------------------------------------
    ' This sample launches the application as interactive user.
    '---------------------------------------------------------

    const TriggerTypeRegistration = 7 ' A constant that specifies a registration trigger.
    const ActionTypeExecutable = 0 ' A constant that specifies an executable action.
    const FlagTaskCreate = 2 ' A constant that specifies the flag in RegisterTaskDefinition.
    const LogonTypeInteractive = 3 ' A constant that specifies an executable action.
    const MaxTaskTime = 5 'The length of time in minutes before the task is automatically deleted

    If WScript.Arguments.Length 1 Then
    WScript.Echo "Usage: cscript launchapp.wsf "
    WScript.Quit
    End If

    strAppPath = WScript.Arguments(0) ' This is the script to run.

    '********************************************************
    ' Is this Vista or XP?
    ' Begin the section added by Jarvis
    '********************************************************

    ' This section that determines OS version is a modified version of code
    ' originally posted at the following web page:
    ' http://blog.eqinox.net/jed/archive/2006/12/05/1270.aspx
    '
    Dim NotVistaClient
    Dim wshShell

    NotVistaClient = False
    Set wshShell = CreateObject("WScript.Shell")
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set objOSList = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    For Each os In objOSList
    BuildNumber = OS.BuildNumber
    If BuildNumber < 6000 Then
    NotVistaClient = True
    End If
    Next
    If NotVistaClient = True Then
    wshShell.Run(strAppPath), 0, False ' Run the logon script normally
    WScript.Quit
    Else ' Run the logon script using launchapp.wsf

    '********************************************************
    ' The next lines set a string variable that adds time MaxTaskTime to the
    ' current date/time to be used to set an expiration to the scheduled task.
    '********************************************************

    Dim atb

    atb = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias"
    offset = wshShell.RegRead(atb) / 60 'get the time offset from the registry and convert it into the hour offset. This script will probably need modification for non-US locales
    offsetHour = offset Mod 60
    offsetMin = offset \ 60
    If offset < 0 Then
    strOffset = "+" & TwoDigit(offsetHour) & ":" & TwoDigit(offsetMin)
    Else
    strOffset = "-" & TwoDigit(offsetHour) & ":" & TwoDigit(offsetMin)
    End If
    cdt = DateAdd("n",MaxTaskTime,Now()) 'Add time to the current date and time so we can set the trigger expiration to that
    ExpireTime = Year(cdt) & "-" & TwoDigit(Month(cdt)) & "-" & TwoDigit(Day(cdt)) &_
    "T" & TwoDigit(Hour(cdt)) & ":" & TwoDigit(Minute(cdt)) & ":" & TwoDigit(Second(cdt)) &_
    strOffset

    Function TwoDigit(vExpression) 'makes single digit numbers have a leading 0 and returns only positive values
    If Abs(vExpression) < 10 Then
    TwoDigit = "0" & Abs(vExpression)
    Else
    TwoDigit = Abs(vExpression)
    End If
    End Function

    '********************************************************
    '********************************************************
    ' End the section added by Jarvis
    '********************************************************
    '********************************************************
    ' Create the TaskService object.
    '********************************************************

    Set service = CreateObject("Schedule.Service")
    call service.Connect()
    Set TypeLib = CreateObject("Scriptlet.TypeLib") 'Used only to generate a GUID
    strTaskName = "Logon script task " & mid(TypeLib.GUID,2,36) 'Give it a unique name using the GUID without the { }

    '********************************************************
    ' Get a folder to create a task definition in.
    '********************************************************

    Dim rootFolder
    Set rootFolder = service.GetFolder("\")

    'Delete the task if already present
    On Error Resume Next
    call rootFolder.DeleteTask(strTaskName, 0)
    Err.Clear
    On Error GoTo 0

    '********************************************************
    ' Create the new task
    '********************************************************

    Dim taskDefinition
    Set taskDefinition = service.NewTask(0)

    '********************************************************
    ' Create a registration trigger.
    '********************************************************

    Dim triggers
    Set triggers = taskDefinition.Triggers

    Dim trigger
    Set trigger = triggers.Create(TriggerTypeRegistration)
    trigger.EndBoundary = ExpireTime 'Set the task to expire so it can be deleted automatically

    '***********************************************************
    ' Create the action for the task to execute.
    '***********************************************************

    ' Add an action to the task. The action executes the app.
    Dim Action
    Set Action = taskDefinition.Actions.Create( ActionTypeExecutable )
    Action.Path = strAppPath

    '***********************************************************
    ' Set the settings for the task
    '***********************************************************

    'Dim settings
    Set settings = taskDefinition.Settings
    settings.DeleteExpiredTaskAfter = "PT0M" 'Delete the task immediately after the trigger expires

    '***********************************************************
    ' Register (create) the task.
    '***********************************************************

    call rootFolder.RegisterTaskDefinition(strTaskName, taskDefinition, FlagTaskCreate,,, LogonTypeInteractive)
    End If

    Comment by urxter | March 4, 2010

  20. For some reason if I take out the last WScript.Echo my Drive mapping script fails. I don’t know why? But I can just take that one line out and that breaks it. I have 2 scripts running from two different GP’s. Any ideas? My printer script seems to run either way. I’ll take having to hit okay for now. It just seem weird to me.

    Thanks for the help!

    Comment by Bryan David Williams | May 18, 2010

  21. Post 19 has a typo.
    If WScript.Arguments.Length 1 Then
    should read
    If WScript.Arguments.Length 1 Then

    There’s a more obvious omission at the beginning and end of the script, but if you can’t figure that one out you probably shouldn’t be using it anyway!

    Big thanks to all of the previous posters, this really shouldn’t be such a headache.

    Comment by DaveO | June 9, 2010


Leave a comment