1

I write own powershell func for debug like:

function StartDebug {
    param (
        [PARAMETER(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        $FunctionName,
        [PARAMETER(Mandatory = $false)]
        $OtherArg
    )

    try {& $FunctionName $OtherArg} catch {...} finally {...}

and use it everyway, but i need more arg after $FunctionName. is it realistic to pass many arguments in this case bec use from 0 to 10 arg. do I have to list all the arguments that can be in the parameters of the function? like:

function StartDebug {
    param (
        [PARAMETER(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        $FunctionName,
        [PARAMETER(Mandatory = $false)]
        $OtherArg,
        [PARAMETER(Mandatory = $false)]
        $OtherArg1,
        [PARAMETER(Mandatory = $false)]
        $OtherArg2,
        [PARAMETER(Mandatory = $false)]
        $OtherArg3
    )

    try {& $FunctionName $OtherArg OtherArg1 OtherArg2 OtherArg3 } catch {...} finally {...}

but i dont use positional parameters in code and too many named parameters in code (~100)

Interested in any ideas about this. tnx!

2 Answers 2

0

The magic word is Splatting. You can provide an array or a hashtable containing your arguments to a function. The splatter is written with an @VariableName instead of the $:

function StartDebug {
    param (
        [PARAMETER(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        $FunctionName,
        [PARAMETER(Mandatory = $false)]
        $OtherArg
    )

    try {& $FunctionName @OtherArg    # Watch out for the @ in the OtherArg
    } catch {$_} finally {}
}


$FunctionName = 'Get-ChildItem'

$Splatter = @{
    Path      = 'C:\'
    Filter    = 'Users'
    Directory = $true
}

$Splatter2 = @('c:\')

StartDebug $FunctionName $Splatter

StartDebug $FunctionName $Splatter2

However if you want to use single items as $OtherArg you will have to provide them as single element array as can be seen with $Splatter2. Or extend your function to transform single arguments in arrays automatically, but thats up to you.

Sign up to request clarification or add additional context in comments.

2 Comments

Wow. It working. Сan you describe the process "transform single arguments in arrays" in more detail?
technically you have 2 options. 1. check if the .count of $OtherArg is high than 1 , then use @ else use $. 2. if the if the .count is 1 place $OtherArg in @() like in $Splatter2 or write [array]$OtherArg in both cases it will be cast to an array.
0

I think you better run it using scriptblock:

$result = Invoke-DeepDebug { Get-ChildItem -Path 'C:\' ; Get-Service -InformationAction Continue}

And in Invoke-DeepDebug you can work with $Command.AST as deep and detailed as you want.

Function Invoke-DeepDebug {
    param(
        [Parameter(Mandatory=$true, Position=0)]
        [Scriptblock]$Command
    )

    Write-Host -f Cyan "Executing " -n
    Write-Host -f Magenta $Command.Ast.Extent.Text -n 
    Write-Host -f Yellow " ... " -n

    $result = $null
    try { 
        $result = Invoke-Command $Command -ErrorAction Stop
        Write-Host -f Green "OK!" 
    } catch { 
        Write-Host -f Red "Error"
        Write-Host -f Red "`t$($_.Exception.Message)"
    }
    return $result
}

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.