0

I would like to implement a function to output some debugging information. I want the function, namely "Write-Foo", to work in the following way:

Write-Foo $SomeThing
# the output will be "SomeThing: (the value of Something)"

Is it possible to implement this function? I don't know how to get the name of the parameter of the function.

Thanks

5 Answers 5

2

This is close to what you want:

function Write-Foo($varName)
{
    $varVal = $ExecutionContext.InvokeCommand.ExpandString("`$variable:$varName")
    Write-Host "$($varName): $varVal"
}

Trying it out:

PS> $SomeThing = 'hello'
PS> Write-Foo SomeThing
SomeThing: hello
Sign up to request clarification or add additional context in comments.

Comments

2

Another take:

function Write-Foo($varName)
{
    $v = Get-Variable $varName
    Write-Host ($v.Name + ": " + $v.Value)
}

Result:

PS C:\> $Something = "nothing"            
PS C:\> Write-Foo SomeThing               
Something: nothing

Comments

1

Another possibility (this assumes what you want to display is the name of the variable that was passed as an argument, not the name of the parameter it was passed to).

function Write-Foo($varName)
{
  $var = 
  ($MyInvocation.line -replace '\s*write-foo\s*\$','').trim()

  '{0}: {1}' -f $var,$varName
}

$something =  'Hello'

write-foo $something
something: Hello

It's easier if you pass the name without the $

function Write-Foo($varName)
{
  $var = Get-Variable $varName 
  '{0}: {1}' -f $var.Name,$var.Value 
}

$something =  'Hello'

write-foo something
something: Hello

I'll also second @Ansgar Weicher's suggestion of writing that to the Debug stream so you don't pollute the pipeline with it.

Comments

1

You could define a function like this:

function Write-Foo($msg) {
  Write-Host ("SomeThing: {0}" -f $msg)
}

or (if you want the output to be available for further processing) like this:

function Write-Foo($msg) {
  "SomeThing: {0}" -f $msg
}

However, since you said you want to output debugging information, using the already existing Write-Debug cmdlet might be a better approach:

PS C:\> Write-Debug 'foo'
PS C:\> $DebugPreference
SilentlyContinue
PS C:\> $DebugPreference = 'Continue'
PS C:\> Write-Debug 'foo'
DEBUG: foo

Comments

1

You can access the function's parameters through $MyInvocation.BoundParameters, so this may be what you want:

function Write-Foo($varName) {
    foreach ($key in $MyInvocation.BoundParameters.Keys) {
        Write-Verbose ("{0}: {1}" -f ($key, $MyInvocation.BoundParameters[$key])) -Verbose
    }
}
Write-Foo "Hello"

and the output looks like this:

VERBOSE: varName: Hello

If you want to be able to control when the debug information appears you can turn this into a cmdlet:

function Write-Foo {
[CmdletBinding()]
Param ($varName)
    foreach ($key in $MyInvocation.BoundParameters.Keys) {
        Write-Verbose ("{0}: {1}" -f ($key, $MyInvocation.BoundParameters[$key]))
    }
}
Write-Foo "Hello"
Write-Foo "This will debug" -Verbose

and the first call produces no output while the second will show you:

VERBOSE: Verbose: True
VERBOSE: varName: This will debug

Naturally you can choose how exactly to output the debug information. Probably either Write-Debug (which usually prompts for each line of output) or Write-Verbose (which is usually suppressed) is appropriate here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.