Viewing entries tagged
csv

PowerShell: Working with CSV Files

PowerShell: Working with CSV Files

Why did I want to do this?

I wanted to learn how to manipulate CSV files for logging purposes as well as for part of a script I was writing to email out a different quest each day. 

In particular I wanted to see if today was completed, and if not, update it to say so and then add the next day with Completed = No.

The setup

This function is part of a larger script that I'll write a post about after covering more of the basics.

You'll need the following things to get it running:

A file named runlog.csv in the same folder with the following contents:

“DateTime”,”Day”,”Completed”
”1/18/2016”,”1”,”No”

Preferably you'll want the first DateTime to match the current date, and day to start at 1. The script should be able to catch a gap in the DateTime and continue on, however.

Now you'll need to setup the following variables:

$todayDate        = (Get-Date).ToShortDateString()
$tomorrowDate     = (Get-Date).AddDays(1).ToShortDateString()
$runLog           = Import-CSV .\runlog.csv
$logHeaders       = @{
    "DateTime"  = '' 
    "Day"       = ''
    "Completed" = '' 
}

How to call the function

You'll want to call the function like so:

if ($updateLog)   {Log-DayQuest $todayDate $tomorrowDate $logHeaders}

At the beginning of the script you'd want something like:

[cmdletbinding()]
Param(
    [boolean]
    $updateLog
)

The code (let's put it all together!)

[cmdletbinding()]
Param(
    [boolean]
    $updateLog
)

$todayDate        = (Get-Date).ToShortDateString()
$tomorrowDate     = (Get-Date).AddDays(1).ToShortDateString()
$runLog           = Import-CSV .\runlog.csv
$logHeaders       = @{
    "DateTime"  = '' 
    "Day"       = ''
    "Completed" = '' 
} 

function Log-DayQuest {
    [cmdletbinding()]
    param($todayDate,$tomorrowDate,$logHeaders)
    
    [int]$questDay   = ($runLog | Where-Object {$_.DateTime -eq $todayDate} | Select-Object Day).Day
    
        if (($runLog | Where-Object {$_.DateTime -eq $todayDate} | Select-Object Completed).Completed -eq "Yes") {
    
            Write-Host "Log already updated!"
 
        } Elseif ($runLog | Where-Object {$_.DateTime -eq $todayDate})  { 

            [int]$day = ($runLog | Where-Object {$_.DateTime -eq $todayDate} | Select-Object Day).Day
        
            #Log today as completed
            ($runLog | Where-Object {$_.DateTime -eq $todayDate}).Completed = "Yes"        

            $runLog | Export-CSV .\runlog.csv -NoTypeInformation
          
            #Log tomorrow as not completed
            
            $logHeaders.DateTime  = $tomorrowDate
            $logheaders.Day       = $day+1
            $logheaders.Completed = "No"

            $newrow = New-Object PSObject -Property $logHeaders
            Export-CSV .\runLog.csv -InputObject $newrow -append -Force
            
            Write-Host "Log updated!"
        
        } elseif($runLog | Where-Object {$_.DateTime -eq $todayDate} -eq $null) {
            
            Write-Host "No entry for today... creating entry and updating"
            [int]$day = ($runlog[$runlog.count-1]).day 
            $logHeaders.DateTime  = $todayDate
            $logheaders.Day       = $day+1
            $logheaders.Completed = "Yes"
            
            $newrow = New-Object PSObject -Property $logHeaders
            Export-CSV .\runLog.csv -InputObject $newrow -append -Force

        }
}

if ($updateLog)   {Log-DayQuest $todayDate $tomorrowDate $logHeaders}

The results

Here are the results of me testing the script.

More on how it works coming up!

Please let me know what you think or if you have a quicker way to accomplish the same thing.

One of the things I love about PowerShell are the different ways to accomplish the same thing. That's the best way to learn.