{"id":2424,"date":"2013-12-14T00:01:00","date_gmt":"2013-12-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/12\/14\/working-with-task-scheduler-xml\/"},"modified":"2013-12-14T00:01:00","modified_gmt":"2013-12-14T00:01:00","slug":"working-with-task-scheduler-xml","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/working-with-task-scheduler-xml\/","title":{"rendered":"Working with Task Scheduler XML"},"content":{"rendered":"<p><strong>Summary<\/strong>: Guest blogger, Jason Morgan, talks about using XML to work with the Task Scheduler.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Today I am proud to introduce Jason Morgan as the newest guest blogger for the Hey, Scripting Guy! Blog. I ran across Jason at the first meeting of the Northern Virginia (NOVA) PowerShell User Group meeting. The Scripting Wife and I were hanging out, and I asked him if he would like to contribute. Today&rsquo;s excellent post is the result of that collaboration. First, a little bit about Jason&hellip;<\/p>\n<p style=\"padding-left: 30px\"><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0045.wes-12-14-13-1.jpg\"><img decoding=\"async\" title=\"Photo of Jason Morgan\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0045.wes-12-14-13-1.jpg\" alt=\"Photo of Jason Morgan\" \/><\/a><\/p>\n<p style=\"padding-left: 30px\">Jason Morgan has been working in IT since 2004.&nbsp;He is an engineer for Verizon Enterprise Services and he works in their Integrated Solutions organization, providing fully managed infrastructure and application support services for hosted and customer premise solutions. He is a founding member of the NOVA PowerShell User Group.<\/p>\n<p style=\"padding-left: 30px\">Blog: <a href=\"\/Users\/v-diree\/Documents\/a-ScriptingGuy\/Dec2013\/14\/JasonsPowerShellBlog.wordpress.com\" target=\"_blank\">Jason&#8217;s PowerShell Blog<\/a><br \/> Twitter: @RJasonMorgan<\/p>\n<p>Thank you for the opportunity to contribute to the Hey, Scripting Guy! Blog. I&rsquo;m here today to talk about working with XML, specifically working with XML as it relates to the Task Scheduler. I&rsquo;ve found at my job that I often need to create the same tasks on multiple computers. Unfortunately, the raw functionality that comes with schtasks.exe is a little limited. For example, you can create a 2003- or 2008-level task, but you can&rsquo;t create a 2008&nbsp;R2 task, which in the XML, is v1.2. Luckily, <strong>schtasks<\/strong> and the Task Scheduler COM objects are able to create tasks directly from XML.<\/p>\n<p>Ultimately, using XML is an easy and flexible way to create tasks and deploy them throughout your environment. It gives you extremely granular control of a task. After you try it, you&rsquo;ll find it&rsquo;s nearly as easy as using the GUI&mdash;and it&rsquo;s a heck of a lot faster.<\/p>\n<p>For those of you who aren&rsquo;t familiar with working with XML in Windows PowerShell, there are a ton of great articles and blogs that cover the subject. In this post, I&rsquo;m going to largely skip the fundamentals and get right in to how to work with XML for scheduled tasks. For background information, I recommend the following posts:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.codeproject.com\/Articles\/61900\/PowerShell-and-XML\" target=\"_blank\">PowerShell and XML<\/a><\/li>\n<li><a href=\"http:\/\/powershell.com\/cs\/blogs\/tobias\/archive\/2009\/02\/02\/xml-part-2-write-add-and-change-xml-data.aspx\" target=\"_blank\">XML Part 2: Write, Add And Change XML Data<\/a><\/li>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/02\/17\/use-powershell-to-simplify-working-with-xml-data.aspx\" target=\"_blank\">Use PowerShell to Simplify Working with XML Data<\/a><\/li>\n<\/ul>\n<p>The first thing you need to do is import a task:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[xml]$Task = get-content .\\example.xml<\/p>\n<p>Then you can begin investigating or overwriting settings. Today we&rsquo;re going to set up a task to run a Windows PowerShell script that&rsquo;s starts on January 1 and runs every 4 hours for a week. Just for fun, we&rsquo;ll also set it to run when a certain user logs on.<\/p>\n<p>Whenever I work with a new XML object, I like to start by piping the XML document to the <strong>Format-Custom<\/strong> cmdlet. It&rsquo;s great way to view any XML object in detail, and it can be a lot easier than trying to go through it manually. Avoid <strong>Format-List<\/strong> if you don&rsquo;t want to see big blocks of the raw XML.<\/p>\n<p style=\"padding-left: 30px\">$task | format-custom<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8468.wes-12-14-13-2.jpg\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8468.wes-12-14-13-2.jpg\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Hopefully after looking at the output, you should have a pretty good idea of all the options you have for modifying the task. Here&rsquo;s a quick tip: The date format that is supported by the Task Scheduler XML schema is produced as follows:<\/p>\n<p style=\"padding-left: 30px\">&nbsp;get-date &ndash;format s<\/p>\n<p>It outputs something like this:<\/p>\n<p style=\"padding-left: 30px\">2013-11-07T20:23:14<\/p>\n<p>Overwriting XML elements is really easy. They accept strings, so all you need to do is:<\/p>\n<p style=\"padding-left: 30px\">$xml.element.property = &ldquo;MyNewValue&rdquo;<\/p>\n<p>For scheduled tasks, you browse or tab your way to the property you&rsquo;re looking for, and overwrite it.<\/p>\n<p>You can (and should) use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa383609(v=vs.85).aspx\" target=\"_blank\">Task Scheduler Schema information<\/a> from MSDN if you run into issues when you are overwriting elements.<\/p>\n<p>Time intervals are specified by using the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa382993(v=vs.85).aspx\" target=\"_blank\">Interval (repetitionType) Element<\/a>. The format is:<\/p>\n<p style=\"padding-left: 30px\">P&lt;days&gt;DT&lt;hours&gt;H&lt;minutes&gt;M&lt;seconds&gt;S<\/p>\n<p>In our case, 4 hours will be <strong>PT4H<\/strong>.<\/p>\n<p>Before you can start modifying the XML, you&rsquo;ll need a good template to work with. I usually start with a simple Task document and add to it as needed. The following posts have good information about adding nodes to XML documents:<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/07\/29\/how-to-add-data-to-an-xml-file-using-windows-powershell.aspx\" target=\"_blank\">How to Add Data to an XML File Using Windows PowerShell<\/a><\/li>\n<li><a href=\"http:\/\/powershell.com\/cs\/blogs\/tobias\/archive\/2009\/02\/02\/xml-part-2-write-add-and-change-xml-data.aspx\" target=\"_blank\">XML Part 2: Write, Add And Change XML Data<\/a>.<\/li>\n<\/ul>\n<p>I&rsquo;ve added <strong>TimeTrigger<\/strong> and <strong>LogonTrigger<\/strong> nodes under <strong>$task.task.triggers<\/strong>.<\/p>\n<p>Now I&rsquo;m going to overwrite the settings to meet my needs. I&rsquo;m staging the task to run when my friend Nick logs on:<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Triggers.LogonTrigger.UserId = &#8220;Contoso\\Nick&#8221;<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5773.wes-12-14-13-3.jpg\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5773.wes-12-14-13-3.jpg\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>In addition to that, I want it to run a little after New Year&rsquo;s Day 2014.<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Triggers.TimeTrigger.StartBoundary = &#8220;$(Get-Date &#8220;01\/1\/2014 00:01:00&#8243; -Format s)&#8221;<\/p>\n<p>I need to use the subexpression, <strong>$()<\/strong>, and the quotation marks because the XML can only accept string values. &nbsp;After that, I set the repetition interval and duration:<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Triggers.TimeTrigger.Repetition.Interval = &#8220;PT4H&#8221;<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Triggers.TimeTrigger.Repetition.Duration = &#8220;P7D&#8221;<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong>&nbsp;&nbsp;Earlier I mentioned the time format that the Task Scheduler accepts. If you have questions, please refer to the post I linked to there.<\/p>\n<p>We&rsquo;ve set the triggers the way we want them. So now we want to set the actions for our task and import our updated XML document. To overwrite the task actions, we simply navigate to the actions node and update the command and arguments:<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Actions.Exec.Command = &#8220;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe&#8221;<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Actions.Exec.Arguments = &#8220;-file c:\\scripts\\SendHappyNewYear.ps1&#8221;<\/p>\n<p>I wrote a fun little script that plays a happy New Year&rsquo;s greeting for my friend. I&rsquo;d like to keep my friend from discovering this task before it goes off, so I&rsquo;ll hide it:<\/p>\n<p style=\"padding-left: 30px\">$task.Task.Settings.Hidden = &#8220;true&#8221;<\/p>\n<p>With the actions in place and the settings modified, the only thing left to do is load it into the Task Scheduler. For Schtasks.exe, we need to point to an XML file. So need to save our modified task as an .xml file. You can commit your changes by saving the XML object&mdash;you can overwrite the existing document or make a new one.<\/p>\n<p style=\"padding-left: 30px\">$task.Save(&#8216;C:\\NewTask.xml&#8217;)<\/p>\n<p>Now run schtasks:<\/p>\n<p style=\"padding-left: 30px\">schtasks.exe \/create \/tn HappyNewYear \/XML C:\\NewTask.xml<\/p>\n<p>That&rsquo;s all there is to it!<\/p>\n<p>When you are comfortable deploying a single task, it&rsquo;s a quick step to deploying more complicated tasks across your environment. The Schtasks utility works well with PSRemoting and with the <strong>Invoke<\/strong> command, you can get a new task out to hundreds of servers in a couple minutes.<\/p>\n<p>Thanks for reading!<\/p>\n<p>~Jason<\/p>\n<p>Thank you Jason, for sharing your time and knowledge in this blog post, and also for leading the user group in NOVA.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest blogger, Jason Morgan, talks about using XML to work with the Task Scheduler. Microsoft Scripting Guy, Ed Wilson, is here. Today I am proud to introduce Jason Morgan as the newest guest blogger for the Hey, Scripting Guy! Blog. I ran across Jason at the first meeting of the Northern Virginia (NOVA) PowerShell [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,474,3,61,45],"class_list":["post-2424","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-jason-morgan","tag-scripting-guy","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Guest blogger, Jason Morgan, talks about using XML to work with the Task Scheduler. Microsoft Scripting Guy, Ed Wilson, is here. Today I am proud to introduce Jason Morgan as the newest guest blogger for the Hey, Scripting Guy! Blog. I ran across Jason at the first meeting of the Northern Virginia (NOVA) PowerShell [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2424","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2424"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2424\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2424"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2424"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2424"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}