How do I use verbose parameter with powershell script (not module)

This topic contains 16 replies, has 4 voices, and was last updated by Profile photo of GS GS 1 year, 9 months ago.

  • Author
    Posts
  • #23317
    Profile photo of GS
    GS
    Participant

    Hello,

    I'm a little confused how can I run my script and specify -Verbose to make Write-Verbose appear which are in my script. Where do I specifically put CmdletBinding attribute?

  • #23318
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The CmdletBinding attribute goes right before the param statement at the beginning of your function:

    function Do-Something
    {
        [CmdletBinding()]
        param ( )
    
        Write-Verbose 'This is verbose!'
    }
    
    Do-Something -Verbose
    
  • #23320
    Profile photo of GS
    GS
    Participant

    What happens if I don't have param() declaration and I declare them like function($x, $y), I tried to put [cmdletbinding]there but it failed with error below. Code and error are below

    function GetResponse ($URI, $Hostname)
    {
    [CmdletBinding()]
    try
    {
    $ResponseCode = (Invoke-WebRequest -Uri $URI -Headers @{"Host"="$Hostname"} -TimeoutSec 5).StatusCode

    PS C:\Users\gsuvalian\Documents> \\prod\serverops\BuildStandards\scripts\getCCSStatus.ps1 -verbose
    At \\prod\serverops\BuildStandards\scripts\getCCSStatus.ps1:7 char:1
    + [CmdletBinding()]
    + ~~~~~~~~~~~~~~~~~
    Unexpected attribute 'CmdletBinding'.
    At \\prod\serverops\BuildStandards\scripts\getCCSStatus.ps1:8 char:1
    + try
    + ~~~
    Unexpected token 'try' in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedAttribute

  • #23321
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You can't do that. CmdletBinding must be applied to a param statement, even if the parentheses after param are empty (as in my example.) Advanced functions must always use the param() construct, not the "Function Do-Something($paramList)" declaration.

  • #23322
    Profile photo of GS
    GS
    Participant

    Do i need to put [CmdletBinding()] in all functions in my script or only the ones which have Write-Verbose?
    My process is calling a workflow and that workflow in turn calling function inside script. So do I put [CmdletBinding()] in both workflow and function?

  • #23323
    Profile photo of GS
    GS
    Participant

    This did not work, what I have is below. I call this script with -verbose and nothing happens, no Write-Verbose execute

    function A {
    [CmdletBinding()]
    param()
    }
    workflow B
    {
    [CmdletBinding()]
    param()
    A
    }
    B

  • #23324
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    It's generally a good idea to put CmdletBinding() in all functions. The only exceptions I make are for internal helper functions in a module, where I control all of the calls to those functions. In those cases, I'll often write old, non-advanced functions (even if they contain calls to Write-Verbose and similar functions), for two reasons:

    – It offers a slight performance increase.
    – The functions will still inherit the value of $VerbosePreference / etc from the exported, advanced functions in the module; there's no need to add on new -Verbose switches inside the module.

  • #23325
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Workflows are something I don't have much experience with. I'm not sure how they interact with normal functions regarding scope, common parameters, etc.

  • #23326
    Profile photo of GS
    GS
    Participant

    It works if I put $VerbosePreference = "Continue" at the start of the script, but would not work if I start my script with -verbose parameter

  • #23327
    Profile photo of Don Jones
    Don Jones
    Keymaster

    The -Verbose parameter is only available if [CmdletBinding()] is present. Otherwise, you can set $VerbosePreference.

  • #23329
    Profile photo of GS
    GS
    Participant

    Yes, I put that tag on both function and workflow but it still does not work, only $VerbosePreference is working.

  • #23338
    Profile photo of GS
    GS
    Participant

    OK. I figure it out. I was supposed to call Workflow withing my script with -Verbose parameter instead of calling my script with -Verbose

    So if I have ps1 file, how do I make it accept -Verbose parameter and pass it to all underlying invocations of WorkFlow inside script?

  • #23340
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    When you call a function with the -Verbose parameter, what it does is set the $VerbosePreference variable _inside that function_ to 'Continue'. It could be that workflows aren't picking up on that function-scoped value for some reason.

    Now that you know what the problem is, though, you could write some code around it. For example:

    $splat = @{}
    if ($VerbosePreference -eq 'Continue') {
        $splat['Verbose'] = $true
    }
    
    YourWorkflowName @splat
    
  • #23342
    Profile photo of GS
    GS
    Participant

    I meant workflow works fine when I call it with -Verbose parameter. My entire script is below. I want to call that script with -Verbose and it somehow translates into call B at the end with -Verbose. Can it be done automatically without making conditional statements?

    function A {
    [CmdletBinding()]
    param()
    }
    workflow B
    {
    [CmdletBinding()]
    param()
    A
    }
    B -Verbose

  • #23343
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Not really. I suppose you could try something like this, to at least keep from adding any new lines to the code:

    B -Verbose:($VerbosePreference -eq 'Continue')
    
  • #23353
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    If you start your script with

    [CmdletBinding()]
    param()
    
    # code
    

    Then you can launch your script with .\scriptname.ps1 -Verbose

    If you want to pass the verbose preference to other scripts called from inside your script, you can do this:

    [CmdletBinding()]
    param()
    
    .\anotherScript -Verbose:$VerbosePreference
    
    AnotherWorkflowOrFunction -Verbose:$VerbosePreference
    

    This way the Verbose parameter will be passed in whatever state it is.

  • #23354
    Profile photo of GS
    GS
    Participant

    Thanks that did the trick
    I did not know that attribute can be applied to the script as a whole

You must be logged in to reply to this topic.