Wednesday, October 16, 2013

Everyday Powershell - Part 4 - Chore List

This is the next part in an ongoing series about Powershell. You may have heard about how awesome Powershell is but have struggled to find ways to make it useful in your day to day work. That's what this series is going to address. It'll provide scripts and knowledge to address practical everyday problems!

I found this in my travels a while back;
http://www.reddit.com/r/PowerShell/comments/1n8w5w/assigning_daily_family_chores/

It's not my script but I have made a couple of changes for the sake of compatibility. I've picked it out because it's a fantastic idea and a great opportunity to look at two important functions in powershell. import-csv and foreach.

Have a look at the script;

# requires -version 2
# Chores.ps1
# Parses chores.csv, randomly assigns the chores and sends an email to each person
# Retrieves family members from family.csv. First person listed in family.csv receives full summary email

$today = (get-date).DayOfWeek
$chores = import-csv chores.csv | where-object {$_.$today -eq 1| select Chore, Weight
$chores = $chores | get-random
-count ($chores.count) | sort-object -property Weight -Descending
$family = import-csv family.csv
$choremsg = @()
$smtpuser = "person@gmail.com"
$smtppassword = "notapassword"

write-host Generating chores list for $Today

# Create first column in $chorelist array to hold the names of who is doing the chore
foreach ($familymember in $family)
{
    $choremsg = $choremsg + ("`r`n" + $familymember.person + "'s Chores for the day:`r`n-------------------------------`r`n")
}

$choreworker = 2
foreach ($chore in $chores)
{
    $choremsg[$choreworker - 1] = $choremsg[$choreworker - 1] + $chore.chore + "`r`n"
    $choreworker++
    if ($choreworker -gt $family.count) { $choreworker = 1 }
}

$choremsg = $choremsg + ("`r`nPlus other duties as assigned `r`n")

$choremsg
$choremsgsubject = ("Chores for " + $today)

$smtpconn = new-object system.net.mail.smtpClient
$smtpconn.host = "smtp.gmail.com"
$smtpconn.port = 587
$smtpconn.EnableSsl = $true
$smtpconn.Credentials = new-object system.net.networkcredential($smtpuser,$smtppassword)
foreach ($familymember in $family)
{
    $smtpconn.send('person@gmail.com',$familymember.email,$choremsgsubject,$choremsg)
}

It's a cool bit of powershell that automates dishing out household chores to the family. You need to setup 2 CSV files for this to work.

Chores.csv Chore,Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Weight Feed dog,1,1,1,1,1,1,1,1 Feed cat,1,1,1,1,1,1,1,1 Clean Main Floor Bathroom,0,0,1,0,0,0,1,3 Family.csv Person, Email Dad,dad@gmail.com Mom,mom@gmail.com kid1,kid1@gmail.com kid2,kid2@gmail.com

Once you've got those CSV files we can use the import-csv function to pull them into powershell as objects that we can use!

Give it a try! Fill $family with the content of the CSV
$family = import-csv family.csv

Cool now just type;
$family

You'll see that your CSV is now a powershell object with properties corresponding to the column headers in your CSV.

Now try
$family.person

This'll just give you all the people. Now try
$family.email

This'll output just the emails.

The other thing to note with this script is the foreach command. Basically this is saying for each thing in a group of things do something. This kind of loop is used all the time in powershell and it's worth taking some time to get your head around.

This script is the essence of Everyday Powershell! Scripting with powershell shouldn't be intimidating, it's automation made awesome! The best way to learn is to just get stuck in and start solving problems and I can't think of much better problems to solve than eliminating arguments about who does what around the house!

So big thanks to Reddit user MessageforyouSir for this little gem. It's a been great excuse to play with and learn about import-csv! Oh and remember if you want to schedule a script check out Part 1 of this series.

Security Note - The security aware among you will note that the script requires that you hard-code a password in plain text. This is generally not considered good practice and wouldn't be necessary if you run you own SMTP server that allows relaying. There's probably a post or two just in managing and storing and using credentials in this way. You'll have to stay tuned for those.







1 comment: