Productivity with Powershell: Grab your agenda from outlook as plain text

I use a plain text file to manage my daily todo items. (Gina Trapani championed this idea with the "todo.txt" movement) and I use some little bits of console goodness to make it work my way.

I like to jam with the console cowboys in cyberspace.

At the start of each day I run a powershell script, "today" that does a bunch of calculations, opens up my todo.txt file in notepad++, and puts a bunch of text into my clipboard as a starting point. Then I paste that list at the bottom of the document. I also scroll up to yesterday's list and run a notepad++ macro that "sweeps" any remaining tasks from yesterday into today's list. Then I get to work.

But there is this big problem inside companies called "meetings" and they tend to get in the way of this thing called "personal productivity". I work remotely and don't have a lot of meetings, so I don't have the habit of checking my calendar, or living in my calendar, as some people do. Hence I have a bad habit of missing meetings. Bosses don't like this habit.

To alleviate the problem, I've improved my "today" script so that it will grab today's meeting schedule from outlook. I've shared the script I wrote for this as a github "gist", here:

Get today's schedule from Outlook, using COM, and format as text for my TODO.txt file

It's not very "elegant" as it is an example of "meware" -- code built for an audience of one.

Heck I'll just post it inline, here's my ugly baby:

# Get a list of meetings occurring today.
function get-meetings() {
	$olFolderCalendar = 9
	$ol = New-Object -ComObject Outlook.Application
	$ns = $ol.GetNamespace('MAPI')
	$Start = (Get-Date).ToShortDateString()
	$End = (Get-Date).ToShortDateString()
	$Filter = "[MessageClass]='IPM.Appointment' AND [Start] > '$Start' AND [End] < '$End'"
	$appointments = $ns.GetDefaultFolder($olFolderCalendar).Items
	$appointments.IncludeRecurrences = $true
	$appointments.Restrict($Filter) |  
	% {
		if ($_.IsRecurring -ne $true) {
			# send the meeting down the pipeline
		} else {
			#"RECURRING... see if it occurs today?"
			try {
				# This will throw an exception if it's not on today. (Note how we combine today's *date* with the start *time* of the meeting)
				$_.GetRecurrencePattern().GetOccurrence( ((Get-Date).ToString("yyyy-MM-dd") + " " + $_.Start.ToString("HH:mm")) )
				# but if it is on today, it will send today's occurrence down the pipeline.
				#"Not today"
	} | sort -property Start | % { 
		# split up the names of the attendees to have just 1 firstname/surname and less space.
		$arrr = ($_.RequiredAttendees.split(';') | % { $_.Trim() } | % { $_.split(' ')[1] + ' ' + $_.split(' ')[0] } )
		$attendees = ($arrr -join " ").Replace(", ",",").TrimEnd(',')
		# this is the formatted string that we return, ready for use in 'today'
		("`n`t`t[ ] " + $_.Start.ToString("HH:mm") + " - " + $_.Subject.ToUpper() + " with: " + $attendees )  

The resulting text looks like this:

		[ ] 09:00 - STANDUP with: Keena Maloney,Rhea Zamora,Ed Jackson
		[ ] 10:00 - DESIGN REVIEW with: Steph Perkins,Rhea Zamora
		[ ] 14:30 - CUSTOMER COMPLAINTS with: Della Bouchard,Steph Perkins

The way recurring meetings work was the tricky bit. I couldn't find any simple way to query a recurring appointment to ask it "Does it actually occur today?"

As always, I'm very open to any feedback or improvements!


My book "Choose Your First Product" is available now.

It gives you 4 easy steps to find and validate a humble product idea.

Learn more.

(By the way, I read every comment and often respond.)

Your comment, please?

Your Name
Your Url (optional)
Note: I may edit, reuse or delete your comment. Don't be mean.