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

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?

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

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: (:slight_smile: , ParseException
+ FullyQualifiedErrorId : UnexpectedAttribute

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.

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?

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

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.

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.

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

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

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

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?

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

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

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')

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.

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