Reputation: 1104
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
Upvotes: 0
Views: 719
Reputation: 68303
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.
Upvotes: 1
Reputation: 95692
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.
Upvotes: 1
Reputation: 10107
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
Upvotes: 2
Reputation: 200323
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
Upvotes: 1
Reputation: 16909
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
Upvotes: 2