Skip to content

Conversation

@iSazonov
Copy link
Contributor

@iSazonov iSazonov commented Jun 6, 2018

@markekraus
Copy link

@iSazonov There are 2 RFCs in you commits for this PR.

Copy link
Contributor

@Jaykul Jaykul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the core premise of moving all aliases to three external sets importable via command or configuration is sound, and addresses PowerShell/PowerShell#5870 👍

I do, however, have issues with some of the reasoning and some of the details of this new "alias policy" ...

In general, I'm not sure we want to add things to powershell.config -- In particular I think anything which can easily be done in a profile script should not go in the config file. Both the "GlobalAliasSet" and the dis/enabling of aliases would be better handled in a profile with commands or even preference variables, unless configuration in the powershell.config is the new GPO ...

As far as totally disabling aliases... it seems to me that the use of aliases in scripts or modules is something that the author of said script or module should be able to disable. That is, perhaps the owner of the computer wants to disable it across the board -- fine. This seems very unlikely, but fine. However, even if computer's owner or the current user does not disable aliases ... if the author of a script or modules does not use aliases, perhaps they should be able to explicitly protect it by adding something like:

Set-StrictMode -NoAliases

Of course, conversely -- what if the admin/owner of a system wants to provide alternate implementations of specific commands? They're currently able to do so by duplicating command names and clobbering fully qualified command names with aliases. Even without aliases they could still do this by creating a module with the same module name and command name. Currently when you use a fully-qualified command name, PowerShell resolves that to the first module with that name which was imported in the current session --but if the command is not found there, PowerShell looks in the other modules with the same name-- so it's trivial for an admin/owner to import their own modules first...

1. UX in interactive sessions.

Having many cmdlets and parameters with long names can make it difficult to enter them in interactive sessions.
Users who typically use standard settings are typically satisfied with the ```IntellySense``` capabilities.
Copy link
Contributor

@Jaykul Jaykul Jun 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a false premise.

  1. Users do not have IntelliSense in the console (they have TabExpansion, which is not the same, at all).
  2. Users are not "typically satisfied" without aliases.

Users use aliases all the time. Particularly in the console, but also in scripts and script modules -- as can be easily demonstrated by examination of source code repositories.

Additionally, users complain when you remove aliases. In fact, that's why this RFC is being written: because each time the PowerShell team makes changes to aliases, the users feel pain and complain -- this, in and of itself, demonstrates users aren't satisfied with typing out the full names of commands.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to echo this. Alias use is huge in the console, and even in writing custom scripts. When teaching new users, unfamiliar with PowerShell, the using aliases can help simplify adoption.

Copy link

@dragonwolf83 dragonwolf83 Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not have it today, but I think IntelliSense might be a good solution. PSReadLine 2.0 gets us very close! If it can be made to work as you type instead having to press CTRL + SPACE, then it could be used.

With IntelliSense driven, you could have 3 choices when typing an alias in this order:

  • Executable when alias matches an executable
  • Fully Resolved Name
  • Alias

Include the details on which one it resolves to would ensure the right one is picked.

Copy link
Contributor

@Jaykul Jaykul Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that what we do now in TabExpansion is far too slow to be used as IntelliSense.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes so is ISE and VS Code.... It is an idea. Of course it isn't useable now, but with development focus, it could be quite useful. In fact, I use ISE as the "terminal" because of Intellisense.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IntelliSense can actually be counter productive in some situations, consider the Azure modules.

Copy link

@Panzerbjrn Panzerbjrn Jul 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to echo this. Alias use is huge in the console, and even in writing custom scripts. When teaching new users, unfamiliar with PowerShell, the using aliases can help simplify adoption.

I just wanted to disagree with this. When helping junior staff learn PowerShell or introducing it to completely new learners, using aliases have always been a source of confusion.
% and ? have no logical or intuitive connections to Where-Object or ForEach-Object.
FT/GM/FL might be easier to type, but Get-Member encourages new learners to actually internalise when the command does and is for.

Users are not "typically satisfied" without aliases.

While users might not be typically "satisfied" without aliases, it is hugely annoying that you never know when an alias from one module will block the importing of another module, unless you first run a command to remove all modules. Something which has easily cost me more time than time I have saved writing GCI instead of Get-C{tab}

the dis/enabling of aliases would be better handled in a profile

And so by not having any aliases in PowerShell at all, but maybe include a profile.ps1 file that includes a couple of aliases, you can show people how to create their own if needed.


Having many cmdlets and parameters with long names can make it difficult to enter them in interactive sessions.
Users who typically use standard settings are typically satisfied with the ```IntellySense``` capabilities.
On the other hand, some users actively using interactive sessions may still be annoyed by the need to type names.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe PowerShell is primarily about interactive sessions. The phrasing in this section makes it sound as though you think interactive sessions are a secondary mode that only a few people use...

On the other hand, some users actively using interactive sessions may still be annoyed by the need to type names.
These users should be able to upload their familiar and useful aliases sets to their interactive sessions.
Given the limited functionality of aliases, these users will also configure their environment by executing commands by importing their own functions and various modules using PowerShell profiles.
It should be noted that we are planning to add a domain-specific language (DSL). This will provide users with much greater customization capabilities than aliases.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are you talking about here? What DSL? How would that supplement aliases?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confused why we would expect users to learn another DSL. This sounds excessively complex.


1. Interactive session customization are delegated to users.

It is recommended to use and develop ```IntellySense``` and other means of assistance to users including ML.
Copy link
Contributor

@Jaykul Jaykul Jun 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't ask me to use ML in my interactive console.
Users don't even want their PowerShell command usage to be exposed to Microsoft, never mind the actual command-lines as they type.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ML raises privacy, performance and security concerns for me.

1. Interactive session customization are delegated to users.

It is recommended to use and develop ```IntellySense``` and other means of assistance to users including ML.
Users can use aliases in interactive sessions but in the future it is better to use DSL.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What DSL?

Developers try to create unique cmdlet names.
They can use module prefixes to resolve name conflicts.

On the other hand, developers of the best intentions can complement their modules cmdlet aliases.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not here to correct grammar, in general, but this sentence confused me. I believe this sentence means:

However, despite their best intentions, developers sometimes cause conflicts in their module's aliases.

Moreover, the behavior becomes unpredictable because each subsequent download module or script can change any alias.
Either the user can destroy a script behavior by creating a new alias or by deleting an existing one.

It is even more unpredictable and dangerous to create scripts in the assumption that there are some predefined (standard) aliases because they can be changed by the user or script at any time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statements like this keep getting repeated -- but they are not relevant.

The fear of aliases being changed is irrelevant except when PowerShell changes it's defaults.

In fact, aliases are no more likely to be changed than the commands that they point to --- it is even possible to register a function with a name that clobbers the so-called "fully qualified" command name. There are, in fact, several modules in the gallery which replace or "clobber" built-in commands (including commands which have built-in aliases) -- but I don't know of any which alter any of the built-in aliases.

Copy link

@dragonwolf83 dragonwolf83 Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To which I'm dealing with right now, PowerCLI and PSCX conflict with built-in cmdlets and ones I wrote. There is no easy-clean way to stop that because of Autoloading of Modules. I see no difference with Aliases in this context.

The reliability of the environment from importing new modules or scripts is a separate issue and RFC.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To which I'm dealing with right now, PowerCLI and PSCX conflict with built-in cmdlets and ones I wrote. There is no easy-clean way to stop that because of Autoloading of Modules. I see no difference with Aliases in this context.

The reliability of the environment from importing new modules or scripts is a separate issue and RFC.

This is pretty much the issue that is currently making me blow a gasket.
Hyper-V, Power-CLI and VirtualMachineManager all use some overlapping aliases, which either cause imports to fail, or commands to not run as expected. Hence why I am having to remove all aliases.


Global configuration option ```GlobalAliasSet``` in ```powershell.config``` turns on loading the desired set. It is turned off by default.

1. PowerShell prevents the use of aliases in scripts and modules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would probably be the single biggest breaking change ever proposed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This surprised me as well. I assume this means the inverse (to preserve back-compat all aliases are loaded by default). Separate to this is perhaps an ignorant (but important to me) question: Does my powershell.config live next to my profile.ps1? I would like a way from my user session to ensure no PowerShell "builtin" aliases are included in my interactive session without scrubbing them by hand in my profile, but I don't want to change machine state and I don't want to have to do this manually on every machine I spin up (I auto-sync profile.ps1 today, and I want a mechanism that lets me auto-sync these settings alongside)

Copy link
Contributor

@Jaykul Jaykul Jun 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

powershell.config(.json) lives in the install folder of PowerShell Core

As far as I know, currently it has to be re-edited every couple months when you deploy the latest PowerShell. That's one of the reasons I don't want this sort of thing in there 😉

Copy link

@kjacobsen kjacobsen Jun 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree this is a massive breaking change.

I am also concerned with the suggestion of powershell.config(.json) as it is a per install not a per-user setting. Edit: I see you suggest we could load them manually during a session.

Some users might want different alias options if this change was to go forward, it would also require more deployment work for each new PS Core release.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, @kjacobsen -- the overall intention is to make it so that the only aliases present are the ones the user wants. They can choose to use one of the default sets, or create their own sets. If the choice is managed in your profile --or a unified config location-- there should be no repeating deployment work, you'd just have a one-time need to create or modify a profile, right?


Global configuration option ```GlobalAliasSet``` in ```powershell.config``` turns on loading the desired set. It is turned off by default.

1. PowerShell prevents the use of aliases in scripts and modules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to propose another point to the "alias policy" and that would be to prevent the creation of Functions or Aliases which include slashes in the name. That is:

  1. PowerShell prevent modules and users from clobbering "fully qualified" command names.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PowerShell prevent modules and users from clobbering "fully qualified" command names.

We actually use that to mock stuff when unit testing scripts 😛

@dragonwolf83
Copy link

I think the motivations need to be cleaned up quite a bit so that we can find the best solution.

Motivations

There are two motivations that I think drives an RFC around aliases.

  1. Prevent conflicts with existing executables on both Linux and Windows.
  2. Stop making breaking changes to aliases in each release.

Misleading Motivations

Other motivations I think are misleading issues that should not be considered are:

  1. Users ability to change aliases
  2. Modules and Scripts conflicting with existing aliases
  3. Recommended policy to not allow aliases in scripts
  4. Cannot depend on standard aliases because meant for users to change

Users ability to change aliases

All of those issues are centered around the idea that because something can change means that its bad policy to allow to "protect the users". If this motivates disabling Aliases, then $profile should be
removed as well. User changes are necessary. Best policy here is to give guideance through PSScriptAnalyzer

Import-Module Conflicts

Module issues are abound here with conflicting cmdlets and aliases. It is made worse by Autoloading Modules. A separate RFC is needed to address this because you can't prevent conflicting names, only manage them.

Script Policy

Scripts should allow aliases. The real issue is $profile. I can create my own function in $profile that I depend on in a script. How is that any different than depending on an alias? Regardless of whether it loads by default or not, if I have a method to customize my environment, then I have a chance to forget that when moving scripts.

Standard Aliases

The idea that there is no contract with aliases is false as well. Standard Aliases are a contract as much as the cmdlet name itself. Up until PowerShell Core, aliases existed for 10+ years with no removals (AFAIK). Things change and eventually aliases and cmdlets need to be deprecated and made obsolete.

This speaks heavily to the real motivation #2, stop making changes without a deprecation process! Since Standard Aliases were bundled, and they are a popular feature, a better method is needed to remove them from a release than to just yank them out. Granted, PowerShell Core with Linux presented a problem that needed to be resolved fast, but that is the purpose of this RFC, to find a long-term solution.

Next Steps

Most everyone agrees they want aliases, they just don't want them to conflict with popular tools.

To address #2, create a RFC to propose a Deprecation Process so that any aliases that are removed again do not come unexpected. We should also get Community Feedback on all Standard Aliases. Export them all into a list and put them out to vote. This could be a RFC Pull Request or maybe some other useful tool to gather that feedback. Upvotes would be for support of that alias, downvotes to say it conflicts and then a vote on whether to keep aliases by default or nah.

Keep working through possible solutions that can address #1: conflicting with existing executables on $env:Path or in current working directory.

* % -> ForEach-Object
* foreach -> ForEach-Object
* ? -> Where-Object
* where -> Where-Object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add * select -> Select-Object ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that these are just examples -- but perhaps we should have a discussion about them. If we're going to create a list of "standard" aliases that will always be there, that list becomes almost sacrosanct, and none of these "standard" aliases should ever be removed. Right?

In any case, this particular list is problematic. I agree that the aliases for the *-Object commands are some of the most used, but you would need to include not just select but also sort, tee, and group, as well as compare and measure ...

However, where and sort are probably already on the chopping block (as-in, should have been removed already, based on my understanding of the new rules) because they clobber built-in command-line executables in Windows. If those two need to be removed to an optional set, then I don't see any reason to include any of these outside of an optional set.

Given that, I think probably there are no standard aliases.


1. Windows PowerShell has many aliases that conflict with the names of standard Unix utilities.

These aliases was removed from PowerShell Core.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be:
These aliases were removed from PowerShell Core.


These aliases was removed from PowerShell Core.
This causes a backward compatibility issue when Windows users do not find the familiar aliases in the interactive session.
It also disrupts the operation of custom scripts that use these aliases.
Copy link

@kjacobsen kjacobsen Jun 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should highlight that this also disrupts some modules that would normally work in PS Core.

It also disrupts the operation of custom scripts and modules that use these aliases.

Users who typically use standard settings are typically satisfied with the ```IntellySense``` capabilities.
On the other hand, some users actively using interactive sessions may still be annoyed by the need to type names.
These users should be able to upload their familiar and useful aliases sets to their interactive sessions.
Given the limited functionality of aliases, these users will also configure their environment by executing commands by importing their own functions and various modules using PowerShell profiles.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are assuming that users are in a position to customize their environments. Sometimes you don't get the chance due to the way stuff is deployed or corporate policies.

I certainly wouldn't say that aliases have limited functionality. They provide a significant productivity boost. Consider the common technical of the alias g for git. That saves a considerable amount of time in the long run.

@joeyaiello
Copy link
Contributor

@PowerShell/powershell-committee reviewed this today, and are making a couple of points:

  • We definitely don't want to change any existing behavior with regards to alias usage. Despite our best practice to not use aliases in scripts, this behavior shouldn't be enforced by default as aliases are supported and should work in scripts. We also expect the aliases defined by PowerShell itself to remain largely static on our supported platforms, despite their differences today.
  • It'd be awesome to see an Import-Alias cmdlet created in a Gallery module. We don't believe today that there's enough overwhelming demand to justify the maintenance of introducing this into PowerShell itself.
  • @Jaykul's approach with his ResolveAlias module is a strong mitigation for the scenario of "I want to use aliases while authoring my scripts, but my module 'artifact' should use the full names for readability/shareability/etc". Additionally, the PSSA rules and Quick Fix in VS Code serve as mitigation for this at authoring time.
  • It seems like the majority of folks in the original Please remove **all** built-in aliases and put them in a module PowerShell#5870 issue want aliases back rather than a stricter mode that prevents alias usage altogether, so we're questioning the overall usefulness of a policy or "strict mode" option that prohibits aliases entirely. It seems like using PSSA as a part of acceptance testing modules could solve this problem today.
  • We recognize that the "clobbering" problem (e.g. Get-VM in both Hyper-V and PowerCLI) exists for both functions and aliases, and this is something that's worth looking into more. In particular, it appears that clobbering an existing alias with New-Alias requires a -Force. However, this isn't possible for a bunch of aliases that defined in PowerShell rather than in the modules that define the functions they're aliasing (e.g. iwr is not actually defined in Microsoft.PowerShell.Utility). We should probably clean up those aliases by putting them in the appropriate modules.
    image
    Import-Module, on the other hand, clobbers aliases and functions by default. This might be something worth prohibiting by policy, though this can already be mitigated today with a PSDefaultParameterValues of -NoClobber on Import-Module.

To that end, we're probably going to end up rejecting this particular RFC proposal. However, given how long this has been here, we want to give @iSazonov a chance to respond to some of this to make sure that it makes sense (and for any others who care deeply to chime in). We'll come back to it in a couple of weeks.

@iSazonov
Copy link
Contributor Author

@joeyaiello
The RFC is not critical for me - feel free to close if you want.

It seems your discussion was more about details but the RFC is more high level - about policy.

Major starting points:

  1. The fundamental problem of aliases in their conflicts with each other and other applications.
  2. This area is sensitive because any change disrupts the user's familiar work environment and annoys the user.

Major policy:

  • user must independently manage his working environment and external modules or scripts must not destroy it.

If your team agrees with this, then it's only a matter of timing and details.


Over time, the situation will only get worse.

It's an ecosystem issue. You need to look from the outside and look at the issue in general in order to choose a suitable direction of evolution.

@Panzerbjrn
Copy link

As a parent and mentor/trainer for juniors, I know that often, the best way to teach good behaviour and habits is to remove the temptation to get into bad habits.

I have never seen anything good come out of aliases being available, although I recognise that many like them.
Is it really that much harder to type Get-ch?
Is it really helpful to have both "curl" and "iwr". Do either of them even make sense?
Is it really a good idea to have Aliases that conflict with other languages? curl springs to mind.

@PowerShell/powershell-committee reviewed this today, and are making a couple of points:

  • We definitely don't want to change any existing behavior with regards to alias usage. Despite our best practice to not use aliases in scripts, this behavior shouldn't be enforced by default as aliases are supported and should work in scripts. We also expect the aliases defined by PowerShell itself to remain largely static on our supported platforms, despite their differences today.

Is this not self-contradictory?
Literally every piece of "Best Practice" about PowerShell is pretty clear about not using Aliases in your scripts/modules, so why encourage that behaviour?
I take a broader view, and look at how this encourages bad code by practically asking devs to get into bad habits in the first place.
I believe this is why so many MS product teams churn out awful buggy modules that don't even respect something as fundamental as Try/Catch blocks. making their modules impossible to use in scripts.

To that end, we're probably going to end up rejecting this particular RFC proposal. However, given how long this has been here, we want to give @iSazonov a chance to respond to some of this to make sure that it makes sense (and for any others who care deeply to chime in). We'll come back to it in a couple of weeks.

PowerShell should never have included aliases in the first place, but instead have had some in one of the Profile files.
It isn't too late to fix this, and it would be a good step towards making PowerShell a 1st class citizen in the scripting world.
A half-way house would be to stop importing aliases from modules and add a parameter like -IncludeAliases.

Having said that, because of the many problems with PowerShell and the low quality of MS modules, we're moving almost everything to Python; so I think it's a shame, PowerShell wasa great beginners platform for me and many others.

@joeyaiello
Copy link
Contributor

Given @iSazonov's stance on this, @PowerShell/powershell-committee is deciding to reject this RFC for the time being.

@Panzerbjrn I'm sorry to hear that you're frustrated with aliases in PowerShell, but, even if we place them in the profile, we don't agree that removing aliases is possible without real-world breaking changes, irrespective of our best practices guidance that users not use aliases in production. Similarly, switching alias import at module import time to an opt-in behavior would break people in the real world.

We're also still going to follow-up on making sure alias definitions exist in their appropriate modules rather than SMA.dll

@joeyaiello joeyaiello merged commit 948a894 into PowerShell:master Oct 27, 2020
@iSazonov iSazonov deleted the alias-policy-rfc branch October 28, 2020 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.