Jared Ryan
Jared Ryan

Reputation: 3

Pass -WhatIf flag to all cmdlets being called in powershell script

I have a test powershell script that I am trying to get the whatif flag passed to all cmdlets in the script. In my script I am calling 3 cmdlets new-Item, copy-item and new-customCmdlet. The last one is a custom cmdlet that I wrote. I have added:

[cmdletBinding(SupportsShouldProcess=$True)] 

to both the test script and the custom cmdlet. When I run this proof of concept script with -Whatif the two system cmdlets (New-Item and copy-Item) run in whatif mode but the custom does not. I thought that if a cmdlet had supportsShouldProcess it should get the whatif flag if the script is running in whatif. That is the case for the two system cmdlets but not mine. I have read the other articles about looking at the call stack and I understand how to see if whatif has been set. For this example I just want the cmdlets to use the -whatif flag that the script was run with.

Here is the script I am running with the whatif flag: PS c:> script.ps1 -WhatIf

[cmdletBinding(SupportsShouldProcess=$True)]
param()
Import-Module c:\mycmdlet.dll

New-Item -ItemType file NewItem.txt
Copy-Item item1.txt copiedItem.txt
Copy-Custom test.txt CopiedTest.txt

Here is the cmdlet code:

using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Reflection;

namespace poc.whatif.Cmdlet
{
    [Cmdlet(VerbsCommon.Copy, "Custom")]
    public class CopyCustom : PSCmdlet
    {
        #region paramaters
        [Parameter(Mandatory = true,
            ValueFromPipelineByPropertyName = true,
            ValueFromPipeline = true,
            Position = 0,
            HelpMessage = "Source File")]
        public string srcFile { get; set; }

        [Parameter(Mandatory = true,
            ValueFromPipelineByPropertyName = true,
            ValueFromPipeline = true,
            Position = 0,
            HelpMessage = "Target File")]
        public string targetFile { get; set; }
        #endregion


    protected override void BeginProcessing()
    {
        WriteVerbose("Starting Copy-Custom");
    }

    protected override void ProcessRecord()
    {
       WriteVerbose("Copying files from here to there");   
    }

    protected override void EndProcessing()
    {
        WriteVerbose("Ending Copy-Custom");
    }
}

Upvotes: 0

Views: 1703

Answers (3)

Matt
Matt

Reputation: 46710

I don't know much about C# either but the preference variable $WhatIfPreference seems very pertinent for the scope of your question.

Determines whether WhatIf is automatically enabled for every command that supports it. When WhatIf is enabled, the cmdlet reports the expected effect of the command, but does not execute the command.

So if you are just talking about most of the built-in cmdlets that do support -WhatIf then I would think it would be just a matter of:

$WhatIfPreference = 1 # Default is 0

Upvotes: 0

StephenP
StephenP

Reputation: 4081

You're missing the SupportShouldProcess attribute. Also you are missing the call to ShouldProcess also make sure you look at ShouldContinue and use a Force parameter as well. See the required development guidelines for more info.

Rewrite the ProcessRecord:

protected override void ProcessRecord()
{
    if(ShouldProcess("target","action"))
    {
        if(ShouldContinue("Do Stuff","Do stuff to this object?"))
        {
            WriteVerbose("Copying files from here to there");
        }
    }
}

Upvotes: 0

Frode F.
Frode F.

Reputation: 54911

I don't work with C# cmdlets, but as far as I can see your custom cmdlet hasn't declared that it supports ShouldProcess, so how would it be able to use it? Ex:

[Cmdlet(VerbsCommon.Copy, "Custom")]

should be something like

[Cmdlet(VerbsCommon.Copy, "Custom", SupportsShouldProcess = true)]

And then you need to use the ShouldProcess()-method inside your begin/processing/end-methods to actually define where the whatif-message should say and when it should say it.

Upvotes: 1

Related Questions