2

My advanced script (with [CmdletBinding(SupportsShouldProcess)] attribute) calls a native command. That native command supports a switch that causes it to run in "dry run" mode, i.e., just outputting what would be copied or deleted without actually doing any copying/deleting.

Sample code of the script:

[CmdletBinding(SupportsShouldProcess)]
param ()
gsutil -m rsync -r -n something gs://something

Here the -n switch turns on the dry run mode.

How can I specify this switch based on whether WhatIf switch was passed to my script?

According to this official article, other cmdlets should inherit -WhatIf values automatically, but still it is suggested to explicitly pass the value to the cmdlets: -WhatIf:$WhatIfPreference. But in the call to a native command, I suppose, this approach doesn't work.

AKd
  • 501
  • 4
  • 17
  • 1
    Yes, that is one of the disadvantages of using native commands vs. cmdlets. I guess that you could do something with an [inline if](https://stackoverflow.com/q/25682507/1701026) but for clarity, I would just do two full statements in an `if/else`, like: `if (WhatIf:$WhatIfPreference) { gsutil -n ... } else { gsutil ... }` – iRon Jan 02 '23 at 09:15
  • If ```Start-Process``` is an option, you could append ```-n``` to the ```-ArgumentList``` values depending on whether your cmdlet was called with ```-WhatIf```. That would let you separate the logic of building arguments from the step to actually invoke the native command… – mclayton Jan 02 '23 at 10:10

1 Answers1

1

As others have commented, you could check the $WhatIfPreference preference variable, which will be $true, when your script has been called with -WhatIf argument.

[CmdletBinding(SupportsShouldProcess)]
param ()

$dryMode = @( if( $WhatIfPreference ) { '-n' } )
gsutil -m rsync -r @dryMode something gs://something

To avoid duplicating the gsutil commandline, I've used argument splatting. To support splatting, $dryMode must be an array, which is enforced through the array subexpression operator @(…). If $WhatIfPreference is $true, the array will consist of a single string with the value -n. Otherwise the array will be empty and splatting an empty array doesn't insert anything into the commandline (not even a space).

Using PowerShell 7+, a cleaner syntax using ternary operator is possible:

$dryMode = $WhatIfPreference ? @('-n') : @()
gsutil -m rsync -r @dryMode something gs://something
zett42
  • 25,437
  • 3
  • 35
  • 72