Search code examples
powershellpowershell-cmdlet

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");
    }
}

Solution

  • 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");
            }
        }
    }