PowerShell / PSScriptAnalyzer

Download ScriptAnalyzer from PowerShellGallery
https://www.powershellgallery.com/packages/PSScriptAnalyzer/
MIT License
1.86k stars 377 forks source link

Add ability to determine when script uses language features and/or cmdlets not available in the specified minimum version of PowerShell #127

Open rkeithhill opened 9 years ago

rkeithhill commented 9 years ago

This is increasingly becoming an issue as PowerShell gets new language features and cmdlets. And cmdlets get new parameters, etc. I could have a #requires -version 3.0 in my script but I'm developing on PowerShell 5.0. It is real easy to slip up and use a lang feature ("using namespace System.Diagnostics") or a cmdlet (New-TemporaryFile) or a new cmdlet parameter (PassThru added to Enable-JobTrigger in v4). It would be great if ScriptAnalyzer saw a #requires -Version X.0 and warned (or errored) when I used a feature not available on X.0. Likewise, I would like to have a parameter to ScriptAnalyzer where I could tell it the minimum version I want to target (perhaps I have several scripts written at different times that have varying levels of #requires -Version).

For bonus points, if someone specified neither the command line parameter (MinimumPowerShellVersion) or had any #requires or min version in their PSD1 file, it would be nice if ScriptAnalyzer told me that - "Scripts require at least version 4 due use of -PassThru parameter on Enable-JobTrigger and use of Get-FileHash cmdlet).

Where things get a bit more tricky is setting a minimum Windows OS version. But the need is there since I have a whole bunch of cmdlets available to me on Windows 8.1 that I know are not available on Windows 7.

ducke commented 9 years ago

:+1:

nightroman commented 9 years ago

That would be really useful. That is what PSSA should be doing in the first place, finding pitfalls like this. They are not easy to check manually, checks are time consuming, and PS documentation sometimes does not mention version changes (e.g. -LiteralPath of *-Clixml is for v3+ and help says nothing about this).

P.S. I should say this, sorry. I am relatively experienced in PowerShell. I tried PSScriptAnalyzer and did not find it useful. Currently it simply does not help me, it does not find issues I am interested in. Instead it adds a lot of noise which rather wastes time. The tool is supposed to save time. I am sure it is too early to judge and a lot of things will be improved and new really useful checks will be added. Like the suggested by @rkeithhill here.

KirkMunro commented 9 years ago

+1

I would like to see this added such that:

a) PSScriptAnalyzer identifies the minimum required version according to what it finds during its analysis (if no #requires statements are present and if it is in a module that does not specify the minimum PowerShell version in the manifest), suggesting as a warning that #requires be used (if it's a script) or PowerShellVersion be added to a manifest if it's a module; and

b) PSScriptAnalyzer raises a different warning if there is an indicated minimum required version that is incorrect based on what is in the script/module.

Kirk Munro Poshoholic, Microsoft MVP Blog http://poshoholic.com/ | Twitter http://twitter.com/poshoholic | LinkedIn http://ca.linkedin.com/in/kirkmunro | GitHub http://github.com/KirkMunro | Facebook http://www.facebook.com/#%21/kirk.munro

Need a PowerShell SME for a project at work? Contact me http://poshoholic.com/contact-me/!

On Fri, May 22, 2015 at 1:52 AM, Roman Kuzmin notifications@github.com wrote:

That would be really useful. That is what PSSA should be doing in the first place, finding pitfalls like this. They are not easy to check manually or time consuming or PS documentation sometimes does not even mentions version changes (-LiteralPath of *-Clixml is for v3+ and help says nothing about this).

— Reply to this email directly or view it on GitHub https://github.com/PowerShell/PSScriptAnalyzer/issues/127#issuecomment-104521799 .

nightroman commented 9 years ago

Some type accelerators were added in v3, i.e. will fail in v2, for example:

ciminstance
NullString
pscredential
pslistmodifier
cultureinfo
mailaddress
bigint
securestring

P.S. I do not use PowerShell 2.0. Why do I care? I develop several tools used by other people. From questions at Stack Overflow I can periodically see that PowerShell 2.0 is still is use. So that some of my tools target v2 as well (if this is not too difficult to achieve, why not?). Hence the interest.

nightroman commented 9 years ago

Yet another class of changes difficult to check manually is enum values. Example: the error action preference values:

KirkMunro commented 9 years ago

Other items added in various releases that could be used in version analysis:

v3: [ordered] "accelerator" (aka PSCustomObject casting - this is actually some syntactic magic that just looks like an accelerator) redirection operators (1> 2> 3> 4> 5> 6>, x>&y, etc.) workflow ForEach-Object and Where-Object parameter sets that use new "simplified" syntax $PSItem automatic variable property enumeration on collections count and length properties on scalar objects $using scope modifier bit operators (-shr, -shl) -Modules parameter on #requires statement

v4: containment operators (-in, -notin) foreach & where magic methods (although you can get those in v3 with the TypePx module loaded, so some consideration needs to be made towards what is only in a certain version because that is all that is possible vs what is in a certain version that could be backported to older versions and what should script analysis do about that) configuration (DSC)

A good way to find the items specific to a particular version of PowerShell is to search help. For example:

Get-Help "PowerShell 3.0"

or

Get-Help "PowerShell 4.0"

I'm not sure those will pick up on documentation where the "PowerShell x.0" string spans more than a single line though.

And of course, this is a great resouce: https://technet.microsoft.com/en-us/library/hh857339.aspx

joeyaiello commented 8 years ago

I want to avoid having a single monolithic rule for all compatibility issues. My current thinking is to create another Source (or 3) for compatibility rules targeting PSv3, PSv4,and PSv5. That way we can approach this in a more incremental manner. Thoughts?

KirkMunro commented 8 years ago

Multiple rules with rule sets for different versions is fine with me.

rkeithhill commented 8 years ago

Yup, that works for me as long as I can select such rules easily enough. Perhaps Get-ScriptAnalyzerRule has a parameter like -CompatVersion where -CompatVersion 3 gives me the rules that target PSv3 as well as the rules that are version independent.

KirkMunro commented 8 years ago

Or, either:

a) let us pick a collection of rule sets to use; or

b) apply rule sets dynamically in certain circumstances (automatically grab the appropriate rule set from PSv3, PSv4, PSv5, etc to apply dynamically based on minimum required version settings in #requires statement or module manifest, etc.).

Kirk Munro Poshoholic, Microsoft MVP Blog http://poshoholic.com/ | Twitter http://twitter.com/poshoholic | LinkedIn http://ca.linkedin.com/in/kirkmunro | GitHub http://github.com/KirkMunro | Facebook http://www.facebook.com/#%21/kirk.munro

Need a PowerShell SME for a project at work? Contact me http://poshoholic.com/contact-me/!

On Tue, Dec 1, 2015 at 6:16 PM, Keith Hill notifications@github.com wrote:

Yup, that works for me as long as I can select such rules easily enough. Perhaps Get-ScriptAnalyzerRule has a parameter like -CompatVersion where -CompatVersion 3 gives me the rules that target PSv3 as well as the rules that are version independent.

— Reply to this email directly or view it on GitHub https://github.com/PowerShell/PSScriptAnalyzer/issues/127#issuecomment-161113334 .

bergmeister commented 6 years ago

Nearly 3 years later... PSSA has the UseCompatibleCmdlets rule for that and PR 954 below updates the files for PowerShell Core 6.0.2 and Windows PowerShell 3/4. If you agree then I will close the issue once all command data files are all updated? Availability of .Net APIs between Windows PowerShell and PowerShell Core is part of issue 805.

rkeithhill commented 6 years ago

That addresses cmdlet compatibility but not sure if it addresses feature compatibility - e.g. support for enums, classes, new operators, new parameters, etc. Perhaps we could close this issue and open a new one that is more specific to features?

bergmeister commented 6 years ago

Good point. A new issue would be good summarising all the differences, especially since PSSA does not need to support v2 any more and we can focus on changes that came only in v4/5/6. As far as I know, enums and classes were introduced in v5. Do you know of any specific new operators that came only in v4/5/6 apart from the ones mentioned above? The command data files include all parameter sets with the relevant parameters btw. I went through the changelog here and the only notable thing that I found was the introduction of #Requires in v4. The only thing that caught me out twice in the past is the breaking behaviour of Get-Content between v4 and v5 (I blogged details here)

PowerCoder commented 4 years ago

I truly miss ISESteroids' ability to look over the script and create the requires-statement for me. I'm still working with Posh v3 and even a few v2 systems and it would be great if I could invoke something with a Posh version as argument that would tell me if the script is compatible with that version and if not, why not.

bergmeister commented 4 years ago

@PowerCoder Such functionality was actually added in 1.18 last year https://devblogs.microsoft.com/powershell/using-psscriptanalyzer-to-check-powershell-version-compatibility/

PowerCoder commented 4 years ago

I apologize. My code is so clean nowadays I have never seen a single PSScriptAnalyzer squiggly in VSCode, so I figured it didn't test for it.

Now I just need to figure out how to set the PoSh extension to check for compatibility with earlier versions of PoSh, so that I get my warnings when I use PoSh5/PwSh Cmdlets. But that is for another repo to help me with...

bergmeister commented 4 years ago

Those rules only run after they've been configured as the extension cannot make assumptions around against which PS version or platforms the script needs to be compatible