Powershell: Introduce mode that disables aliases in scripts

Created on 22 Aug 2016  路  10Comments  路  Source: PowerShell/PowerShell

Inspired by PR #1901, I suggest Microsoft create a new version of strict mode for better writing style. In this new version, suppress all aliases by default. (People really should not use aliases in scripts/modules!) Enforcing good command invoking style makes backward compatibility easier both for Microsoft and script writer.

Example:

Set-StrictMode -Version 123; # 123 is an imaginary version number.
iwr -Uri example.com; # This line fails since aliases are suppressed here.
Set-Alias iwr Invoke-WebRequest;
iwr -Uri example.com; # This line succeeds since `iwr` is set explicitly in the scope.

If suppressing all aliases is not approachable, it at least should suppress all aliases that are identical to utilities that is popular in Linux/Unix.

And Microsoft should leave Linux/Unix aliases available to scripts that are not setting this version of strict mode and running on Windows PowerShell. Removing those aliases from Windows PowerShell interactive sessions is good. That'll be acceptable for compatibility and better consistency with PowerShell on other systems.

Area-Cmdlets Issue-Enhancement Up-for-Grabs WG-Language

Most helpful comment

Unfortunately, I don't have a ton of historical context on Set-StrictMode like @BrucePay or @LeeHolmes, but I get the sense it's more about syntactical language purity than best pratices.

For that reason, I'd actually lean more towards this being implemented via Script Analyzer, our static analysis tool. We already have an AvoidAlias rule over there, though it was aggressively derided for being too noisy on people who didn't feel like aliases in scripts were a problem. Given everything with #1901, maybe it's time to bump it up to an Error level severity and tell the pro-alias folks to override AvoidAlias in their PSSA settings files.

All 10 comments

Unfortunately, I don't have a ton of historical context on Set-StrictMode like @BrucePay or @LeeHolmes, but I get the sense it's more about syntactical language purity than best pratices.

For that reason, I'd actually lean more towards this being implemented via Script Analyzer, our static analysis tool. We already have an AvoidAlias rule over there, though it was aggressively derided for being too noisy on people who didn't feel like aliases in scripts were a problem. Given everything with #1901, maybe it's time to bump it up to an Error level severity and tell the pro-alias folks to override AvoidAlias in their PSSA settings files.

@> though it was aggressively derided for being too noisy

@joeyaiello Go ahead, you can say it. You "told us so". ;-) Although, at the time I wasn't thinking about PS running on Linux and the implications. Yikes!

As a result when people calling curl blahblah:
PS will execute the binary curl.exe in PATH (if any) in Strict mode. And run iwr in Normal mode...

Set-StrictMode is dynamic, but we introduced using in a way that makes this possible.

At any rate, this should be an RFC, I suggest writing one up.

Guidance should be as always was to avoid Aliases in scripts & I've always supported the Rule for being noisy as the more experienced PowerShell scripter can always suppress the rule if they want to.

There are some basic aliases that I'd leave alone, even if this gets implemented. Select, Where, that sort of thing.

It seems we want something like:

using language aliases on/off

using language autovariables readonly/writable

I think turning off aliases needs to be tiered a bit rather than a simple on/off. Not all aliases are equally bad. I see the same discussion in PSScriptAnalyzer because its too noisy for core scenarios.

Aliases like iwr, curl, gci, ls, and cat are bad for two reasons:

  1. Too Short and hard to read
  2. Aliases to existing executables like curl, ls, and cat

The most useful aliases are: Select, Where, Group, Sort, %.

I found when doing a lot with the pipeline, the % alias (ForEach-Object) is invaluable to actually making it readable because you can very quickly finding yourself with lots of nested foreach loops. Cutting that down to just % substantially simplifies the code. I know some people stay away from pipelines but I see % as important as | itself and once you get used to it, reads faster than foreach itself or ForEach-Object.

So at a minimum I think we should keep all of the Aliases for -Object since they are core fundamentals of PowerShell and reduce noise a lot. They are likely to be the most used aliases. The full list is below:

PS C:\> Get-Alias | Where ReferencedCommand -Like "*-Object" | Select DisplayName

DisplayName              
-----------              
% -> ForEach-Object      
? -> Where-Object        
compare -> Compare-Object
diff -> Compare-Object   
foreach -> ForEach-Object
group -> Group-Object    
measure -> Measure-Object
select -> Select-Object  
sort -> Sort-Object      
tee -> Tee-Object        
where -> Where-Object    

With IntelliSense in PowerShell (PSReadline, VS Code, ISE) alias profitableness tends to zero.
Currently VS Code warns about alias and allow replace it by two clicks. It is great feature.

In script/module text aliases is bad practice in all times. The situation may become even worse when we realize our Keywords RFC.

The great features of the VSCode PowerShell extension during _editing_ notwithstanding, a strict mode of sorts that prevents _running_ scripts with aliases (ideally, at parse time) sounds useful.

I agree with @dragonwolf83 that certain aliases, such as % and ? are indispensable, but I think allowing aliases that shadow native utilities (e.g., sort) are problematic.

So, I think only the following aliases should still be permitted:

  • _built-in_ aliases (they are the only ones guaranteed to available - at least for a given PS version)...
  • ... that don't shadow native utilities on _any_ platform (in other words: the route that PS _Core_ has already chosen)

Another thing worth preventing in scripts is the use of _elastic syntax_ (e.g., -Expand for -ExpandProperty), because it threatens the long-term stability of the code (future parameters with the same prefix could render the previously unique prefix ambiguous).
(Not all such cases can be prevented however, such as in the case of indirect command execution via strings).

In a similar vein, it would be great if the VSCode PowerShell extension didn't just expand _aliases_ to their underlying commands, but expand _parameter-name prefixes_ to the full parameter names too - and possibly also for the recently proposed extension of elastic syntax to _operators_ - see #4730.

Was this page helpful?
0 / 5 - 0 ratings