Skip to content

A prompt for a mandatory parameter can cause $PSCmdlet.DefaultParameterSetName to reflect the wrong parameter set #11201

Closed

Description

Note: In addition to the immediate bug, the current behavior of selecting the explicitly defined parameter set with its mandatory parameter in parameter-less invocations is questionable as a whole - see the proposal below.

Steps to reproduce

function foo {
  [CmdletBinding()]   # No default parameter set.
  param(

    # Only one explicitly defined parameter set, comprising
    # one mandatory and one optional parameter.
    [Parameter(ParameterSetName='bar', Mandatory)]
    $MandatoryInItsSetButOptionalOverall,
    [Parameter(ParameterSetName='bar')]
    $MustBeCombinedWithMandatory,

    # An untagged (all-parameter-sets) parameter.
    $UnrelatedAndOptional
  )
  # Echo the effective parameter set.
  $PSCmdlet.ParameterSetName
}

# Note: This will (questionably) prompt for a -MandatoryInItsSetButOptionalOverall value.
#       Submit any value or just press Enter.
foo | Should -Be 'bar'

Expected behavior

The test should succeed.

Actual behavior

The test fails:

Expected strings to be the same, but they were different. 
Expected length: 3 Actual length:   18 Strings differ at index 0. 
Expected: 'bar' But was: '__AllParameterSets'

That is, even though set bar was clearly selected - otherwise there would have been no prompt - __AllParameterSets was then reported as the effective parameter set.

As an aside regarding the fundamental behavior:

As the naming of the parameters suggests, bar shouldn't have become the effective parameter set by default.
While that can be worked around by naming an (otherwise unused) different default parameter set in the [CmdletBinding()] attribute, doing so shouldn't be necessary - see the initial post of #11143 for an example, and the proposal below for a potential resolution.

Environment data

PowerShell Core 7.0.0-preview.6

Activity

  1. added
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Nov 26, 2019
  2. jhoneill commented on Nov 27, 2019

    @jhoneill

    This time (!) I think you are right and PowerShell is wrong. (Although "It's a corner case" and "Don't write like that" also apply to some extent)

      param(
        # Only one explicitly defined parameter set, comprising
        # one mandatory and one optional parameter.
        [Parameter(ParameterSetName='bar', Mandatory)]
        $MandatoryInItsSetButOptionalOverall,
        [Parameter(ParameterSetName='bar')]
        $MustBeCombinedWithMandatory,
    
        # An untagged (all-parameter-sets) parameter.
        $UnrelatedAndOptional
      )
    

    Says "I am naming one parameter set". With one set we expect PowerShell to create a second parameter set so you can have "Not the 'bar' set" and it names this '__AllParameterSets'

    Here's the table of what it should do

    $MandInSet    $MustbeComined   $unrelated   Result
       -               -               -         Not Set "bar"
       -               -               X         "
       -               X               -         Set bar, prompt for mand
       -               X               X         "
       X               -               -         Set bar OK as is
       X               -               X         "
       X               X               -         "
       X               X               X         "
    

    And it seems to use this logic to report the parameter set name, but it uses different logic to decide what to prompt for - there it says "There is only one set and that has a mandatory parameter".

    If you declared two sets explicitly i.e

        [Parameter(ParameterSetName='bar')]
        [Parameter(ParameterSetName='Fud')]
        $UnrelatedAndOptional
    

    The problem goes away. But PowerShell should either say "Error: you have defined only one parameter set" or, if allows one set it should use the same logic for prompting and set name.
    To avoid breaking existing scripts it can't throw an error, and can't stop prompting, so, as you say, the "wrong" part is the set name.

  3. mklement0 commented on Nov 27, 2019

    @mklement0
    ContributorAuthor

    Good analysis.

    As for "it's a corner case": only in the sense that it may not be common, but it is a legitimate scenario.

    As for "Don't write like that": You should be able to write like that, because all the information is there to infer the intended behavior; it is just a variant of the more general problem described in #11143: The need to work around the questionable behavior by artificially introducing another parameter set designated as the default [CmdletBinding(DefaultParameterSetName='Fud')]; or, even more cumbersomely, using the workaround you suggest
    ([Parameter(ParameterSetName='bar')] [Parameter(ParameterSetName='Fud')] $UnrelatedAndOptional)).

  4. jhoneill commented on Nov 27, 2019

    @jhoneill

    We can discuss can vs should vs must :-)
    But people should not write functions / cmdlets which define a single parameter set, but it is allowed. Legitimacy is a matter of opinion ... and inferring intent which isn't written is potentially dangerous.

    Dividing things into one set doesn't make any sense, so PS has to either make a second set or throw an error if someone does that. But when the only declared set has a mandatory parameter it goes the "safe" way . So this won't run without a name or ID

    Function BadOne {
    param (
        [Parameter(ParameterSetName="ByID",  Mandatory=$true)]$ID,
        [Parameter(ParameterSetName="ByName",Mandatory=$true)]$Name,
        $waitForServer 
    )
        if ($ID) {runsql "Delete from Foo where ID = $ID"} 
        else     {runsql "Delete from foo where name like '$name*'"}
        if ($waitForServer) {Start-Sleep $waitForServer}
    }

    If I'm lazy and don't write the mandatory, it still doesn't run with out a name or ID , PowerShell protects me from my own bad (but perfectly legal) code. You and I have done that one to death :-)

    But if I take out the ID parameter, PowerShell will decide I can't get into the function without the name parameter. It's handling code I really should not write (but am allowed to write) in the safe way. It's not clear without naming a second set that I want things to proceed so PS so it requires me to be explicit (which good, usually) but that is also cumbersome (bad, usually). I'm fine with that side.
    But if someone depends on the parameter set name (as they might if this is something from which a parameter has been removed) things will break; it needs a single named parameter set, WITH a mandatory parameter AND relying on ParameterSetName to get the bug to occur, but it is a bug all the same.

  5. mklement0 commented on Nov 27, 2019

    @mklement0
    ContributorAuthor

    and inferring intent which isn't written is potentially dangerous.

    Do you consider writing 'foo' -replace 'o' instead of 'foo' -replace 'o', '' dangerous, because it doesn't explicitly specify a replacement operand?

    Having useful, well-documented default behavior is a great blessing, in any language, because it reduces noise.

    But people should not write functions / cmdlets which define a single parameter set, but it is allowed.

    All we know is that the current behavior is inconsistent, and there's no official documentation as to how it should work.

    Logically there is no reason for your "should" and, more importantly, not enforcing it avoids unnecessary code (having to come up with a name for a parameter set that is logically implied and for which a default name exists).

    Omitting a Mandatory property has nothing to do with laziness - it has different semantics that are already meaningfully supported: a group of related parameters belonging to the same parameter set may all be non-mandatory by themselves, yet I may want to know - by querying $PSCmdlet.ParametersetName - if at least one of them was specified. Tagging any of them as Mandatory would break that behavior.

    But if I take out the ID parameter, PowerShell will decide I can't get into the function without the name parameter.

    What you consider a protection, I consider a bug and a nuisance. The inference that -Name is then mandatory overall and that it should become the default parameter set is logically ill-founded.

    It's not clear without naming a second set that I want things to proceed

    If you go by the simple rules proposed in #11143, it is clear: Since no default parameter set is designated, argument-less invocation is allowed (as is invocation with only all-parameter-sets arguments) and makes __AllParameterSets the effective parameter set.

    While that may not make much sense with only a single, mandatory parameter ($Name) in the then only explicit set (ByName), the example in the initial post shows a meaningful example with multiple parameters.

    Of course, if you have just one explicit parameter set whose parameter you want to be mandatory unconditionally, there is no good reason to use an explicit parameter set at all: simply replace [Parameter(ParameterSetName="ByName",Mandatory=$true)]$Name with [Parameter(Mandatory=$true)]$Name

  6. jhoneill commented on Nov 28, 2019

    @jhoneill

    and inferring intent which isn't written is potentially dangerous.

    Do you consider writing 'foo' -replace 'o' instead of 'foo' -replace 'o', '' dangerous, because it doesn't explicitly specify a replacement operand?

    Would it delete information from my production database ?
    foo -replace doesn't parse (but I would have required replace to have the replacement string; however it is what it is now, and changing at this point would create more of a problem)
    You can't run copy -destination \stuff it requires a path. That's inconvenient, it could assume current directory (as it does for destination when path is specified). But since the same thing prevents del [enter] deleting all my files, I'm happy for copy to be consistent and not run without a path.

    But people should not write functions / cmdlets which define a single parameter set,
    Logically there is no reason for your "should" and, more importantly, not enforcing it avoids unnecessary code (having to come up with a name for a parameter set that is logically implied and for which a default name exists).

    The logic is that parametersets divide the the parameters into groups. Dividing into one group makes no sense. It lets people cut a corner, and sometimes that's OK.. But when a parameter in the sole group is mandatory, you can't not select the the group.

    Omitting a Mandatory property has nothing to do with laziness
    It may or may not be. In that example the sets have only one member so they are de-facto mandatory, I want them to be mandatory but I don't need to write it (which is something you were asking to be changed in the other issue), not writing mandatory is cutting a corner in that case, but there are other cases...
    it has different semantics that are already meaningfully supported: a group of related parameters belonging to the same parameter set may all be non-mandatory by themselves, yet I may want to know - by querying $PSCmdlet.ParametersetName - if at least one of them was specified. Tagging any of them as Mandatory would break that behavior.

    If the set can exist without a parameter then that parameter is non-mandatory, I used export-Excel as an example, you can create a table by giving a TableName or TableSyle. That's a set with two optional members.
    You've given a clever use of a single set; though rather than writing[Parameter(parameterSetName="a")]for each parameter and referring using if ($pscmdlet.parametersetname -eq a) {...}
    it's shorter to use
    `$PSBoundParameters.Keys -match "^(Pone|Ptwo)$"

    But if I take out the ID parameter, PowerShell will decide I can't get into the function without the name parameter.

    What you consider a protection, I consider a bug and a nuisance. The inference that -Name is then mandatory overall and that it should become the default parameter set is logically ill-founded.

    The behaviour is protective, it's just a question of whether one values the protection. If there bug is allowing a single parameter set which forces PowerShell to make one of two inferences.

    • Either the author wants the only set they have declared to be default set, therefore the Parameter must be provided
    • Or the author was splitting the parameters into two sets, and wants the one they have not referred to to be the default , so it is OK to continue without providing the parameter.
      The one which doesn't run the code which deletes the data is the one it chooses.

    It's not clear without naming a second set that I want things to proceed

    If you go by the simple rules proposed in #11143, it is clear: Since no default parameter set is designated, argument-less invocation is allowed (as is invocation with only all-parameter-sets arguments) and makes __AllParameterSets the effective parameter set.
    You're asking for Del [enter] to delete all files.

    Of course, if you have just one explicit parameter set whose parameter you want to be mandatory unconditionally, there is no good reason to use an explicit parameter set at all: simply replace [Parameter(ParameterSetName="ByName",Mandatory=$true)]$Name with [Parameter(Mandatory=$true)]$Name

    You're completely correct, that code should never get written. But in a world where people add bits and remove bits if "orphaned" bits like that do occur. If PowerShell is presented with it, is it certain that I have not ended up with one parameter set by deleting other things and so the parameter needs to be mandatory. If I wanted it not to be mandatory I could remove "mandatory" if I wanted it to be unconditionally mandatory I could remove the set When there is ambiguity it doesn't run the code. And

  7. mklement0 commented on Nov 28, 2019

    @mklement0
    ContributorAuthor

    Would it delete information from my production database ?

    It just might, depending on context.

    The point is: There is no substitute for (a) understanding the language features you're working with and (b) testing thoroughly before performing potentially destructive actions.

    foo -replace doesn't parse (but I would have required replace to have the replacement string;

    I, for one, greatly appreciate the convenience of not having to specify the replacement string, because defaulting to '' is a sensible, time-saving, concision-promoting default.

    In other words: You can shoot yourself in the foot with any language feature, but that shouldn't get in the way of implementing sensible default behavior.

    Dividing into one group makes no sense.

    It makes sense if there's an implied other group, which there is is - sometimes: let's make it consistent. If you're not aware of this implied other group, you wouldn't have a reason to create the explicit group to begin with.

    If the set can exist without a parameter
    it's shorter to use `$PSBoundParameters.Keys -match "^(Pone|Ptwo)$"

    That alternative is both obscure and fragile.

    Either the author wants the only set they have declared to be default set

    Then they shouldn't have declared a n explicit set to begin with.

    But in a world where people add bits and remove bits if "orphaned" bits like that do occur.

    Again: you need to understand the feature you're working with, and you must test your use of them.

    Any feature allows you to use it in ways that don't make sense, and it's infeasible to guard against all possible unintended uses.

  8. mklement0 commented on Nov 28, 2019

    @mklement0
    ContributorAuthor

    Another approach to resolving the current inconsistencies and obscure failures, namely one that favors the explicit expression of intent you prefer, would be the following:

    Note: This is a more fundamentally breaking than the proposal in #11143, but perhaps with opt-in features being considered to avoid breaking changes, this is an option:

    • Enforce the following at parse time to signal that there's a fundamental problem with the function that needs resolving, as opposed to the current situational failures that depend on the specifics of a given invocation. This also has the advantage of being able to provide a specific error messages with clear resolution directions.

      • If an explicit parameter set is associated with at least one parameter, enforce designating the default parameter set in [CmdletBinding()] to avoid ambiguity and signal explicit intent.

      • References to otherwise undefined parameter sets in [CmdletBinding()] won't be permitted.

    • [CmdletBinding(DefaultParameterSetName='')] will signal the explicit intent to allow invocations without parameters altogether, as well as invocations comprising all-parameter-sets parameters only.

      • $PSCmdlet.DefaultParameterSetName will then reflect '' (the empty string).
    • While we're at: Let's drop the unnecessary Name suffix from the DefaultParameterSetName and ParameterSetName properties.

  9. jhoneill commented on Nov 28, 2019

    @jhoneill

    The point is: There is no substitute for (a) understanding the language features you're working with and (b) testing thoroughly before performing potentially destructive actions.

    I don't think anyone would disagree with that point. But if one tests a script to ensure that today it can't run without parameters, and then someone changes the language so that it will run and do damaging things with no parameters, it puts the onus on the script author to go back and re-test every script for every release of the language. They won't do that, and then the people who made the change are blamed for the result.

    I wrote "a", "b", "d". "e", "f" | delete-something earlier in the year. and that . after d functions as an operator even with a space after it. So my line read, "a," "b", the 'e' property of the string "d" , "f" and the script (not mine) deleted a*, b*, * and f* . I can bluster all I want that . should never be "member" if followed by white space but there may be people whose code depends on being able to just that. One can't break their scripts to wrap people who make an error like that one in cotton wool.

    foo -replace doesn't parse (but I would have required replace to have the replacement string;

    I, for one, greatly appreciate the convenience of not having to specify the replacement string, because defaulting to '' is a sensible, time-saving, concision-promoting default.

    Its an allowed shortcut it might make it harder for someone who doesn't know that behaviour to read a script (because it is an undocumented feature)
    One could make a case that -join or -split without parameter should join assume '' but that means the operator is sometimes unary and sometimes binary which makes it hard to implement.
    IF things had be designed to require 2 values (my way and the way the [Regex] object works), there is a sound case to say "allow the shortcut", because no-one would have code out there which worked in a particular way with a single value.
    However now that things don't happen that way if I convinced people that it the second operand must error if it has 1 or 3 values that would break existing scripts. Worse, your scripts which relied on that behaviour to remove something would (1) give a non-terminating error, (2) not remove something and (3) blunder on to use the wrong string with who-knows-what consequences. Sometimes the status-quo might not be "best" way but a change causes adverse consequences which outweigh the improvement.. Arguing for a sub-optimum status-quo isn't something many people like doing. But sometimes that's what you have to do to avoid doing harm.

    In other words: You can shoot yourself in the foot

    Did you know "Shooting oneself in the foot" isn't about poor skills with a gun. Soldiers in WWI used did it to get out of fighting. Depending on who you say "He shot himself in the foot" to, they may think you're describing took one negative to because the feared something else.

    Dividing into one group makes no sense.

    It makes sense if there's an implied other group, which there is is - sometimes: let's make it consistent. If you're not aware of this implied other group, you wouldn't have a reason to create the explicit group to begin with.

    PowerShell creates the extra group instead of throwing an error - and doing so helps test code before it is complete. Expanding the scope of it would change the behaviour of scripts which run on PowerShell up to V6, in a way which is dangerous.

    If the set can exist without a parameter
    it's shorter to use `$PSBoundParameters.Keys -match "^(Pone|Ptwo)$"

    That alternative is both obscure and fragile.

    Not at all . And I, for one, greatly appreciate the convenience of being able to use a simple regex rather than attach parameter attributes, and be able to see that condition applies to Parameter_one and _two at the point the conditional code executes and not scroll up to look at the attributes.

    Either the author wants the only set they have declared to be default set

    Then they shouldn't have declared a n explicit set to begin with.

    You're right. But after a painful series of edits by authors who didn't talk to each other the script ended up like that. Should a future version of PowerShell work like all past versions. Or should it assume the author wrote this script with this version of PowerShell in mind ? It's a choice between making you declare a second parameter set and trashing other people's systems.

    But in a world where people add bits and remove bits if "orphaned" bits like that do occur.

    Again: you need to understand the feature you're working with, and you must test your use of them.

    When a script was written by someone who understood how things worked at the time lives in production for years, and is supported by people with less knowledge, that because a laudable but unacheivable goal.

    Any feature allows you to use it in ways that don't make sense, and it's infeasible to guard against all possible unintended uses.

    All possible ? Probably. Del doesn't delete all your files if you run it with no parameters. Why not ? We run del . more than any other version of the command it would be a huge time saver.
    Most commands which need an input won't run without the input. You're arguing that scripts and functions which don't run without input today, should start running without input in the future. It's the equivalent of saying next years version of a dangerous piece of machinery should have the safety guards removed, and if people who relied on them lose arms, they should have understood the machine wasn't the same as ones they used before.

  10. mklement0 commented on Nov 28, 2019

    @mklement0
    ContributorAuthor

    You're arguing that scripts and functions which don't run without input today, should start running without input in the future.

    No. As stated in my proposal in #11143 and the alternative above, they are breaking changes, although in different ways: #11143 would make things more permissive, the alternative would make things stricter.

    I can see the appeal of the stricter approach, but in either case the breaking nature must be managed.

    Note that from your perspective the status quo has insufficient safeguards, and fixing that would mean that existing scripts could break.

  11. jhoneill commented on Nov 28, 2019

    @jhoneill

    You're arguing that scripts and functions which don't run without input today, should start running without input in the future.

    No. As stated in my proposal in #11143

    That says

    If an advanced function or script doesn't explicitly declare a default parameter set via its [CmdletBinding()] attribute:

    • Always allow invocations without arguments

    Today with no input this doesn't run. It has no cmdletbinding attribute and the * line says it would always be allowed to run without arguments, deleting all data.

    Function BadOne {
    param (
        [Parameter(ParameterSetName="ByID")]$ID,
        [Parameter(ParameterSetName="ByName")]$Name,
        $waitForServer 
    )
        if ($ID) {runsql "Delete from Foo where ID = $ID"} 
        else     {runsql "Delete from foo where name like '$name*'"}
        if ($waitForServer) {Start-Sleep $waitForServer}
    }
    

    Your second bullet point it that says:

    • Specifically, do not try to infer a default parameter set from among the explicit ones for parameter-less or only all-parameter-sets parameter invocations.

    Which breaks this script.

    Function OKOne {
    param (
        [Parameter(ParameterSetName="X",Mandatory=$True)]$East,
        [Parameter(ParameterSetName="Y")]$North,
        $waitForServer 
    )
        if ($PSCmdlet.ParameterSetName -eq "Y") {
            "Process North South" 
        }
    }

    Both types of script are common enough that I've encountered multiple clients with scripts which fit one or both patterns.

    Note that from your perspective the status quo has insufficient safeguards, and fixing that would mean that existing scripts could break.

    Well yes, I tried to make the point that it is not about strictness or laxness - as I said, if existing things were made more to my taste (stricter languages - that's how I was taught, I'm stuck with that bias) it could be every bit as bad as making them more to your taste. In my view, very little is broken as things stand: current safeguards are adequate without being excessive; things tend to fail safely, and where shortcuts are denied the extra work is tolerable.

    I had an idea. If there were something named differently, let's call it a "LooseSet" , it could do
    anything you wanted and not break existing scripts.

    Param (
      [parameter(looseSet=A,Mandatory)]$x 
      [parameter(looseSet=A)]$y
      $z 
    )
    

    Would not allow X without Y, but would allow just Z or nothing at all

    Param (
      [parameter(looseSet=one,)]$a
      [parameter(looseSet=one)]$b
      [parameter(looseSet=Two,)]$c
      [parameter(looseSet=Two)]$d 
    )
    

    Would allow no parameters and support a check something to see if you had been passed a or b, or passed c or d without demanding one has a mandatory parameter, or [cmdletbinding] adds a set.
    This could sit in parallel with what exists, breaks nothing, and any explanation would say why they were different from parameter sets and what steps need to be taken to ensure the body isn't dangerous.

  12. mklement0 commented on Nov 28, 2019

    @mklement0
    ContributorAuthor

    What would break is already spelled out in #11143. I understand that you think that is dangerous.
    Reflecting on that is what made me propose the alternative, which I am now leaning toward.

    It would give you the strictness you desire while eliminating inconsistencies and providing clear failure cases with specific error messages.

    But, of course, it is a breaking change that script authors would have to opt into or - God forbid / allow - the right approach for a future PowerShell version not saddled with technical debt.

    Personally, I'm not interested in fixing the current behavior in a backward-compatible fashion (except for the obvious bug that prompted this issue), introducing a new property increases complexity and doesn't eliminate the existing inconsistencies and obscure failures.

  13. jhoneill commented on Nov 28, 2019

    @jhoneill

    That's a misuse of "Technical debt". Things which are imperfect are not automatically technical debt; things which have escalating cost (like interest), can't be avoided forever (like repayment) but are ducked to meet a deadline generally are.

    Personally, I'm not interested in fixing the current behavior in a backward-compatible fashion

    Well that's the end of that discussion then. Re-read of what Bruce said on that other thread. He's smarter than both of us put together. And I'll leave this here. Have a good life.

    #6745 (comment)

  14. mklement0 commented on Nov 29, 2019

    @mklement0
    ContributorAuthor

    That's a misuse of "Technical debt"

    Good point, thank you for the correction. I've always used technical debt loosely (but incorrectly) to mean "accumulated broken behavior that can't be fixed without breaking backward-compatibility", but I do hope it's clear from the content of #6745 that the latter is what I actually meant.

    Well that's the end of that discussion then

    It's the end of my personal involvement in the specific debate of how to improve parameter-set handling without breaking backward compatibility, because:

    • (a) you can work around the existing limitations by simply designating a made-up parameter set in the [CmdletBinding()] attribute - no need for introducing additional properties such as looseSet

    • (b) the fundamental problems with the current behavior cannot be fixed if maintaining backward compatibility is the premise.

    Therefore, my personal interest is limited to exploring how to solve the problem fundamentally, with two possible outcomes:

    • Ideally, a fundamental solution can be implemented and users can at least opt in or, perhaps, some day, there will be a "vNext" in which a fundamental solution can be the default.

    • At the very least, it's important to have clarity on how things should work, which helps guide future design decisions.

    Re-read of what Bruce said on that other thread.

    You're linking to a comment by Joel Bennett (@Jaykul), which refers to a (perceived) fiat decision by the powers that be. Contrast this with this statement, for instance.

    He's smarter than both of us put together.

    The merit of someone's argument is unrelated to your perception of their level of intelligence.

    Have a good life.

    Please refrain from making such comments. They add nothing to the discussion and serve only to antagonize.

  15. mklement0 commented on Nov 29, 2019

    @mklement0
    ContributorAuthor

    Ilya (@iSazonov), can you please label this issue as a bug?

    The surrounding discussion aside, the original problem described in the initial post is a clearly an easily verifiable bug in the context of the current behavior.

    If you want a simpler repro:

    # Just press Enter when prompted; passing a -Foo argument makes the problem go away.
    & { [CmdletBinding()] param([Parameter(Mandatory, ParameterSetName='ByFoo')] $Foo) $PSCmdlet.ParameterSetName } | Should -Be ByFoo
  16. jhoneill commented on Nov 29, 2019

    @jhoneill

    Have a good life.

    Please remain from making such comments. They add nothing to the discussion and serve only to antagonize.

    You are too willing to be be antagonized without realizing that you antogoize others. For clarity, that was intended to mean "I will discuss maters with with you no further; but I bear you no ill will" . Since it is obvious that you're not especially concerned if a change renders the new product unadoptable, don't accept that (e.g) Bruce Payette is more likely to know what's good and bad than you or I, and seem to want to argue every point and the language used, you appear to want to test the second half, but the first half stands. I should, perhaps have known better than to expect you to take a wish of a good future in the spirit it was meant. I won't reply further.

  17. added
    Issue-BugIssue has been identified as a bug in the product
    and removed
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Nov 29, 2019
  18. iSazonov commented on Nov 29, 2019

    @iSazonov
    Collaborator

    James O'Neill (@jhoneill) I wonder why you throw an exception on good discussion? :-) Please be patient and follow CoC. Michael Klement (@mklement0) too - please ignore personal comments - it is moderator's headache :-)

    James O'Neill (@jhoneill) As for your concern. Sometimes we change the mind to the opposite, even in global things. For example, for PowerShell 6 a main rule was "To have only ported cmdlets", all window-only cmdlets was removed (with one exception), But for PowerShell 7 the rule was changed to "To have easy adoption for Windows users". As result some Windows-only cmdlet was added back. This happened because Windows users do not want to use limited PowerShell version and stay on Windows PowerShell. We get this understanding only after collect statistics for 2 years.
    For the discussion we want to collect all points, concerns and ideas so that get more full understanding the problem. Perhaps we reject this today but can accept 2-3 years later. Or forget at all :-) Be patient please.

  19. jhoneill commented on Nov 29, 2019

    @jhoneill

    Ilya (@iSazonov) My patience is finite, so is my time, and engaging with MK has proved to be excessively demanding of both.
    PowerShell 6 has not displaced Windows PowerShell because too many things do not work. That's being addressed in 7: if people are persuaded that what they have worked for 10+ years moves to 7 safely and reliably we get progress; otherwise I'll be working on 5.1 until I retire. I'll point you at Bruce's comment

    even relatively small changes on a core path can seriously hinder adoption. Look at Python 3. It took 10 years to really catch on.

    If someone wants to say they know better than Bruce, and proclaim

    I'm not interested in fixing the current behavior in a backward-compatible fashion

    then it's better for me, and for the general tone if I leave them to it.

  20. mklement0 commented on Nov 29, 2019

    @mklement0
    ContributorAuthor

    James O'Neill (@jhoneill):

    engaging with MK has proved to be excessively demanding of both.

    Please refrain from making such comments. They add nothing to the discussion and serve only to antagonize.

    If someone wants to say they know better than Bruce

    Deferring to whom you perceive to be an authority is your personal choice, but doing so has no place in a rational debate.

    Ilya (@iSazonov):

    please ignore personal comments - it is moderator's headache :-)

    I understand, and I will keep that in mind - I wasn't even aware that moderation of such matters was being performed. (Does what is described here happen routinely?)

    On what - I promise - is a one-time explanation:

    While ignoring personal comments is certainly an option, my personal preference is to:

    • (a) hold people accountable for their actions,

    • and (b) seek to instill an understanding as to why ad hominem comments are uncalled for.

    I agree that, in the face of the apparent futility of (b) here, I should have stopped much earlier (though, except for the original plea, all comments regarding the unwarranted personal dimension were addressed in the context of comments primarily focused on discussing the issue at hand).

  21. jhoneill commented on Nov 30, 2019

    @jhoneill

    engaging with MK has proved to be excessively demanding of both.

    Please refrain from making such comments. They add nothing to the discussion and serve only to antagonize.

    It is interesting that you have used It adds/they add nothing to the discussion and serve only to antagonize. three times as if it is a common response: the bullet points sound like someone who has a prepared strategy when they choose to be antagonized. Others might wonder why they attract that kind of comment.
    How I see the the consumption of my time, and how I feel the strain on my patience is as a valid a thing for me to express as any thought of yours. To categorize that view as an ad hominem attack suggests you might be well advised to avoid Latin tags - I had to study Latin so even its correct use doesn't impress me; when people use it for "he said something I don't like" ... describing the effect would, to coin a phrase, serve only to antagonize.
    My view is that I have wasted too much time responding to postings which only the work of Dunning & Kruger can explain. Having recognized that, I won't you goad me into wasting any more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIssue has been identified as a bug in the productWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions