In a Cmdlet, how can I detect if the Debug flag is set?

前端 未结 4 427
暗喜
暗喜 2020-12-19 13:09

I\'m writing a PowerShell Cmdlet and using WriteDebug, but I want to write an object which requires an extra API call, and I\'d rather not make that call when debugging is t

相关标签:
4条回答
  • 2020-12-19 13:23

    Experimentation indicates you might want to look at the $DebugPreference variable. I tried it with advanced functions, but it probably works just as well in a cmdlet.

    Try the following sequence of commands:

    function f { [cmdletbinding()]Param() $DebugPreference }
    function g { [cmdletbinding()]Param() f }
    f
    f -Debug
    g
    g -Debug
    
    0 讨论(0)
  • 2020-12-19 13:26

    Just checking if the -Debug flag is set can be done with the code below, but it is not enough.

    bool debug = false;
    bool containsDebug = MyInvocation.BoundParameters.ContainsKey("Debug");
    if (containsDebug)
        debug = ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();
    

    PowerShell also allows you to set a global flag called $DebugPreference which the code above does not check. And calling a cmdlet from another cmdlet inherits these common parameters which is not inherited through the Debug flag as the code above checks. The code below will check $DebugPreference and solves those problems.

    debug = (ActionPreference)GetVariableValue("DebugPreference") != ActionPreference.SilentlyContinue;
    

    Unfortunately in contrary to a cmdlet in PowerShell you have to check both. So the final C# code is as below. I have also added the code for the Verbose common parameter as bonus. Be sure to inherit from PSCmdlet instead of Cmdlet to get to the GetVariableValue method.

    bool debug = false;
    bool containsDebug = MyInvocation.BoundParameters.ContainsKey("Debug");
    if (containsDebug)
        debug = ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();
    else
        debug = (ActionPreference)GetVariableValue("DebugPreference") != ActionPreference.SilentlyContinue;
    
    bool verbose = false;
    bool containsVerbose = MyInvocation.BoundParameters.ContainsKey("Verbose");
    if (containsVerbose)
        verbose = ((SwitchParameter)MyInvocation.BoundParameters["Verbose"]).ToBool();
    else
        verbose = (ActionPreference)GetVariableValue("VerbosePreference") != ActionPreference.SilentlyContinue; 
    
    0 讨论(0)
  • 2020-12-19 13:40

    Try this:

    $Debug = $psboundparameters.debug.ispresent
    
    
    if ($Debug){
      Write-Debug(string.Format("Name : {0}", api.GetName(myobj))
      }
    
    0 讨论(0)
  • 2020-12-19 13:42

    To access the Debug flag from C# you should be able to do essentially the same thing as mjolinor suggests:

    if (this.MyInvocation.BoundParameters.ContainsKey("Debug"))
    {
        ... do something ...
    }
    

    However, note that you can specify the debug parameter with a value of false:

    MyCmdlet -Debug:$false
    

    To handle this case, you probably want to add something like this (from within the PSCmdlet):

    bool debug = MyInvocation.BoundParameters.ContainsKey("Debug") &&
                 ((SwitchParameter)MyInvocation.BoundParameters["Debug"]).ToBool();
    

    In C# BoundParameters is a dictionary, so you could also use TryGetValue(), but note that the value of a switch (like Debug) is a SwitchParameter not a bool.

    for further information see the following:

    • PSCmdlet.MyInvocation: http://msdn.microsoft.com/en-us/library/system.management.automation.pscmdlet.myinvocation(v=vs.85).aspx
    • BoundParameters: http://msdn.microsoft.com/en-us/library/system.management.automation.invocationinfo.boundparameters(v=vs.85).aspx
    • SwitchParameter: http://msdn.microsoft.com/en-us/library/windows/desktop/system.management.automation.switchparameter(v=vs.85).aspx
    0 讨论(0)
提交回复
热议问题