<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PowerShell Station &#187; Scheduled Tasks</title>
	<atom:link href="http://powershellstation.com/category/scheduled-tasks/feed/" rel="self" type="application/rss+xml" />
	<link>http://powershellstation.com</link>
	<description>Mike&#039;s PowerShell Musings</description>
	<lastBuildDate>Thu, 05 Apr 2012 03:05:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Verifying Automation</title>
		<link>http://powershellstation.com/2011/01/06/verifying-automation/</link>
		<comments>http://powershellstation.com/2011/01/06/verifying-automation/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 00:59:16 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scheduled Tasks]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=317</guid>
		<description><![CDATA[If you&#8217;re anything like me, you&#8217;ve been bitten by the PowerShell bug and are using it among other automation sources to make you life in IT much more enjoyable. If this is not the case&#8230;you need to get started!&#160; There&#8217;s no time like the present, and a PowerShell New Year&#8217;s resolution should be something to [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re anything like me, you&#8217;ve been bitten by the PowerShell bug and are using it among other automation sources to make you life in IT much more enjoyable.  If this is not the case&#8230;you need to get started!&nbsp; There&#8217;s no time like the present, and a PowerShell New Year&#8217;s resolution should be something to consider.</p>
<p>For those of you that are with me in the PowerShell camp, I have something that I&#8217;d like to discuss.&nbsp; You probably have hundreds (dozens?) of scripts scheduled on multiple servers, possibly in multiple domains or geographical locations to perform things like these:</p>
<ul>
<li>Gather information about servers</li>
<li>Generate reports about application usage</li>
<li>Copy information from one place to another</li>
<li>Validate security setup</li>
<li>Start and Stop processes</li>
<li>Scan log files for error conditions</li>
<li>Lots of other things (you get the point)</li>
</ul>
<p>How do you know that the scripts that you have written carefully and scheduled are actually running successfully?&nbsp; At first, this seems like a silly question.&nbsp; When you deployed the script, surely you ran it once to make sure it worked.&nbsp; What could have gone wrong?</p>
<p>Here are some examples that come to mind:</p>
<ul>
<li>A policy was pushed which set the execution policy to Restricted</li>
<li>The credentials you scheduled the script with have been revoked</li>
<li>A file share that the scripts depend on is unavailable</li>
<li>Firewall rules change and now WMI queries aren&#8217;t working</li>
<li>The Task Scheduler service is stopped</li>
</ul>
<p>You can probably think of a lot more examples of things that would keep scripts from working, but you get the idea.&nbsp; I&#8217;ve given some thought to how to do this, but haven&#8217;t come to any real conclusions.&nbsp; Obviously, having your scripts log results is helpful, but only if you monitor the logs for success/failure.&nbsp; Also, if you have a script which is supposed to run every 10 minutes, it doesn&#8217;t help if you don&#8217;t get alerted when it only runs once in a day, even if&nbsp; it runs successfully.&nbsp; Also, if there is more than one person writing scripts, how do you make sure that everyone is using the same techniques to log progress?</p>
<p>Here are some of my thoughts:</p>
<ul>
<li>Use a &#8220;launcher&#8221; to run scripts (see below)</li>
<li>Keep a database of processes with an expected # of runs per day</li>
<li>Monitor matching start/end of scripts</li>
<li>Log all output streams (<a title="example" href="http://www.nivot.org/2009/08/19/PowerShell20AConfigurableAndFlexibleScriptLoggerModule.aspx">example</a>)</li>
</ul>
<p>The first item in the list (the launcher) has been something I&#8217;ve been considering because it&#8217;s not trivial to run a PowerShell script in a scheduled task.&nbsp; Even with the -file parameter which was added in PowerShell 2.0, it can involve a fairly long command-line.&nbsp; With the added difficulty of trying to capture output streams (most of which are not exposed to the command shell) it becomes a process that is almost hard to get right every time.&nbsp; Some features I&#8217;m planning for the launcher are:</p>
<ul>
<li>Load appropriate profiles</li>
<li>Log all output streams (with timestamps) to file or database</li>
<li>Log application start/end times</li>
<li>Email owner of script if there are unhandled exceptions</li>
</ul>
<p>I know this topic is not specific to PowerShell, but as Windows administrators get more used to scripting solutions to their automation problems with PowerShell (which I am confident that they are doing), it&#8217;s something that every organization will need to consider.&nbsp; I&#8217;ll try to follow up with some posts that have some actual code to address some of these points.</p>
<p>Mike</p>
<p>P.S.  I&#8217;m specifically not discussing &#8220;enterprise job scheduling&#8221; solutions like JAMS because of the high cost involved.  I&#8217;d like to see the community come up with something a little more budget-friendly.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpowershellstation.com%2F2011%2F01%2F06%2Fverifying-automation%2F&amp;title=Verifying%20Automation" id="wpa2a_2"><img src="http://powershellstation.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2011/01/06/verifying-automation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell ETS (Extended Type System)</title>
		<link>http://powershellstation.com/2009/09/15/powershell-ets-extended-type-system/</link>
		<comments>http://powershellstation.com/2009/09/15/powershell-ets-extended-type-system/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 02:12:28 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scheduled Tasks]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[add-member]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Script]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=63</guid>
		<description><![CDATA[In a recent post , I showed how to get a list of Scheduled Tasks as objects using PowerShell and Import-CSV.   In that, I included the following line of code:

$task.PSObject.TypeNames.Insert(0,"DBA_ScheduledTask")

In this post, I'll try to explain why I did that.]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://powershellstation.com/2009/09/10/getting-scheduled-tasks-in-powershell/">recent post</a> , I showed how to get a list of Scheduled Tasks as objects using PowerShell and Import-CSV.   In that, I included the following line of code:</p>
<pre class="brush: powershell; gutter: false">$task.PSObject.TypeNames.Insert(0,"DBA_ScheduledTask")</pre>
<p>In this post, I&#8217;ll try to explain why I did that.</p>
<p>There are several approaches to making objects in PowerShell.</p>
<ul>
<li>Use new-object to create an object from an existing <em>class</em> (.NET, COM, ADSI, WMI)</li>
<li>Use add-member to add properties and methods to an existing <em>object</em></li>
<li>Use ETS (the Extended Type System) to add properties and methods to an existing <em>class</em></li>
</ul>
<p>Obviously, the first approach (new-object)  makes sense if there is an existing class that you know fits the purposes you have in mind.  It helps if there&#8217;s a constructor that takes arguments that you have lying around, too.  For example:</p>
<pre class="brush: powershell; gutter: false"> $conn=new-object data.sqlclient.sqlconnection "Server=laptopsqlexpress;Integrated Security=True"</pre>
<p>But often, you&#8217;re working with a domain-specific object that doesn&#8217;t exist in the .NET framework or anything else.</p>
<p>The second approach (using add-member) is useful, for example,  if you need to create a record from a collection of properties.  You can also add methods using add-member.   One thing that you&#8217;ll run into with using add-member is that you have to remember to add the same members (the same set of properties and methods) to each similar object that you&#8217;re dealing with.  This is a lot different than when you create a class definition and instantiate objects from the class.</p>
<p>The third approach is similar to the second, in that you specify properties and methods to add, but in this case, you specify them in a configuration file ( *.ps1xml) that is added with the update-typedata cmdlet.   In this file, you name the class that you want to extend, and list the property and method definitions that you want to add.  After the update-typedata cmdlet is issued, all objects of the type listed will have the new properties and methods.</p>
<p>One especially nice feature of the third approach is that the name of the class you want to extend does not have to be the actual name of the type of the objects.  What it really does is match the values in the object&#8217;s PSObject.TypeNames property.  For most objects, this property is a list of the inheritance chain for the object, going back to System.Object.  However, as in the above example, you are free to add (or remove) items from this list.  Above, I added &#8220;DBA_ScheduledTask&#8221; to the list.  That means that if I have a .ps1xml configuration file that has ETS info in it for the type &#8220;DBA_ScheduledTask&#8221;, that set of properties and methods would be available from the objects I create.</p>
<p>I often use functions that return data out of a database.  PowerShell is nice enough that it acts like DataRows are objects, using column names for properties.  This makes it very easy to use the data in PowerShell without doing much to it.  By adding a specific &#8220;type name&#8221; to the TypeNames collection, I can instantly make the DataRow records into full-fledged objects (by including an appropriate update-typdata command in my profile).  In the post about Scheduled Tasks, it would make sense to use ETS to specify the Run and Delete methods.  Here&#8217;s what that would look like:</p>
<pre  class="brush: xml">&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;Types&gt;
 &lt;Type&gt;
 &lt;Name&gt;DBA_ScheduledTask&lt;/Name&gt;
 &lt;Members&gt;
 &lt;ScriptMethod&gt;
 &lt;Name&gt;Run&lt;/Name&gt;
 &lt;Script&gt;
 schtasks.exe /RUN /TN $this.TaskName /S $this.HostName
 &lt;/Script&gt;
 &lt;/ScriptMethod&gt;
 &lt;ScriptMethod&gt;
 &lt;Name&gt;Delete&lt;/Name&gt;
 &lt;Script&gt;
 schtasks.exe /DELETE /TN $this.TaskName /S $this.HostName
 &lt;/Script&gt;
 &lt;/ScriptMethod&gt;
 &lt;/Members&gt;
 &lt;/Type&gt;
&lt;/Types&gt;</pre>
<p>With this in a file (for instance c:typesscheduledTasks_type.ps1xml), you would issue the command &#8220;update-typedata c:typesscheduledTasks_type.ps1xml&#8221;, and the Run and Delete methods would be added to items of that type.  Of course, you&#8217;d want to modify the code in the previous post to not add those methods with add-member.</p>
<p>I tend to use a mix of add-member and ETS to create the objects I want.  You have to be careful when using ETS to remember that if you want the extra properties, you have to have loaded the ps1xml file in the session you&#8217;re running.  This often isn&#8217;t the case if you&#8217;re remoted into a server troubleshooting something.  For that reason, it&#8217;s usually preferrable (in my opinion) to use add-member most of the time.  I use a custom PowerShell host that allows me to use ETS data to specify context menus for different types of objects and customize them through the ps1xml files.  Since I don&#8217;t expect to find those context menus when I&#8217;m in the text console on a server, it doesn&#8217;t get me into trouble.</p>
<p>Let me know if you have any questions, comments, or complaints.</p>
<p>Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/09/15/powershell-ets-extended-type-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Scheduled Tasks in PowerShell</title>
		<link>http://powershellstation.com/2009/09/10/getting-scheduled-tasks-in-powershell/</link>
		<comments>http://powershellstation.com/2009/09/10/getting-scheduled-tasks-in-powershell/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 05:12:26 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Scheduled Tasks]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[ETS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Script]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=6</guid>
		<description><![CDATA[There are a few approaches to manipulating scheduled tasks in PowerShell.

    * WMI - Useful if you are only going to manipulate them via script.  The tasks will not be visible in the control panel applet.
    * SCHTASKS.EXE - Works ok, but has a somewhat arcane syntax, and is a text-only tool.
    * Task Scheduler API -Best of both worlds, but only on Vista (not XP).]]></description>
			<content:encoded><![CDATA[<p>There are a few approaches to manipulating scheduled tasks in PowerShell.</p>
<ul>
<li>WMI &#8211; Useful if you are only going to manipulate them via script.  The tasks will not be visible in the control panel applet.</li>
<li>SCHTASKS.EXE &#8211; Works ok, but has a somewhat arcane syntax, and is a text-only tool.</li>
<li>Task Scheduler API -Best of both worlds, but only on Vista (not XP).</li>
</ul>
<p>My current environment is an XP laptop, and hundreds of W2k3 and W2k8 servers.  I really need to be able to hit the tasks from the control panel (don&#8217;t have PowerShell installed everywhere&#8230;but that&#8217;s in process).  Since I have to use SCHTASKS.EXE , I figured I should write a PowerShell interface that makes things a bit easier.</p>
<p>The main thing I wanted was to get objects back.  Once you&#8217;ve started using PowerShell, you realize that &#8220;everything returns objects&#8221; makes for a very powerful scripting experience.  So, when you have to fall back to an external command like SCHTASKS.EXE, you really feel the pain.  The approach I took was to ask SCHTASKS for a verbose output (no reason not to get all of the properties), and also to write the output as CSV.  I then send the output into a file.  A problem that arises when trying to get PowerShell to import the CSV is that the column headers are not very friendly (e.g. &#8220;Repeat: Until: Time&#8221;).  So, before importing we need to &#8220;massage&#8221; a little bit.  I simply removed spaces (leaving Pascal-cased words) and replaced colons with underscores.  Another issue was that different versions of SCHTASKS.EXE would sometimes include an extra blank line in the file.  Finally, I decided that I should add some methods using <strong><span style="font-family: Verdana,sans-serif;">Add-Member</span></strong><span style="font-family: inherit;"> to allow me to run or delete the task without having to remember the syntax. </span></p>
<p>I hope you find this script useful.  If you have suggestions for improvements, or questions about how part of it works, feel free to leave a comment.</p>
<pre class="brush: powershell">function get-tasks($server="", $taskname="",[switch]$help){
  if ($help)
    {
        $msg = @"
Get scheduled tasks from a remote server as objects.  Optionally you may supply a substring to be found in the task names.

Usage: get-tasks [Server] [substring] [-help]
ex:  get-tasks MACHINE1 LOGS    #to get all scheduled tasks from MACHINE1 containing LOGS
"@
        Write-Host $msg
        return
    }
    $filename = [System.IO.Path]::GetTempFileName()
 if ($server){
     schtasks /query /fo csv /s $server /v &amp;gt; $filename
 } else {
    schtasks /query /fo csv /v &amp;gt; $filename
 }
    $lines=Get-Content $filename
 if ($lines -is [string]){
    return $null
 } else {
        if ($lines[0] -ne ''){
   Set-Content -path $filename -Value ([string]$lines[0]).Replace(" ","").Replace(":","_")
   $start=1

  } else {
   Set-Content -path $filename -Value ([string]$lines[1]).Replace(" ","").Replace(":","_")
   $start=2
  }
  if ($lines.Count -ge $start){
   Add-content  -Path $filename -Value $lines[$start..(($lines.count)-1)]
  }
  $tasks=Import-Csv $filename
  Remove-Item $filename
  $retval=@()
  foreach ($task in $tasks){
   if (($taskname -eq '') -or $task.TaskName.contains($taskname)){
    $task.PSObject.TypeNames.Insert(0,"DBA_ScheduledTask")
    Add-Member -InputObject $task -membertype scriptmethod -Name Run -Value { schtasks.exe /RUN /TN $this.TaskName /S $this.HostName}
    Add-Member -InputObject $task -membertype scriptmethod -Name Delete -Value { schtasks.exe /DELETE /TN $this.TaskName /S $this.HostName}
    $retval += $task
   }
  }
  return $retval
 }
}</pre>
<p>Links:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/aa394399%28VS.85%29.aspx">WMI for scheduled tasks (MSDN)</a></li>
<li><a href="http://myitforum.com/cs2/blogs/yli628/archive/2008/07/28/powershell-script-to-retrieve-scheduled-tasks-on-a-remote-machine-task-scheduler-api.aspx">Using the Task Scheduler API (in Vista)</a></li>
<li><a href="http://www.peetersonline.nl/index.php/powershell/managing-scheduled-tasks-remotely-using-powershell/">Another take on scripting SCHTASKS.EXE</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/09/10/getting-scheduled-tasks-in-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  powershellstation.com/category/scheduled-tasks/feed/ ) in 0.20679 seconds, on May 20th, 2012 at 1:20 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on May 21st, 2012 at 1:20 am UTC -->
