diff --git a/Engine/Helper.cs b/Engine/Helper.cs index 347ebc521..89a33b354 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -349,7 +349,7 @@ public bool PositionalParameterUsed(CommandAst cmdAst) /// /// /// - public CommandInfo GetCommandInfo(string name, CommandTypes commandType = CommandTypes.All) + public CommandInfo GetCommandInfo(string name, CommandTypes commandType = CommandTypes.Alias | CommandTypes.Cmdlet | CommandTypes.Configuration | CommandTypes.ExternalScript | CommandTypes.Filter | CommandTypes.Function | CommandTypes.Script | CommandTypes.Workflow) { return this.invokeCommand.GetCommand(name, commandType); } diff --git a/Engine/SpecialVars.cs b/Engine/SpecialVars.cs index 633657e2d..8b1d8050f 100644 --- a/Engine/SpecialVars.cs +++ b/Engine/SpecialVars.cs @@ -140,6 +140,7 @@ internal enum PreferenceVariable Confirm = 14, } + internal const string Host = "Host"; internal const string HistorySize = "MaximumHistoryCount"; internal const string OutputEncoding = "OutputEncoding"; internal const string NestedPromptLevel = "NestedPromptLevel"; @@ -159,6 +160,7 @@ internal enum PreferenceVariable internal static readonly string[] OtherInitializedVariables = new string[] { + Host, HistorySize, OutputEncoding, NestedPromptLevel, diff --git a/README.md b/README.md index efe28c450..0de5ddc6c 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,87 @@ If you have previous version of PSScriptAnalyzer installed on your machine, you To confirm installation: run ```Get-ScriptAnalyzerRule``` in the PowerShell console to obtain the built-in rules +Suppressing Rules +================= + +You can suppress a rule by decorating a script/function or script/function parameter with .NET's [SuppressMessageAttribute](https://msdn.microsoft.com/en-us/library/system.diagnostics.codeanalysis.suppressmessageattribute.aspx). `SuppressMessageAttribute`'s constructor takes two parameters: a category and a check ID. Set the `categoryID` parameter to the name of the rule you want to suppress (you may omit the `checkID` parameter): + + function SuppressMe() + { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideCommentHelp")] + param() + + Write-Verbose -Message "I'm making a difference!" + + } + +All rule violations within the scope of the script/function/parameter you decorate will be suppressed. + +To suppress a message on a specific parameter, set the `SuppressMessageAttribute`'s `CheckId` parameter to the name of the parameter: + + function SuppressTwoVariables() + { + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideDefaultParameterValue", "b")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideDefaultParameterValue", "a")] + param([string]$a, [int]$b) + { + } + } + +Use the `SuppressMessageAttribute`'s `Scope` property to limit rule suppression to functions or classes within the attribute's scope. Use the value `Function` to suppress violations on all functions within the attribute's scope. Use the value `Class` to suppress violoations on all classes within the attribute's scope: + + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSProvideCommentHelp", "", Scope="Function")] + param( + ) + + function InternalFunction + { + param() + + Write-Verbose -Message "I am invincible!" + } + +The above example demonstrates how to suppress rule violations for internal functions using the `SuppressMessageAttribute`'s `Scope` property. + +You can further restrict suppression based on a function/parameter/class/variable/object's name by setting the `SuppressMessageAttribute's` `Target` property to a regular expression. Any function/parameter/class/variable/object whose name matches the regular expression is skipped. + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPositionalParameters", Scope="Function", Target="PositionalParametersAllowed")] + Param( + ) + + function PositionalParametersAllowed() + { + Param([string]$Parameter1) + { + Write-Verbose $Parameter1 + } + + } + + function PositionalParametersNotAllowed() + { + param([string]$Parameter1) + { + Write-Verbose $Parameter1 + } + } + + # The script analyzer will skip this violation + PositionalParametersAllowed 'value1' + + # The script analyzer will report this violation + PositionalParametersNotAllowed 'value1 + +To match all functions/variables/parameters/objects, use `*` as the value of the Target parameter: + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPositionalParameters", Scope="Function", Target="*")] + Param( + ) + + + + Building the Code ================= diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 index b2f61dfb8..2f28ff5a2 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVarsNoViolations.ps1 @@ -9,6 +9,9 @@ function Test { $a = 3; +#should not raise error +$Host + "hi there!" -match "hi" | Out-Null; $matches[0]; diff --git a/Tests/Rules/AvoidPositionalParametersNoViolations.ps1 b/Tests/Rules/AvoidPositionalParametersNoViolations.ps1 index 41562ffd8..874ef0bd7 100644 --- a/Tests/Rules/AvoidPositionalParametersNoViolations.ps1 +++ b/Tests/Rules/AvoidPositionalParametersNoViolations.ps1 @@ -4,4 +4,13 @@ Clear-Host Split-Path -Path "Random" -leaf Get-Process | Where-Object {$_.handles -gt 200} get-service-computername localhost | where {($_.status -eq "Running") -and ($_.CanStop -eq $true)} -1, 2, $null, 4 | ForEach-Object {"Hello"} \ No newline at end of file +1, 2, $null, 4 | ForEach-Object {"Hello"} +& "$env:Windir\System32\Calc.exe" Parameter1 Parameter2 + +# There was a bug in Positional Parameter rule that resulted in the rule being fired +# when using external application with absolute paths +# The below function is to validate the fix - rule must not get triggered +function TestExternalApplication +{ + & "c:\Windows\System32\Calc.exe" parameter1 +} \ No newline at end of file