Jump to content
water

Creating a "brushed up" Task Scheduler UDF?

Would you like to see a brushed up Task Scheduler UDF (inlcuding help files, examples ...)?  

21 members have voted

  1. 1. Would you like to see such a brushed up UDF?

    • Yes
    • Don't mind
    • Maybe later
      0
    • No
      0


Recommended Posts

Hi @water

I'm currently testing the UDF, and have found an issue with _TS_TaskImportXML.  I have some XML files for task that I have exported manually, and I'm trying to import them.  Most of my tasks files have LogonType set to Password.  When I try to import them, I get @error=1707, @extended=-2147352567.  This is caused by the $oFolder.RegisterTaskDefinition call having empty strings for username and password.  According to the documentation for $TASK_LOGON_PASSWORD, "Use a password for logging on the user. The password must be supplied at registration time."  When I fill in the user name and password for the RegisterTaskDefinition call in the function, the task imports correctly.  I think it would be a good Idea to add optional parameters for user name and password to the function.  

Thanks,

 

Adam

 

Share this post


Link to post
Share on other sites

@AdamUL If it needs the username and password to register the task, it can't be optional... unless you don't plan on registering it? Or do your XML files have the username and password in them already?

Edited by seadoggie01

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Share this post


Link to post
Share on other sites

@seadoggie01  If you look in the code for _TS_TaskImportXML you will see that the task is registered with empty strings for the user name and password.  

Local $oTask = $oFolder.RegisterTaskDefinition($sTaskName, $oTaskDefinition, $TASK_CREATE, "", "", 0)
If @error Then Return SetError(1707, @error, 0)

This could easily be changed to 

Func _TS_TaskImportXML($oService, $sTaskPath, $iInputType, $vXMLInput, $sUserId = Default, $sPassword = Default)
    If $sUserId = Default Then $sUserId = ""
    If $sPassword = Default Then $sPassword = ""
.
.
.
    Local $oTask = $oFolder.RegisterTaskDefinition($sTaskName, $oTaskDefinition, $TASK_CREATE, $sUserId, $sPassword, 0)
    If @error Then Return SetError(1707, @error, 0)
.
.
.

No, the password is not stored, when you export a task with the "password" LoginType.  Also, the password is not stored in the XML file.  

 

Adam

Share this post


Link to post
Share on other sites

I think it makes sense to remove the Task Registration from the XML import function.
We already have a registration function that allows to pass userid and password.
So the XML import function would not create and return a Task but create a Task Definition object from the imported XML and return this object to the caller.
He could then do further modifications before calling _TS_TaskRegister (and provide usrid and password).

What do you think?
 


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Hi water, that sounds like a good idea.   _TS_TaskCopy would need to be updated as well, as it uses _TS_TaskImportXML.  _TS_TaskCopy also fails to copy a task with Principal LogonType set to Password, as is to be expected.  

 

Adam

 

Share this post


Link to post
Share on other sites

Version 1.3.0.0 released

Changelog can be found on the download page and the history in the ZIP file.

For download please see my signature below.

Please play with this version and tell me what doesn't work or is missing!


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
23 hours ago, AdamUL said:

Hi water, that sounds like a good idea.   _TS_TaskCopy would need to be updated as well, as it uses _TS_TaskImportXML.  _TS_TaskCopy also fails to copy a task with Principal LogonType set to Password, as is to be expected.  

Done 🙂


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Nice work water. 

I noticed something when registering an imported task.  If you want to keep the same Principal LogoType, as in the XML file, you need to call the _TS_TaskRegister function with $TASK_LOGON_NONE as the $iLogonType.  If you do not, it gets changed to the default, $TASK_LOGON_INTERACTIVE_TOKEN.

With Principal LogonType $TASK_LOGON_PASSWORD in the file.

Global $oTask = _TS_TaskRegister($oService, $sFolderName, $sTargetTaskName, $oTaskDefinition, "Domain\Username", "Password", $TASK_LOGON_NONE)

With other Principal LogonTypes in the file.  I would also use this in the example file for _TS_TaskImportXML.  

Global $oTask = _TS_TaskRegister($oService, $sFolderName, $sTargetTaskName, $oTaskDefinition, Default, Default, $TASK_LOGON_NONE)

 

This is also the case when you create a task, if you set the Principal LogonType with _TS_TaskPropertiesSet or _TS_Wrapper_PrincipalSet, and then register with _TS_TaskRegister or _TS_Wrapper_TaskRegister without additional parameters.  Using the following keeps the Principal LogonType set.  

_TS_Wrapper_TaskRegister($oService, "Test", "Test-DateTime-Daily", $oTaskDefinition, Default, Default, $TASK_LOGON_NONE)

Sorry, if I'm not describing it well enough.  As nothing really needs to change in the UDF itself, maybe an entry in the Wiki pointing this out.  

 

Adam

 

Share this post


Link to post
Share on other sites
48 minutes ago, AdamUL said:

As nothing really needs to change in the UDF itself, maybe an entry in the Wiki pointing this out.

That's exactly what I intend to do ;)
When working with the UDF we will better understand how the Task Scheduler is meant by MS to be used.
I - or everyone else - can update the wiki and save this hands-on experience so it might be helpful for others.

Thanks for testing and reporting your findings!

N.B.: Do you think it is sensible to change _TS_TaskRegister and set the default $iLogonType from $TASK_LOGON_INTERACTIVE_TOKEN to $TASK_LOGON_NONE?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites
22 hours ago, water said:

N.B.: Do you think it is sensible to change _TS_TaskRegister and set the default $iLogonType from $TASK_LOGON_INTERACTIVE_TOKEN to $TASK_LOGON_NONE?

That's a good question.  It would be a script breaking change.  If we do have $TASK_LOGON_NONE as the default for _TS_TaskRegister, then when you register a task you will need to explicitly state the LogonType you want when registering a created task.  If you set it in the principal or import a task with it set, then it wouldn't be an issue.  Is that what we want?  _TS_Wrapper_TaskRegister would need to be changed as well.  If we keep it the same, and you used _TS_Wrapper_PrincipalSet and then use _TS_Wrapper_TaskRegister with default settings, what you set could be changed.   

We could add some code in the the TaskRegister functions to check if there is a current LogonType, and use $TASK_LOGON_NONE instead of the default.  This would require an update to the UDF.  It wouldn't be script breaking.  I updated the functions below to show you what I mean.  Let me know what you think.  

Func _TS_TaskRegister($oService, $sFolder, $sName, $oTaskDefinition, $sUserId = Default, $sPassword = Default, $iLogonType = Default)
    If $sUserId = Default Then $sUserId = ""
    If $sPassword = Default Then $sPassword = ""
    If Not IsObj($oService) Then Return SetError(2101, 0, 0)
    If Not _TS_FolderExists($oService, $sFolder) Then Return SetError(2102, @error, 0)
    If _TS_TaskExists($oService, $sFolder & "\" & $sName) Then Return SetError(2103, @error, 0)
    If Not IsObj($oTaskDefinition) Then Return SetError(2104, 0, 0)
    Local $aTaskProperties = _TS_TaskPropertiesGet($oService, $oTaskDefinition, 1, True, "PRINCIPAL", "LogonType") ;<=== Added.
    If UBound($aTaskProperties, $UBOUND_ROWS) = 1 Then                                                             ;<=== Added.
        If $iLogonType = Default Then $iLogonType = $TASK_LOGON_NONE                                               ;<=== Added.
    Else                                                                                                           ;<=== Added.
        If $iLogonType = Default Then $iLogonType = $TASK_LOGON_INTERACTIVE_TOKEN                                  ;<=== Moved.
    EndIf                                                                                                          ;<=== Added.
    ; Register (create) the Task
    Local $oFolder = _TS_FolderGet($oService, $sFolder)
    If @error Then Return SetError(2105, @error, 0)
    Local $oTask = $oFolder.RegisterTaskDefinition($sName, $oTaskDefinition, $TASK_CREATE, $sUserId, $sPassword, $iLogonType)
    If @error Then Return SetError(2106, @error, 0)
    Return $oTask
EndFunc   ;==>_TS_TaskRegister
Func _TS_Wrapper_TaskRegister($oService, $sFolder, $sName, $oTaskDefinition, $sUserId = Default, $sPassword = Default, $iLogonType = Default)
    If Not IsObj($oService) Or ObjName($oService) <> "ITaskService" Then Return SetError(3001, 0, 0)
    If Not IsObj($oTaskDefinition) Or ObjName($oTaskDefinition) <> "ITaskDefinition" Then Return SetError(3004, 0, 0)
    If $sUserId = Default Then $sUserId = ""
    If $sPassword = Default Then $sPassword = ""
    If $iLogonType = Default Then $iLogonType = $TASK_LOGON_INTERACTIVE_TOKEN
    If Not _TS_FolderExists($oService, $sFolder) Then Return SetError(3002, @error, 0)
    If _TS_TaskExists($oService, $sFolder & "\" & $sName) Then Return SetError(3003, @error, 0)
    $oTaskDefinition.RegistrationInfo.Uri = $sFolder & "\" & $sName
    If @error Then Return SetError(3007, @error, 0)
    Local $aTaskProperties = _TS_TaskPropertiesGet($oService, $oTaskDefinition, 1, True, "PRINCIPAL", "LogonType") ;<=== Added.
    If UBound($aTaskProperties, $UBOUND_ROWS) = 1 Then                                                             ;<=== Added.
        If $iLogonType = Default Then $iLogonType = $TASK_LOGON_NONE                                               ;<=== Added.
    Else                                                                                                           ;<=== Added.
        If $iLogonType = Default Then $iLogonType = $TASK_LOGON_INTERACTIVE_TOKEN                                  ;<=== Moved.
    EndIf                                                                                                          ;<=== Added.
    ; Register (create) the Task
    Local $oFolder = _TS_FolderGet($oService, $sFolder)
    If @error Then Return SetError(3005, @error, 0)
    Local $oTask = $oFolder.RegisterTaskDefinition($sName, $oTaskDefinition, $TASK_CREATE, $sUserId, $sPassword, $iLogonType)
    If @error Then Return SetError(3006, @error, 0)
    Return $oTask
EndFunc   ;==>_TS_Wrapper_TaskRegister

Your welcome on the testing.  Thank you for writing this UDF.   

 

Adam

 

Edited by AdamUL

Share this post


Link to post
Share on other sites

Great idea :)
I have implemented the following changes:

  • Added the additional code as suggested to _TS_TaskRegister
  • _TS_Wrapper_TaskRegister is now an alias for _TS_TaskRegister as the wrapper has the same functionality and has only been added for completeness
  • _TS_TaskPropertiesGet has been modified so you get the property value as a string when you set $iFormat to 1 and $sQueryProperties to a single property. Else you get the full array.

Comments please ;)

Temp.au3


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Thanks Water.  Nice changes.  I like the non-array return for _TS_TaskPropertiesGet on a single property.  Just a heads up. In my testing of _TS_TaskPropertiesGet, numerical values, such as LogonType, return as a number type (Int32), not a string.  Values such as UserId return as String.  This is also the case for the returned array.  Maybe a comment in the documentation about the type as being returned by the COM object?  This most likely won't be an issues with the way AutoIt handles variants.  Testing snippet below.  

;~ Global $vTaskProperties = _TS_TaskPropertiesGet($oService, $sTask, 1, True)
;~ Global $vTaskProperties = _TS_TaskPropertiesGet($oService, $sTask, 1, True, "PRINCIPAL")
;~ Global $vTaskProperties = _TS_TaskPropertiesGet($oService, $sTask, 1, True, "PRINCIPAL", "LogonType")
Global $vTaskProperties = _TS_TaskPropertiesGet($oService, $sTask, 1, True, "PRINCIPAL", "UserId")
If @error Then
    MsgBox($MB_ICONERROR, "_TS_TaskPropertiesGet", "Returned @error=" & @error & ", @extended=" & @extended & @CRLF & @CRLF & _TS_ErrorText(@error))
Else
    If IsArray($vTaskProperties) Then 
        _ArrayColInsert($vTaskProperties, UBound($vTaskProperties, $UBOUND_COLUMNS))
        For $i = 0 To UBound($vTaskProperties, $UBOUND_ROWS) - 1
            $vTaskProperties[$i][UBound($vTaskProperties, $UBOUND_COLUMNS) - 1] = VarGetType($vTaskProperties[$i][2])
        Next
        _ArrayDisplay($vTaskProperties, "$vTaskProperties")
    Else
        MsgBox($MB_OK, "PRINCIPAL", $vTaskProperties & @CRLF & @CRLF &  "Type: " & VarGetType($vTaskProperties))
    EndIf 
EndIf

I was able to plug in the new _TS_TaskRegister, and it worked without issue in my testing scripts and the examples.  

Good work.  

 

Adam

Share this post


Link to post
Share on other sites

Thanks for the heads up :)

Have added a remark in the UDF.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2019-07-24 - Version 1.3.6.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-11-07 - Version 1.3.0.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...