Skip to content

write function names and parameters for debugging and tracing

2012/01/02

When scripts become more complex it helps if you have a functionality to do some kind of tracing. Using the Set-PSDebug -Trace 1 / 2 produces a large amount of output. What I need is a simple call to a trace-function that lists the function name . This way I can follow the program flow while developing. Additionally I added an option to list the parameters passed to the function. It is far away from perfect and has some flaws when complex data structures are passed but it is better than none.

The heart of  write-trace function is using the get-variable cmdlet with the scope parameter 1. This way you can grab the MyInvocation variable from the traced function. The myInvocation.myCommand lets you access thefunction name and the parameter list. All the default parameters are filtered out, so they do not fill the out put.

In the calling script you define the “debuglevel” . 1 means only function names , 2 means also parameters. With the variable $logToFile it can be defined where the output goes. If you want it to a file, do not forget to define the variable $logfile path. The example shows how I differenciate between logging in the “working directory” or the script directory :

$logToFile  = $false
$debugLevel = 2

$defaultParametersIgnored = "Verbose", "Debug", "ErrorAction", "WarningAction" , "ErrorVariable" , "WarningVariable", "OutVariable" , "OutBuffer"

if($logPathSwitch -eq "wd") {
    $logfilePath = $pwd.path
} else {
    $p = $myInvocation.mycommand.path.lastindexof('\')
    if($p -gt 2) {
        $logFilePath = $myInvocation.mycommand.path.substring(0,$p)
    } else {
        $logFilePath = "."
    }
}

$logDate = (get-date)
$logFilePath += '\'+ $myInvocation.mycommand.name.substring(0,$myInvocation.mycommand.name.lastindexof('.')) + `
                "-{0}-{1:D2}-{2:D2}.log" -f $logDate.year, $logDate.month, $logDate.day

function write-trace{

    $upCmd = (get-variable -sc 1 "myInvocation").value

    $outText = "`r`ndbgTrace: ---------------------------------`r`ncalling function name " + $upCmd.MyCommand.name + "`r`n"

    if($debugLevel -gt 1 ) {
        $upCmd.mycommand.Parameters.keys | ?{$defaultParametersIgnored  -notcontains $_ } | %{
            $s= get-variable  -scope 1 $_
            $val = $s.value | ft * | out-string -Width 2000
            $outtext += "Name: {0} Val: {1} `r`n" -f $_, $val
        }        
    }
    $outText += "`r`ndbgTrace: ---------------------------------`r`n" 

    if($logToFile -eq $true) {
        $outText | out-file $LogFilePath -append
    } else {
        $outtext | out-host
    }
}    

function f2dbg {
    param ( $parameter1 = "parameter one default value",
            $parameter2 = "parameter TWO default value")

    if($debuglevel -gt 0) {    write-trace  }

}

function f2debug_withoutParam {

    if($debuglevel -gt 0) {    write-trace }

    "this function has no parameters"

    $x = "this is the parameters content"

    f2dbg $x

}

f2debug_withoutParam

f2dbg -parameter1 "direct text" -parameter2 (get-date)

f2dbg -parameter1 "direct text","array","3 values" -parameter2 (get-process)
Advertisements

From → basics, powershell

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: