Skip to content

What is the right way to implement deprecation in PowerShell? #11674

@mklement0

Description

@mklement0

Follow-up from #11662 (comment):

Context:

Note: Deprecation in the context of PowerShell is always "soft" deprecation in the sense that, given the commitment to backward compatibility, features are never removed, so that old code continues to function. Instead, deprecation means discouraging use of a given feature, for various reasons: having been superseded by a superior alternative, general obsoleteness, security concerns.

Deprecation can be implemented in the following, potentially complementary ways:

  • Documentation warnings: Clearly state that a given cmdlet / one of its parameters is deprecated and should not be used in new code.

  • Design-time warnings: Implement a PSScriptAnalyzer (PSSA) warning that is ideally also surfaced in Visual Studio Code, via the PowerShell extension's integrated PowerShell Editor Services (PSES).
    This is currently mostly not implemented (see details below).

  • Runtime warnings:
    Currently, a warning (to stream 3) is emitted when a deprecated feature is called.

The latter are currently implemented by a repurposing of the general System.ObsoleteAttribute attribute, whose purpose is to provide compile-time warnings (and optionally errors) about obsolete features: given that PowerShell code isn't compiled, the PowerShell engine explicitly surfaces Obsolete attributes on cmdlets or their parameters (but seemingly not SDK classes with the attribute) with a PowerShell warning at runtime.

Examples of features currently deprecated this way are Send-MailMessage and the -Raw parameter of the Format-Hex cmdlet; e.g.:

PS> 'foo' | Format-Hex -Raw
WARNING: Parameter 'Raw' is obsolete. Raw parameter is deprecated.
... # regular output

3>$null or -WarningAction Ignore can be used to suppress the warning, but old code written pre-deprecation will show the warning.

As an aside: The combination of the boilerplate part of the warning (Parameter 'Raw' is obsolete) with the attribute-specific message (Raw parameter is deprecated) could use some revising.


Relevant questions are:

  • Should deprecation be signaled at runtime at all?

    • If so, is the current approach the right one?
  • Is it sufficient to warn at design time, knowing that not every user will see those warnings, given that they may use an editor other than Visual Studio Code and not install and routinely run Invoke-ScriptAnalyzer after installing the PSScriptAnalyzer module?

    • As of this writing, PSSA (warning) rules seems to comprise just one relating to one specific deprecated feature, AvoidUsingDeprecatedManifestFields, whereas several more deprecated features exist - full list of rules is here.

    • Perhaps a more promising approach is to let PSSA directly surface Obsolete attributes encountered in code, if technically feasible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Committee-ReviewedPS-Committee has reviewed this and made a decisionIssue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-No ActivityIssue has had no activity for 6 months or more

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions