Let's assume the following CmdLets:
Write-MyColl
function Write-MyColl {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[psobject] $InputObject
)
$verb = Get-Command Write-Verbose
$fixedName = $PSCmdlet.MyInvocation.InvocationName
function Write-Verbose ($Object) {
& $verb "[$fixedName] $Object"
}
if ($InputObject.name) {
Write-Verbose "Writing `$InputObject's Name: `"$($InputObject.name)`""
}
}
New-MyColl
function New-MyColl {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string[]] $Names
)
$verb = Get-Command Write-Verbose
$fixedName = $PSCmdlet.MyInvocation.InvocationName
function Write-Verbose ($Object) {
& $verb "[$fixedName] $Object"
}
Write-Verbose "Names: $Names"
foreach ($name in $Names) {
@{
id = 123;
name = $name
} | Write-MyColl
}
}
As you can see New-MyColl overrides Microsoft.PowerShell.Utility\Write-Verbose with it's own Write-Verbose. This works perfectly and outputs:
VERBOSE: [New-MyColl] Names: [...]
Now, when Write-MyColl is invoked it should override Function:\Write-Verbose from New-MyColl and I want it to output something like:
VERBOSE: [New-MyColl] [Write-MyColl] Writing `$InputObject's Name: "[...]"
As you might already think, it doesn't work. Write-Verbose recursively calls itself until the end of days. I already tried local function definitions and local variables, but they won't be visible to the invoked CmdLet.
I think for my specific use-case, I will use Get-PsCallStack, however I'd love to see a solution to override overriden functions like described above.
What's hard for me to understand is, why the 2nd Write-Verbose calls itself, so $verb seemingly points to a function, which is not yet defined. Shouldn't it point to the prior defined function? I already tried to Remove-Item the funtion at the end of the script, but it didn't change anything.
Do you have any idea how to achieve this call-stack-behavior?
Thanks to PetSerAI's comment, I came to the following solution:
The
-VerboseParameter isn't passed to the newly created function; that's why I added it to the-ArgumentList. I'm sure, it's not very pretty, but it does exactly what it should. OverwriteWrite-Verbosefor each call.Now the output looks like: