Lessons In MSBuild - Introduction

   Submit to Reddit      
  

The Microsoft build engine (MSBuild) is not necessarily the easiest to learn, and documentation and examples can be difficult to find.

There is however an excellent book written by Sayed Ibrahim Hashimi and William Bartholomew titled "Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build" (Microsoft Press, 2009, ISBN-13: 978-0-7356-2628-7). I very strongly recommend purchasing this book if you are serious about learning MSBuild.

In this series of lessons I will be discussing a few MSBuild related tips that I found useful to understand during my recent dabbling in MSBuild 3.5 projects.

Lessons in PowerShell - Looping Through File Folders

   Submit to Reddit      
  

One way in PowerShell to get a collection of file folders is by using the .NET System.IO.Directory.GetDirectories function. Time is short, and I am familiar with that, so I will use the .NET library in this example script.

Here is one way in which it can be done.

$folders=[System.IO.Directory]::GetDirectories("c:\xxxx")

foreach ($folderName in $folders)
{                
    ...
}

If we wanted to, within the loop we could instantiate a System.IO.DirectoryInfo object to give us more information about the folder.

$folder = New-Object System.IO.DirectoryInfo($folderName)

And then we can access the properties on that class, like the folder's LastWriteTime in order to find out how old it is.

Here is a complete script.

$now = Get-Date
$yesterday = $now.AddDays(-1)
$folders=[System.IO.Directory]::GetDirectories("c:\program files")                    

foreach ($folderName in $folders)                    
{
    $folder = New-Object System.IO.DirectoryInfo($folderName)

    if ($folder.LastWriteTime -lt $yesterday)                    
    {                     
        Write-Host("Folder " + $folderName + " is at least a day old")                    
    }
    else
    {
        Write-Host("Folder " + $folderName + " is less than a day old")
    }                    
}

Lessons In PowerShell - Logging From A Script Running Via Windows Task Scheduler

   Submit to Reddit      
  

Logging and tracing information can normally be written to the host console, standard output or standard error streams. However, when a PowerShell script is run from the Windows Task Scheduler, those mechanisms are typically not available.

To work around this situation, I decided to create a log file for my PowerShell Script which is executed from Windows Task Scheduler.

For a start, we can use the .NET StreamWriter class to create a file stream.

$logFile = New-Object System.IO.StreamWriter("C:\temp\Script.log")

Please note: you must ensure that the user account the script runs under needs to have file system security access to that specific folder and file.

We can then create a function that will write a message to the log file and also flush the stream (I wanted to closely monitor the progress of the script while it may be running, so I am explicitly flushing the stream).

Function LogMessage($message)
{
    $logFile.WriteLine($message)

    $logFile.Flush()
}

And using the mimicked PowerShell Version 1 Try / Catch / Finally script block, we can ensure that even if an error occurs, the stream will be closed. See the bottom line below.

Here is the script in its entirety.

# Trap settings
$ReportErrorShowExceptionClass=$true
$ReportErrorShowInnerException=$true
$ReportErrorShowSource=$true
$ReportErrorShowStackTrace=$true

# Setup log file functionality
$now=Get-Date
$logFile = New-Object System.IO.StreamWriter("C:\temp\Script.log")

Function LogMessage($message)
{
    $logFile.WriteLine($message)
    $logFile.Flush()
}

&{
    &{ #Try 
          LogMessage("Started at " + $now)
          ...
          LogMessage("Successfully finished")
    } 
    trap #Catch
    {
        LogMessage("TRAPPED: " + $_.Exception.GetType().FullName) 
        LogMessage("TRAPPED: " + $_.Exception.Message)
        continue # So that the "Finally" gets executed
    }
} #Finally
$logFile.Close()

There we have it... a PowerShell script that runs under Windows Task Scheduler and writes out to a log file.

Of course, using the PowerShell Version 2 Try/Catch statement is much nicer than this PowerShell Version 1 equivalent.

Lessons In PowerShell - Calling A Static / Shared Method

   Submit to Reddit      
  

In order to call a static / shared .NET method from PowerShell, use the following format.

Format:

[type]::StaticMethodName

Example:

[DateTime]::Now

Note: In this specific example, the PowerShell alias Get-Date could be used instead of [DateTime]::Now � this is just an example!