Powershell: Deprecate the -DisableNameChecking parameter, and remove the warnings that are produced if that parameter is not used

Created on 15 Sep 2020  Â·  14Comments  Â·  Source: PowerShell/PowerShell

I am logging this as a bug and not as an enhancement request because in the eyes of a tool builder, this appears to be a bug (or at the very least, a design flaw). The warning that is produced upon import of a module that contains a command with an unapproved verb is for nobody other than the author of that module, yet scripters are the ones who are presented with that message. This poses several problems:

  1. It confuses scripters who don't realize that message is not meant for them unless they also created the module.
  2. It pushes work on toolbuilders to silence this warning if they happen to be using PowerShell behind the scenes and modules they use (that often are beyond their control) happen to cause this warning.

The message that is being conveyed is of good intent, but it is directed at the wrong audience entirely, and it should never have been written as a warning for all to see (warnings are meant to convey useful information to the scripter that they may be doing something wrong). For that reason, the message should be removed entirely from Import-Module and Import-PSSession. The -DisableNameChecking parameter can be kept around for compatibility reasons, but it should simply be ignored. PSScriptAnalyzer is a much more appropriate technology to be used to convey this information to the author of a command.

Steps to reproduce

nmo -name Example {
    function Create-Something {[CmdletBinding()]param(); Write-Verbose 'This could create something big!'}
} | ipmo

Expected behavior

The module would import, without any messages sent to the console.

Actual behavior

The module imports, sending the following output to the console:

WARNING: The names of some imported commands from the module 'Example' include unapproved verbs that might make them
less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose
parameter. For a list of approved verbs, type Get-Verb.

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.3
PSEdition                      Core
GitCommitId                    7.0.3
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0
}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Committee-Reviewed Issue-Question

Most helpful comment

I could see adding this sort of a check to Publish-Module but having it in Import-Module is a real drag.

All 14 comments

Yeah, I think this need is already fairly well covered with PSScriptAnalyzer rules and similar tooling. I see no reason to really keep this around as a warning.

I could see adding this sort of a check to Publish-Module but having it in Import-Module is a real drag.

@PowerShell/powershell-committee discussed this, we understand the pain point and agree that for a user who sees and ignores specific warnings messages will be noise. We propose:

  • We update the current warning message to show the specific commands with unapproved verbs to inform the user so they can more easily find them since they use non-standard verbs and don't have to run a subsequent command
  • We should look into having a fully qualified id for all streams so that we could have a Disable-Warning cmdlet in the future to suppress writing out specific warning messages to satisfy those folks and update all stream output within PowerShell to have these ids

@SteveL-MSFT: Based on that reply, I'm not sure you understand the pain point. In unattended scripts, logs are important, and warnings and error messages are the most important messages within those logs. If anything is to be displayed in PowerShell as a warning, it should be a result of some significant impact. Some examples:

  • you invoked a command to retrieve users, and you were sent back 1000 users, but there are more users to retrieve, so warn the user that they may not be seeing all records because the command was not invoked to retrieve all records
  • you invoked a REST endpoint and your call was redirected, so warn the user about the redirection

Messages indicating that some cmdlets (that you might care less about -- you're running unattended scripts) come with unapproved verbs does not constitute significant impact when it comes to scripting.

It seems you are looking at this through the eyes of an interactive scripting session, where it could be useful to notify users about cmdlets that use non-standard verbs, so that they are more discoverable. Write-Host seems appropriate for this, because it's 100% directed towards interactive PowerShell use where you can get a message in your host to tell you about the cmdlets that are not consistent with PowerShell verb recommendations.

If the message must stay, my strong recommendation would be twofold:

  1. Update the message to call out the specific cmdlets that are using non-standard verbs.
  2. Change the target of the message by making it write directly to the host so that it does not pollute any streams. And by this I mean $host.UI.Write, not Write-Host (that is now written to an information stream). Since this message is only relevant for interactive use, it has no bearing in log files, transcripts, etc., and should never appear in any of them.

I might be missing a point here but the author of a module which generates these messages will have seen them multiple times before letting their code out into the world, and chose to ship a module in that state.
The message says "beware, the author didn't fix the names of their functions, to stop this message appearing so all kinds of other quite basic things could be wrong".

Here is an excerpt from "Shell of an Idea" on the original intent behind this message.

PowerShell today still doesn’t enforce proper verb usage. There’s just a ton of risk in getting it wrong and breaking things for people. But it does now use a “shaming” approach: attempting to load a module that has unapproved verbs will result in a WARNING message. “Sadly,” Snover says, “we didn’t go with my suggested wording, which was something to the effect of, ‘WARNING: you are using a snap-in produced by morons that don’t care about you or your user experience.’”

Not sure how I feel about _that_ being the original intent. Shame is never a particularly effective motivator. 😂

With respect, I disagree with the OP. First and foremost, this is not a bug; the developers intended it as part of the design and I don't see any extenuating circumstances that make this a bug.

Second, this warning is both for the developer and the user. Imagine I import a module called MpDefinitionPackage. When it has New-MpDefinitionPackage, Set-MpDefinitionPackage, Get-MpDefinitionPackage, I naturally assume the command for deleting a package is Remove-MpDefinitionPackage. I'd be very annoyed if it was called Delete-MpDefinitionPackage.

With respect, I disagree with the OP. First and foremost, this is not a bug; the developers intended it as part of the design and I don't see any extenuating circumstances that make this a bug.

Second, this warning is both for the developer and the user. Imagine I import a module called MpDefinitionPackage. When it has New-MpDefinitionPackage, Set-MpDefinitionPackage, Get-MpDefinitionPackage, I naturally assume the command for deleting a package is Remove-MpDefinitionPackage. I'd be very annoyed if it was called Delete-MpDefinitionPackage.

Imagine you don't import your module (because most folks don't...they just invoke commands), and you invoke Get-MpDefinitionPackage, and upon doing so you are presented with a warning (or possibly multiple warnings) about cmdlets that you didn't invoke and weren't going to invoke. Those warnings have absolutely nothing to do with your work, and are irrelevant to you.

Now scale that up to a module containing 100 cmdlets, with only one that uses in incorrect verb. 99 cmdlet invocations could work just fine yet produce a warning for one cmdlet that is an outlier.

Now consider someone not very well experienced with PowerShell, and when they invoke a cmdlet they get a warning. Not an informational message. A warning. Think about event logs, and how warning, error, and critical messages are usually the ones most relevant to a problem when you are looking at log file. When diagnosing issues after the fact, how does a warning telling you that a cmdlet author made a poor decision when it came to naming a small percentage of their cmdlets, which likely have nothing to do with what you were doing.

Of course, I do recognize that the information presented in this message _may_ be useful to some folks. But the signal to noise on this message is by far closer to being noise than signal the majority of times that it occurs (especially since once you see it once or twice, it isn't ever necessary to see it again), and having it classified as a warning message is overstepping in this case.

Regardless, I respect that you disagree @skycommand.

Imagine you don't import your module (because most folks don't...they just invoke commands), and you invoke Get-MpDefinitionPackage, and upon doing so you are presented with a warning (or possibly multiple warnings) about cmdlets that you didn't invoke and weren't going to invoke.

I'm afraid this does not happen.

Care to try it? On a Windows 10 v20H1 computer, open a PowerShell window and immediately issue the following command, without using the autocomplete feature:

PowerShell Get-DOConfig

This command belongs to the DeliveryOptimization module, which contains a cmdlet with an unapproved verb. Yet, you receive no warning of that kind. But upon trying to explicitly import the module, you do get your dreaded warning.

Imagine you are presented with a warning (or possibly multiple warnings) about cmdlets that you didn't invoke and weren't going to invoke.

Any self respecting developer would fix this before they let their code out into the world. So the first think you think is "They didn't test this, what dreadful shoddy code have I got here ?" Run an anti-malware scan and delete it.

First and foremost, this is not a bug; the developers intended it as part of the design and I don't see any extenuating circumstances that make this a bug.

@skycommand: You're making assumptions. Every developer intends every piece of code that they write to be part of the design. If you're not seeing this as an issue, it could very well be that you're making assumptions, not asking the right questions, and simply not looking hard enough at the issue that is being presented.

Imagine you don't import your module (because most folks don't...they just invoke commands), and you invoke Get-MpDefinitionPackage, and upon doing so you are presented with a warning (or possibly multiple warnings) about cmdlets that you didn't invoke and weren't going to invoke.

I'm afraid this does not happen.

This is true, and I misspoke on this point since it had been a while since I posted this -- I was looking for Import-Module in one of the scripts where this was a problem for me and it was not being used, but I should have been looking for Import-PSSession, which is used to import cmdlets from another PowerShell session, this warning shows up for Exchange cmdlet import. Regardless, you're pushback seems to be about interactive PowerShell use. I'm not using PowerShell interactively here. In fact, the fact that PowerShell is being used at all is irrelevant to the end user. But warnings and error messages are, or should be, important, because they highlight problems, especially when running scripts unattended when you are reviewing logs. With this functionality implemented the way it is today, the warning is always generated, even in scenarios where it has no place whatsoever, where you do want warnings _about the actual code being executed, not about insignificant command naming that means nothing to someone reviewing a message log_. I have had to make a significant technical investment to silence these warnings in my product, so I logged this issue because that investment should not have been necessary, and it would be better for the PowerShell community if these warnings were only presented during interactive sessions, if at all. I stand by the opinion that this message is misdirected: it should be for the author), and there are far better ways to communicate such a message. See https://github.com/PowerShell/PowerShell/issues/13637#issuecomment-694260675.

If you had asked questions about this instead of pushing back without understanding why I logged this issue in the first place, we could have a productive discussion about the problem. Instead, your communication makes you come across as a gatekeeper getting in the way of something that truly does need improvement.

I have had to make a significant technical investment to silence these warnings in my product, so I logged this issue because that investment should not have been necessary

I think part of the goal of the warnings was to try to get you to log the issue with the people who own the module with the non-standard verbs.

I am frankly amazed at how well the name-shaming gambit has worked, at least I don't recall having ever seen this warning. If we did not have some mechanism like this, I think it would be a very different world, naming-wise. Maybe we wouldn't actually mind so much... but personally I do find it really nice that I am able to infer command names based on previously-seen nouns and stuff like that. I don't think a PSScriptAnalyzer solution would have even close to the same strength as the current name warning... I don't think I've personally ever run PSScriptAnalyzer. (Not that I think it's bad... I just got started in Powershell before that was a thing, and so I have entrenched habits.)

All that said, I am not opposed to your suggestion to refine the existing mechanism to improve the warning, and I think your idea to get the warning out of logged output has merit and should be considered. To quote again:

  • Update the message to call out the specific cmdlets that are using non-standard verbs.
  • Change the target of the message by making it write directly to the host so that it does not pollute any streams. And by this I mean $host.UI.Write, not Write-Host (that is now written to an information stream). Since this message is only relevant for interactive use, it has no bearing in log files, transcripts, etc., and should never appear in any of them.

this warning shows up for Exchange cmdlet import

We collectively cast our side-eye on you, Exchange cmdlet authors.

We collectively cast our side-eye on you, Exchange cmdlet authors.

Exchange is an...interesting team to work with. The latest Exchange module actually suppresses this warning, completely and quietly bypassing the original intent of having this warning in the first place. In their script module, which makes a connection to Exchange and imports cmdlets from that remote session, they explicitly use -DisableNameChecking internally, so no matter how much anyone might like to be aware that they are exporting commands with non-approved verbs (they have commands with the verbs Delete, Preview, Release, Rotate, Troubleshoot, Upgrade and Validate), they're just quietly hiding that detail and avoiding the public shaming that this warning was intended to call out, and there's nothing really stopping others from designing modules that do the same.

This is a clear failure. Instead of learning from the warning, renaming commands and using aliases for backwards compatibility with other names that they feel they really need to have, they add logic to suppress the warning. Great to see partner teams getting along and playing nice with one another.

Was this page helpful?
0 / 5 - 0 ratings