diff --git a/Engine/Commands/GetScriptAnalyzerLoggerCommand.cs b/Engine/Commands/GetScriptAnalyzerLoggerCommand.cs index 3a0390da3..b26e8b034 100644 --- a/Engine/Commands/GetScriptAnalyzerLoggerCommand.cs +++ b/Engine/Commands/GetScriptAnalyzerLoggerCommand.cs @@ -1,4 +1,16 @@ -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; using System.ComponentModel.Composition; diff --git a/Engine/Commands/GetScriptAnalyzerRuleCommand.cs b/Engine/Commands/GetScriptAnalyzerRuleCommand.cs index 2945941ac..21883302e 100644 --- a/Engine/Commands/GetScriptAnalyzerRuleCommand.cs +++ b/Engine/Commands/GetScriptAnalyzerRuleCommand.cs @@ -1,4 +1,16 @@ -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; using System.ComponentModel.Composition; diff --git a/Engine/Commands/InvokeScriptAnalyzerCommand.cs b/Engine/Commands/InvokeScriptAnalyzerCommand.cs index 50742ce63..cd04f621e 100644 --- a/Engine/Commands/InvokeScriptAnalyzerCommand.cs +++ b/Engine/Commands/InvokeScriptAnalyzerCommand.cs @@ -1,4 +1,16 @@ -using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; using System.ComponentModel.Composition; diff --git a/Engine/Generic/AvoidCmdletGeneric.cs b/Engine/Generic/AvoidCmdletGeneric.cs index 2b3e6d2c7..7946f7895 100644 --- a/Engine/Generic/AvoidCmdletGeneric.cs +++ b/Engine/Generic/AvoidCmdletGeneric.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/AvoidParameterGeneric.cs b/Engine/Generic/AvoidParameterGeneric.cs index 3417fe3ee..7f6a0bf96 100644 --- a/Engine/Generic/AvoidParameterGeneric.cs +++ b/Engine/Generic/AvoidParameterGeneric.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/DiagnosticRecord.cs b/Engine/Generic/DiagnosticRecord.cs index 732777025..66f93d406 100644 --- a/Engine/Generic/DiagnosticRecord.cs +++ b/Engine/Generic/DiagnosticRecord.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/ExternalRule.cs b/Engine/Generic/ExternalRule.cs index 994d99a3a..43b849401 100644 --- a/Engine/Generic/ExternalRule.cs +++ b/Engine/Generic/ExternalRule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/ICommandRule.cs b/Engine/Generic/ICommandRule.cs index dd3bad8e2..082429149 100644 --- a/Engine/Generic/ICommandRule.cs +++ b/Engine/Generic/ICommandRule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/IDSCResourceRule.cs b/Engine/Generic/IDSCResourceRule.cs index a61ef432a..935179b3a 100644 --- a/Engine/Generic/IDSCResourceRule.cs +++ b/Engine/Generic/IDSCResourceRule.cs @@ -1,4 +1,16 @@ -using System.Collections.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System.Collections.Generic; using System.Management.Automation.Language; namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic diff --git a/Engine/Generic/IExternalRule.cs b/Engine/Generic/IExternalRule.cs index 9ef1c7105..d51f33bea 100644 --- a/Engine/Generic/IExternalRule.cs +++ b/Engine/Generic/IExternalRule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/ILogger.cs b/Engine/Generic/ILogger.cs index e49bacea0..9a74aca12 100644 --- a/Engine/Generic/ILogger.cs +++ b/Engine/Generic/ILogger.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/IRule.cs b/Engine/Generic/IRule.cs index 1a32b78d8..e4c3f3bc6 100644 --- a/Engine/Generic/IRule.cs +++ b/Engine/Generic/IRule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/IScriptRule.cs b/Engine/Generic/IScriptRule.cs index 8627dc6bf..c9993d266 100644 --- a/Engine/Generic/IScriptRule.cs +++ b/Engine/Generic/IScriptRule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/ITokenRule.cs b/Engine/Generic/ITokenRule.cs index ab048a356..2213f8d57 100644 --- a/Engine/Generic/ITokenRule.cs +++ b/Engine/Generic/ITokenRule.cs @@ -1,4 +1,16 @@ -using System.Collections.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System.Collections.Generic; using System.Management.Automation.Language; namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic diff --git a/Engine/Generic/LoggerInfo.cs b/Engine/Generic/LoggerInfo.cs index 2c80df2f5..ebb9d72e9 100644 --- a/Engine/Generic/LoggerInfo.cs +++ b/Engine/Generic/LoggerInfo.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/RuleInfo.cs b/Engine/Generic/RuleInfo.cs index 3e7a31597..1848599e5 100644 --- a/Engine/Generic/RuleInfo.cs +++ b/Engine/Generic/RuleInfo.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/SkipNamedBlock.cs b/Engine/Generic/SkipNamedBlock.cs index a170e41df..448c668f5 100644 --- a/Engine/Generic/SkipNamedBlock.cs +++ b/Engine/Generic/SkipNamedBlock.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Generic/SkipTypeDefinition.cs b/Engine/Generic/SkipTypeDefinition.cs index 5279fd518..25214c50f 100644 --- a/Engine/Generic/SkipTypeDefinition.cs +++ b/Engine/Generic/SkipTypeDefinition.cs @@ -1,4 +1,16 @@ -using System.Collections.Generic; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System.Collections.Generic; using System.Management.Automation.Language; namespace Microsoft.Windows.Powershell.ScriptAnalyzer.Generic diff --git a/Engine/Generic/SourceType.cs b/Engine/Generic/SourceType.cs index f85e12ed8..bab7cd0e3 100644 --- a/Engine/Generic/SourceType.cs +++ b/Engine/Generic/SourceType.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/Helper.cs b/Engine/Helper.cs index f66c9b33f..70bd69f6b 100644 --- a/Engine/Helper.cs +++ b/Engine/Helper.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -229,10 +241,11 @@ public bool PositionalParameterUsed(CommandAst cmdAst) /// Given a command's name, checks whether it exists /// /// + /// /// - public CommandInfo GetCommandInfo(string name) + public CommandInfo GetCommandInfo(string name, CommandTypes commandType=CommandTypes.All) { - return Helper.Instance.MyCmdlet.InvokeCommand.GetCommand(name, CommandTypes.All); + return Helper.Instance.MyCmdlet.InvokeCommand.GetCommand(name, commandType); } /// @@ -247,6 +260,29 @@ public IEnumerable DscResourceFunctions(Ast ast) && resourceFunctionNames.Contains((item as FunctionDefinitionAst).Name, StringComparer.OrdinalIgnoreCase), true); } + /// + /// Gets all the strings contained in an array literal ast + /// + /// + /// + public List GetStringsFromArrayLiteral(ArrayLiteralAst alAst) + { + List result = new List(); + + if (alAst != null && alAst.Elements != null) + { + foreach (ExpressionAst eAst in alAst.Elements) + { + if (eAst is StringConstantExpressionAst) + { + result.Add((eAst as StringConstantExpressionAst).Value); + } + } + } + + return result; + } + /// /// Returns true if the block should be skipped as it has a name /// that matches keyword @@ -637,7 +673,7 @@ public int Compare(Tuple t1, Tuple t2) /// /// Class used to do variable analysis on the whole script /// - public class ScriptAnalysis: ICustomAstVisitor2 + public class ScriptAnalysis: ICustomAstVisitor { private VariableAnalysis OuterAnalysis; @@ -663,7 +699,12 @@ public object VisitScriptBlock(ScriptBlockAst scriptBlockAst) if (scriptBlockAst == null) return null; VariableAnalysis previousOuter = OuterAnalysis; - OuterAnalysis = Helper.Instance.InitializeVariableAnalysisHelper(scriptBlockAst, OuterAnalysis); + + // We already run variable analysis in these cases so check + if (!(scriptBlockAst.Parent is FunctionDefinitionAst) && !(scriptBlockAst.Parent is FunctionMemberAst)) + { + OuterAnalysis = Helper.Instance.InitializeVariableAnalysisHelper(scriptBlockAst, OuterAnalysis); + } if (scriptBlockAst.DynamicParamBlock != null) { @@ -691,77 +732,40 @@ public object VisitScriptBlock(ScriptBlockAst scriptBlockAst) } /// - /// Do nothing - /// - /// - /// - public object VisitBaseCtorInvokeMemberExpression(BaseCtorInvokeMemberExpressionAst baseCtorInvokeMemberExpressionAst) - { - return null; - } - - /// - /// Do nothing + /// perform special visiting action if statement is a typedefinitionast /// - /// + /// /// - public object VisitConfigurationDefinition(ConfigurationDefinitionAst configurationDefinitionAst) + private object VisitStatementHelper(StatementAst statementAst) { - return null; - } - - /// - /// Do nothing - /// - /// - /// - public object VisitDynamicKeywordStatement(DynamicKeywordStatementAst dynamicKeywordAst) - { - return null; - } + if (statementAst == null) + { + return null; + } - /// - /// Set outer analysis before further visiting. - /// - /// - /// - public object VisitFunctionMember(FunctionMemberAst functionMemberAst) - { - var previousOuter = OuterAnalysis; - OuterAnalysis = Helper.Instance.InitializeVariableAnalysisHelper(functionMemberAst, OuterAnalysis); + TypeDefinitionAst typeAst = statementAst as TypeDefinitionAst; - if (functionMemberAst != null) + if (typeAst == null) { - functionMemberAst.Body.Visit(this); + statementAst.Visit(this); + return null; } - OuterAnalysis = previousOuter; + foreach (var member in typeAst.Members) + { + FunctionMemberAst functionMemberAst = member as FunctionMemberAst; - return null; - } + if (functionMemberAst != null) + { + var previousOuter = OuterAnalysis; + OuterAnalysis = Helper.Instance.InitializeVariableAnalysisHelper(functionMemberAst, OuterAnalysis); - /// - /// Do nothing - /// - /// - /// - public object VisitPropertyMember(PropertyMemberAst propertyMemberAst) - { - return null; - } + if (functionMemberAst != null) + { + functionMemberAst.Body.Visit(this); + } - /// - /// Visit the functions defined in class - /// - /// - /// - public object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst) - { - if (typeDefinitionAst != null) - { - foreach (var member in typeDefinitionAst.Members) - { - member.Visit(this); + OuterAnalysis = previousOuter; } } @@ -1177,7 +1181,7 @@ public object VisitNamedBlock(NamedBlockAst namedBlockAst) { foreach (var statement in namedBlockAst.Statements) { - statement.Visit(this); + VisitStatementHelper(statement); } } @@ -1260,7 +1264,7 @@ public object VisitStatementBlock(StatementBlockAst statementBlockAst) { foreach (var statement in statementBlockAst.Statements) { - statement.Visit(this); + VisitStatementHelper(statement); } } diff --git a/Engine/Loggers/WriteObjectsLogger.cs b/Engine/Loggers/WriteObjectsLogger.cs index cb6c7ee5e..d348ffdd0 100644 --- a/Engine/Loggers/WriteObjectsLogger.cs +++ b/Engine/Loggers/WriteObjectsLogger.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Engine/PSScriptAnalyzer.psd1 b/Engine/PSScriptAnalyzer.psd1 index 04b9f778a..4e82b6f12 100644 --- a/Engine/PSScriptAnalyzer.psd1 +++ b/Engine/PSScriptAnalyzer.psd1 @@ -23,7 +23,7 @@ Copyright = '(c) 2015. All rights reserved.' Description = 'PSScriptAnalyzer provides script analysis and checks for potential code defects in the scripts by applying a group of builtin or customized rules on the scripts being analyzed.' # Minimum version of the Windows PowerShell engine required by this module -# PowerShellVersion = '' +PowerShellVersion = '5.0' # Name of the Windows PowerShell host required by this module # PowerShellHostName = '' diff --git a/Engine/ScriptAnalyzer.cs b/Engine/ScriptAnalyzer.cs index 1184516b6..1dacd3d63 100644 --- a/Engine/ScriptAnalyzer.cs +++ b/Engine/ScriptAnalyzer.cs @@ -1,4 +1,16 @@ -using Microsoft.Windows.Powershell.ScriptAnalyzer.Commands; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using Microsoft.Windows.Powershell.ScriptAnalyzer.Commands; using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; using System; using System.Collections.Generic; diff --git a/Engine/SpecialVars.cs b/Engine/SpecialVars.cs index 107f9b5ad..298c0ba16 100644 --- a/Engine/SpecialVars.cs +++ b/Engine/SpecialVars.cs @@ -1,6 +1,14 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// using System; using System.Collections; diff --git a/Engine/Strings.cs b/Engine/Strings.cs index 9dfec8b3b..acf802615 100644 --- a/Engine/Strings.cs +++ b/Engine/Strings.cs @@ -1,12 +1,14 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.35317 +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ namespace Microsoft.Windows.Powershell.ScriptAnalyzer { using System; diff --git a/Engine/VariableAnalysis.cs b/Engine/VariableAnalysis.cs index 393cbc63b..bbfa309cf 100644 --- a/Engine/VariableAnalysis.cs +++ b/Engine/VariableAnalysis.cs @@ -1,6 +1,14 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// using System; using System.Collections; diff --git a/Engine/VariableAnalysisBase.cs b/Engine/VariableAnalysisBase.cs index f0530a725..5f136b99b 100644 --- a/Engine/VariableAnalysisBase.cs +++ b/Engine/VariableAnalysisBase.cs @@ -1,6 +1,14 @@ -/********************************************************************++ -Copyright (c) Microsoft Corporation. All rights reserved. ---********************************************************************/ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// using System; using System.Collections; diff --git a/RuleDocumentation/UseShouldProcessForStateChangingFunctions.md b/RuleDocumentation/UseShouldProcessForStateChangingFunctions.md new file mode 100644 index 000000000..4ac36a36b --- /dev/null +++ b/RuleDocumentation/UseShouldProcessForStateChangingFunctions.md @@ -0,0 +1,30 @@ +#UseShouldProcessForStateChangingFunctions +**Severity Level: Warning** + +##Description + +Functions that have verbs like New, Start, Stop, Set, Reset and Restart that change system state should support 'ShouldProcess' + +##How to Fix + +To fix a violation of this rule, please add attribute SupportsShouldProcess. eg: [CmdletBinding(SupportsShouldProcess = $true)] to the function. + +##Example + +Wrong: +``` + function Set-ServiceObject + { + [CmdletBinding()] + param ([string]$c) + } +``` + +Correct: +``` + function Set-ServiceObject + { + [CmdletBinding(SupportsShouldProcess = $true)] + param ([string]$c) + } +``` diff --git a/Rules/AvoidAlias.cs b/Rules/AvoidAlias.cs index 53c37f8b2..3d012e782 100644 --- a/Rules/AvoidAlias.cs +++ b/Rules/AvoidAlias.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidDefaultTrueValueSwitchParameter.cs b/Rules/AvoidDefaultTrueValueSwitchParameter.cs index 5d7504e98..29feba72f 100644 --- a/Rules/AvoidDefaultTrueValueSwitchParameter.cs +++ b/Rules/AvoidDefaultTrueValueSwitchParameter.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidEmptyCatchBlock.cs b/Rules/AvoidEmptyCatchBlock.cs index a60b5d080..34db3c9c4 100644 --- a/Rules/AvoidEmptyCatchBlock.cs +++ b/Rules/AvoidEmptyCatchBlock.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidGlobalVars.cs b/Rules/AvoidGlobalVars.cs index 87dd453a4..b7f983854 100644 --- a/Rules/AvoidGlobalVars.cs +++ b/Rules/AvoidGlobalVars.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidInvokingEmptyMembers.cs b/Rules/AvoidInvokingEmptyMembers.cs index ba0feb95e..5331b67ca 100644 --- a/Rules/AvoidInvokingEmptyMembers.cs +++ b/Rules/AvoidInvokingEmptyMembers.cs @@ -1,3 +1,15 @@ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + using System; using System.Collections.ObjectModel; using System.Collections.Generic; diff --git a/Rules/AvoidParameterGeneric.cs b/Rules/AvoidParameterGeneric.cs index 3417fe3ee..7f6a0bf96 100644 --- a/Rules/AvoidParameterGeneric.cs +++ b/Rules/AvoidParameterGeneric.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidPositionalParameters.cs b/Rules/AvoidPositionalParameters.cs index f43c9f80d..db39e021f 100644 --- a/Rules/AvoidPositionalParameters.cs +++ b/Rules/AvoidPositionalParameters.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidReservedCharInCmdlet.cs b/Rules/AvoidReservedCharInCmdlet.cs index 17a9c38a0..0a1ad4a66 100644 --- a/Rules/AvoidReservedCharInCmdlet.cs +++ b/Rules/AvoidReservedCharInCmdlet.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidReservedParams.cs b/Rules/AvoidReservedParams.cs index d065fd881..106a37984 100644 --- a/Rules/AvoidReservedParams.cs +++ b/Rules/AvoidReservedParams.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidShouldContinueWithoutForce.cs b/Rules/AvoidShouldContinueWithoutForce.cs index e7a956a54..e6e622d56 100644 --- a/Rules/AvoidShouldContinueWithoutForce.cs +++ b/Rules/AvoidShouldContinueWithoutForce.cs @@ -1,3 +1,15 @@ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + using System; using System.Collections.ObjectModel; using System.Collections.Generic; diff --git a/Rules/AvoidTrapStatement.cs b/Rules/AvoidTrapStatement.cs index ada9595fd..5fdd8196a 100644 --- a/Rules/AvoidTrapStatement.cs +++ b/Rules/AvoidTrapStatement.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUnitializedVariable.cs b/Rules/AvoidUnitializedVariable.cs index fa5dab4a7..337a7d955 100644 --- a/Rules/AvoidUnitializedVariable.cs +++ b/Rules/AvoidUnitializedVariable.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUnloadableModule.cs b/Rules/AvoidUnloadableModule.cs index 341e3b14d..5e21ee989 100644 --- a/Rules/AvoidUnloadableModule.cs +++ b/Rules/AvoidUnloadableModule.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidUserNameAndPasswordParams.cs b/Rules/AvoidUserNameAndPasswordParams.cs index a97e2615d..c9cceef18 100644 --- a/Rules/AvoidUserNameAndPasswordParams.cs +++ b/Rules/AvoidUserNameAndPasswordParams.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUsingComputerNameHardcoded.cs b/Rules/AvoidUsingComputerNameHardcoded.cs index 80623a4c3..3563e864a 100644 --- a/Rules/AvoidUsingComputerNameHardcoded.cs +++ b/Rules/AvoidUsingComputerNameHardcoded.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs b/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs index aa54701e0..e7a884b6b 100644 --- a/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs +++ b/Rules/AvoidUsingConvertToSecureStringWithPlainText.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUsingFilePaths.cs b/Rules/AvoidUsingFilePaths.cs index 916b9fe22..cc9a9b256 100644 --- a/Rules/AvoidUsingFilePaths.cs +++ b/Rules/AvoidUsingFilePaths.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidUsingInternalURLs.cs b/Rules/AvoidUsingInternalURLs.cs index 32adac1fe..c165d7672 100644 --- a/Rules/AvoidUsingInternalURLs.cs +++ b/Rules/AvoidUsingInternalURLs.cs @@ -1,3 +1,15 @@ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + using System; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUsingInvokeExpression.cs b/Rules/AvoidUsingInvokeExpression.cs index e32e2f0dc..99c51f799 100644 --- a/Rules/AvoidUsingInvokeExpression.cs +++ b/Rules/AvoidUsingInvokeExpression.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/AvoidUsingPlainTextForPassword.cs b/Rules/AvoidUsingPlainTextForPassword.cs index 0581dbf0b..7933ff47f 100644 --- a/Rules/AvoidUsingPlainTextForPassword.cs +++ b/Rules/AvoidUsingPlainTextForPassword.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/AvoidUsingWriteHost.cs b/Rules/AvoidUsingWriteHost.cs index bb4084abd..b5126a608 100644 --- a/Rules/AvoidUsingWriteHost.cs +++ b/Rules/AvoidUsingWriteHost.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/LoggerInfo.cs b/Rules/LoggerInfo.cs index 2c80df2f5..ebb9d72e9 100644 --- a/Rules/LoggerInfo.cs +++ b/Rules/LoggerInfo.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/MissingModuleManifestField.cs b/Rules/MissingModuleManifestField.cs index d9113b172..6816878f3 100644 --- a/Rules/MissingModuleManifestField.cs +++ b/Rules/MissingModuleManifestField.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/PossibleIncorrectComparisonWithNull.cs b/Rules/PossibleIncorrectComparisonWithNull.cs index 6aa952bc2..149deebe8 100644 --- a/Rules/PossibleIncorrectComparisonWithNull.cs +++ b/Rules/PossibleIncorrectComparisonWithNull.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/ProvideCommentHelp.cs b/Rules/ProvideCommentHelp.cs index e65193518..b6f0e4c02 100644 --- a/Rules/ProvideCommentHelp.cs +++ b/Rules/ProvideCommentHelp.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -10,6 +22,7 @@ using System.Globalization; using System.Threading; using System.Reflection; +using System.Management.Automation; namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules { @@ -19,6 +32,8 @@ namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules [Export(typeof(IScriptRule))] public class ProvideCommentHelp : SkipTypeDefinition, IScriptRule { + private HashSet exportedFunctions; + /// /// AnalyzeScript: Analyzes the ast to check that cmdlets have help. /// @@ -30,6 +45,131 @@ public IEnumerable AnalyzeScript(Ast ast, string fileName) { DiagnosticRecords.Clear(); this.fileName = fileName; + exportedFunctions = new HashSet(StringComparer.OrdinalIgnoreCase); + List exportFunctionsCmdlet = Helper.Instance.CmdletNameAndAliases("export-modulemember"); + + // find functions exported + IEnumerable cmdAsts = ast.FindAll(item => item is CommandAst + && exportFunctionsCmdlet.Contains((item as CommandAst).GetCommandName(), StringComparer.OrdinalIgnoreCase), true); + + CommandInfo exportMM = Helper.Instance.GetCommandInfo("export-modulemember", CommandTypes.Cmdlet); + + // switch parameters + IEnumerable switchParams = (exportMM != null) ? exportMM.Parameters.Values.Where(pm => pm.SwitchParameter) : Enumerable.Empty(); + + if (exportMM == null) + { + return DiagnosticRecords; + } + + foreach (CommandAst cmdAst in cmdAsts) + { + if (cmdAst.CommandElements == null || cmdAst.CommandElements.Count < 2) + { + continue; + } + + int i = 1; + + while (i < cmdAst.CommandElements.Count) + { + CommandElementAst ceAst = cmdAst.CommandElements[i]; + ExpressionAst exprAst = null; + + if (ceAst is CommandParameterAst) + { + var paramAst = ceAst as CommandParameterAst; + var param = exportMM.ResolveParameter(paramAst.ParameterName); + + if (param == null) + { + i += 1; + continue; + } + + if (string.Equals(param.Name, "function", StringComparison.OrdinalIgnoreCase)) + { + // checks for the case of -Function:"verb-nouns" + if (paramAst.Argument != null) + { + exprAst = paramAst.Argument; + } + // checks for the case of -Function "verb-nouns" + else if (i < cmdAst.CommandElements.Count - 1) + { + i += 1; + exprAst = cmdAst.CommandElements[i] as ExpressionAst; + } + } + // some other parameter. we just checks whether the one after this is positional + else if (i < cmdAst.CommandElements.Count - 1) + { + // the next element is a parameter like -module so just move to that one + if (cmdAst.CommandElements[i + 1] is CommandParameterAst) + { + i += 1; + continue; + } + + // not a switch parameter so the next element is definitely the argument to this parameter + if (paramAst.Argument == null && !switchParams.Contains(param)) + { + // skips the next element + i += 1; + } + + i += 1; + continue; + } + } + else if (ceAst is ExpressionAst) + { + exprAst = ceAst as ExpressionAst; + } + + if (exprAst != null) + { + // One string so just add this to the list + if (exprAst is StringConstantExpressionAst) + { + exportedFunctions.Add((exprAst as StringConstantExpressionAst).Value); + } + // Array of the form "v-n", "v-n1" + else if (exprAst is ArrayLiteralAst) + { + exportedFunctions.UnionWith(Helper.Instance.GetStringsFromArrayLiteral(exprAst as ArrayLiteralAst)); + } + // Array of the form @("v-n", "v-n1") + else if (exprAst is ArrayExpressionAst) + { + ArrayExpressionAst arrExAst = exprAst as ArrayExpressionAst; + if (arrExAst.SubExpression != null && arrExAst.SubExpression.Statements != null) + { + foreach (StatementAst stAst in arrExAst.SubExpression.Statements) + { + if (stAst is PipelineAst) + { + PipelineAst pipeAst = stAst as PipelineAst; + if (pipeAst.PipelineElements != null) + { + foreach (CommandBaseAst cmdBaseAst in pipeAst.PipelineElements) + { + if (cmdBaseAst is CommandExpressionAst) + { + exportedFunctions.UnionWith(Helper.Instance.GetStringsFromArrayLiteral((cmdBaseAst as CommandExpressionAst).Expression as ArrayLiteralAst)); + } + } + } + } + } + } + } + } + + i += 1; + } + } + ast.Visit(this); return DiagnosticRecords; @@ -47,10 +187,8 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun return AstVisitAction.SkipChildren; } - if (!string.Equals(funcAst.Name, "Get-TargetResource", StringComparison.OrdinalIgnoreCase) && !string.Equals(funcAst.Name, "Set-TargetResource", StringComparison.OrdinalIgnoreCase) && - !string.Equals(funcAst.Name, "Test-TargetResource", StringComparison.OrdinalIgnoreCase)) + if (exportedFunctions.Contains(funcAst.Name)) { - if (funcAst.GetHelpContent() == null) { DiagnosticRecords.Add( diff --git a/Rules/ProvideVerboseMessage.cs b/Rules/ProvideVerboseMessage.cs index 6faec0730..5f695966d 100644 --- a/Rules/ProvideVerboseMessage.cs +++ b/Rules/ProvideVerboseMessage.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Rules/ReturnCorrectTypesForDSCFunctions.cs b/Rules/ReturnCorrectTypesForDSCFunctions.cs index 64fc6af58..3879e8aea 100644 --- a/Rules/ReturnCorrectTypesForDSCFunctions.cs +++ b/Rules/ReturnCorrectTypesForDSCFunctions.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/ScriptAnalyzerBuiltinRules.csproj b/Rules/ScriptAnalyzerBuiltinRules.csproj index 97680fe99..9e57fe94f 100644 --- a/Rules/ScriptAnalyzerBuiltinRules.csproj +++ b/Rules/ScriptAnalyzerBuiltinRules.csproj @@ -1,4 +1,4 @@ - + Debug @@ -83,6 +83,7 @@ + @@ -108,4 +109,4 @@ mkdir "$(SolutionDir)$(SolutionName)" copy /y "$(TargetPath)" "$(SolutionDir)$(SolutionName)" - + \ No newline at end of file diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs index 21466cf0c..7b6c6133a 100644 --- a/Rules/Strings.Designer.cs +++ b/Rules/Strings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.35317 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -1554,6 +1554,42 @@ internal static string UsePSCredentialTypeName { } } + /// + /// Looks up a localized string similar to Use ShouldProcess For State Changing Functions. + /// + internal static string UseShouldProcessForStateChangingFunctionsCommonName { + get { + return ResourceManager.GetString("UseShouldProcessForStateChangingFunctionsCommonName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Functions that have verbs like New, Start, Stop, Set, Reset, Restart that change system state should support 'ShouldProcess'.. + /// + internal static string UseShouldProcessForStateChangingFunctionsDescrption { + get { + return ResourceManager.GetString("UseShouldProcessForStateChangingFunctionsDescrption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Function ’{0}’ has verb that could change system state. Therefore, the function has to support 'ShouldProcess'.. + /// + internal static string UseShouldProcessForStateChangingFunctionsError { + get { + return ResourceManager.GetString("UseShouldProcessForStateChangingFunctionsError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to UseShouldProcessForStateChangingFunctions. + /// + internal static string UseShouldProcessForStateChangingFunctionsName { + get { + return ResourceManager.GetString("UseShouldProcessForStateChangingFunctionsName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Cmdlet Singular Noun. /// diff --git a/Rules/Strings.resx b/Rules/Strings.resx index caf5bbbb5..f8d13de1b 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -654,4 +654,16 @@ Set-TargetResource function in DSC Resource should not output anything to the pipeline. + + Use ShouldProcess For State Changing Functions + + + Functions that have verbs like New, Start, Stop, Set, Reset, Restart that change system state should support 'ShouldProcess'. + + + Function ’{0}’ has verb that could change system state. Therefore, the function has to support 'ShouldProcess'. + + + UseShouldProcessForStateChangingFunctions + \ No newline at end of file diff --git a/Rules/UseApprovedVerbs.cs b/Rules/UseApprovedVerbs.cs index 35cb7fe40..9df853532 100644 --- a/Rules/UseApprovedVerbs.cs +++ b/Rules/UseApprovedVerbs.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseCmdletCorrectly.cs b/Rules/UseCmdletCorrectly.cs index 7189e324e..f1de7b4cd 100644 --- a/Rules/UseCmdletCorrectly.cs +++ b/Rules/UseCmdletCorrectly.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseDeclaredVarsMoreThanAssignments.cs b/Rules/UseDeclaredVarsMoreThanAssignments.cs index 8a6709b6a..6cbd7d883 100644 --- a/Rules/UseDeclaredVarsMoreThanAssignments.cs +++ b/Rules/UseDeclaredVarsMoreThanAssignments.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseIdenticalMandatoryParametersDSC.cs b/Rules/UseIdenticalMandatoryParametersDSC.cs index f91619482..fb0ac20f4 100644 --- a/Rules/UseIdenticalMandatoryParametersDSC.cs +++ b/Rules/UseIdenticalMandatoryParametersDSC.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.Generic; using System.Linq; using System.Management.Automation.Language; diff --git a/Rules/UseIdenticalParametersDSC.cs b/Rules/UseIdenticalParametersDSC.cs index 853ee8d5d..5f69f6c68 100644 --- a/Rules/UseIdenticalParametersDSC.cs +++ b/Rules/UseIdenticalParametersDSC.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UsePSCredentialType.cs b/Rules/UsePSCredentialType.cs index 77caee6ad..070910e2d 100644 --- a/Rules/UsePSCredentialType.cs +++ b/Rules/UsePSCredentialType.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseShouldProcessCorrectly.cs b/Rules/UseShouldProcessCorrectly.cs index 7ab17944d..f1cb785e4 100644 --- a/Rules/UseShouldProcessCorrectly.cs +++ b/Rules/UseShouldProcessCorrectly.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseShouldProcessForStateChangingFunctions.cs b/Rules/UseShouldProcessForStateChangingFunctions.cs new file mode 100644 index 000000000..cca236a4a --- /dev/null +++ b/Rules/UseShouldProcessForStateChangingFunctions.cs @@ -0,0 +1,130 @@ +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Management.Automation.Language; +using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic; +using System.ComponentModel.Composition; +using System.Globalization; + +namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules +{/// + /// UseShouldProcessCorrectly: Analyzes the ast to check that if the ShouldProcess attribute is present, the function calls ShouldProcess and vice versa. + /// + [Export(typeof(IScriptRule))] + public class UseShouldProcessForStateChangingFunctions : IScriptRule + { + /// + /// AnalyzeScript: Analyzes the ast to check if ShouldProcess is included in Advanced functions if the Verb of the function could change system state. + /// + /// The script's ast + /// The script's file name + /// A List of diagnostic results of this rule + public IEnumerable AnalyzeScript(Ast ast, string fileName) + { + if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage); + + IEnumerable funcDefAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true); + string supportsShouldProcess = "SupportsShouldProcess"; + string trueString = "$true"; + foreach (FunctionDefinitionAst funcDefAst in funcDefAsts) + { + string funcName = funcDefAst.Name; + bool hasShouldProcessAttribute = false; + + if (funcName.StartsWith("Restart-", StringComparison.OrdinalIgnoreCase) || + funcName.StartsWith("Stop-", StringComparison.OrdinalIgnoreCase)|| + funcName.StartsWith("New-", StringComparison.OrdinalIgnoreCase) || + funcName.StartsWith("Set-", StringComparison.OrdinalIgnoreCase) || + funcName.StartsWith("Update-", StringComparison.OrdinalIgnoreCase) || + funcName.StartsWith("Reset-", StringComparison.OrdinalIgnoreCase)) + { + IEnumerable attributeAsts = funcDefAst.FindAll(testAst => testAst is NamedAttributeArgumentAst, true); + if (funcDefAst.Body != null && funcDefAst.Body.ParamBlock != null + && funcDefAst.Body.ParamBlock.Attributes != null && + funcDefAst.Body.ParamBlock.Parameters != null) + { + if (!funcDefAst.Body.ParamBlock.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof (CmdletBindingAttribute))) + { + continue; + } + + foreach (NamedAttributeArgumentAst attributeAst in attributeAsts) + { + if (attributeAst.ArgumentName.Equals(supportsShouldProcess, StringComparison.OrdinalIgnoreCase)) + { + if((attributeAst.Argument.Extent.Text.Equals(trueString, StringComparison.OrdinalIgnoreCase)) && !attributeAst.ExpressionOmitted || + attributeAst.ExpressionOmitted) + { + hasShouldProcessAttribute = true; + } + } + } + + if (!hasShouldProcessAttribute) + { + yield return + new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture,Strings.UseShouldProcessForStateChangingFunctionsError, funcName),funcDefAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName); + } + } + } + } + } + + /// + /// GetName: Retrieves the name of this rule. + /// + /// The name of this rule + public string GetName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.UseShouldProcessForStateChangingFunctionsName); + } + + /// + /// GetCommonName: Retrieves the Common name of this rule. + /// + /// The common name of this rule + public string GetCommonName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.UseShouldProcessForStateChangingFunctionsCommonName); + } + + /// + /// GetDescription: Retrieves the description of this rule. + /// + /// The description of this rule + public string GetDescription() + { + return string.Format(CultureInfo.CurrentCulture, Strings.UseShouldProcessForStateChangingFunctionsDescrption); + } + + /// + /// GetSourceType: Retrieves the type of the rule: builtin, managed or module. + /// + public SourceType GetSourceType() + { + return SourceType.Builtin; + } + + /// + /// GetSourceName: Retrieves the module/assembly name the rule is from. + /// + public string GetSourceName() + { + return string.Format(CultureInfo.CurrentCulture, Strings.SourceName); + } + } + +} diff --git a/Rules/UseSingularNouns.cs b/Rules/UseSingularNouns.cs index 743762414..162a36437 100644 --- a/Rules/UseSingularNouns.cs +++ b/Rules/UseSingularNouns.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Rules/UseStandardDSCFunctionsInResource.cs b/Rules/UseStandardDSCFunctionsInResource.cs index bf97a4cf1..548eac8fa 100644 --- a/Rules/UseStandardDSCFunctionsInResource.cs +++ b/Rules/UseStandardDSCFunctionsInResource.cs @@ -1,4 +1,16 @@ -using System; +// +// Copyright (c) Microsoft Corporation. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +using System; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Linq; diff --git a/Tests/Disabled Rules/AvoidOneChar.tests.ps1 b/Tests/Disabled Rules/AvoidOneChar.tests.ps1 new file mode 100644 index 000000000..6c9820fe1 --- /dev/null +++ b/Tests/Disabled Rules/AvoidOneChar.tests.ps1 @@ -0,0 +1,24 @@ +Import-Module PSScriptAnalyzer +$oneCharMessage = "The cmdlet name O only has one character." +$oneCharName = "PSOneChar" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$invoke = Invoke-ScriptAnalyzer $directory\AvoidUsingReservedCharOneCharNames.ps1 | Where-Object {$_.RuleName -eq $oneCharName} +$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $oneCharName} + +Describe "Avoid Using One Char" { + Context "When there are violations" { + It "has 1 One Char Violation" { + $oneCharViolations.Count | Should Be 1 + } + + It "has the correct description message" { + $oneCharViolations[0].Message | Should Match $oneCharMessage + } + } + + Context "When there are no violations" { + It "has no violations" { + $noReservedCharViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Disabled Rules/AvoidUnloadableModule.tests.ps1 b/Tests/Disabled Rules/AvoidUnloadableModule.tests.ps1 new file mode 100644 index 000000000..a9d5f85cf --- /dev/null +++ b/Tests/Disabled Rules/AvoidUnloadableModule.tests.ps1 @@ -0,0 +1,24 @@ +Import-Module PSScriptAnalyzer +$unloadableMessage = [regex]::Escape("Cannot load the module TestBadModule that the file TestBadModule.psd1 is in.") +$unloadableName = "PSAvoidUnloadableModule" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\TestBadModule\TestBadModule.psd1 | Where-Object {$_.RuleName -eq $unloadableName} +$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $unloadableName} + +Describe "AvoidUnloadableModule" { + Context "When there are violations" { + It "has 1 unloadable module violation" { + $violations.Count | Should Be 1 + } + + It "has the correct description message" { + $violations.Message | Should Match $unloadableMessage + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingClearHostWriteHost.ps1 b/Tests/Disabled Rules/AvoidUsingClearHost.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingClearHostWriteHost.ps1 rename to Tests/Disabled Rules/AvoidUsingClearHost.ps1 diff --git a/Tests/Disabled Rules/AvoidUsingClearHost.tests.ps1 b/Tests/Disabled Rules/AvoidUsingClearHost.tests.ps1 new file mode 100644 index 000000000..b32fd73db --- /dev/null +++ b/Tests/Disabled Rules/AvoidUsingClearHost.tests.ps1 @@ -0,0 +1,25 @@ +Import-Module PSScriptAnalyzer +Set-Alias ctss ConvertTo-SecureString +$clearHostMessage = "File 'AvoidUsingClearHostWriteHost.ps1' uses Clear-Host. This is not recommended because it may not work in some hosts or there may even be no hosts at all." +$clearHostName = "PSAvoidUsingClearHost" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingClearHost.ps1 | Where-Object {$_.RuleName -eq $clearHostName} +$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingClearHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $writeHostName} + +Describe "AvoidUsingClearHost" { + Context "When there are violations" { + It "has 3 Clear-Host violations" { + $violations.Count | Should Be 3 + } + + It "has the correct description message for Clear-Host" { + $violations[0].Message | Should Match $clearHostMessage + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingClearHostWriteHostNoViolations.ps1 b/Tests/Disabled Rules/AvoidUsingClearHostNoViolations.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingClearHostWriteHostNoViolations.ps1 rename to Tests/Disabled Rules/AvoidUsingClearHostNoViolations.ps1 diff --git a/Tests/Rules/AvoidUsingFilePath.ps1 b/Tests/Disabled Rules/AvoidUsingFilePath.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingFilePath.ps1 rename to Tests/Disabled Rules/AvoidUsingFilePath.ps1 diff --git a/Tests/Rules/AvoidUsingFilePath.tests.ps1 b/Tests/Disabled Rules/AvoidUsingFilePath.tests.ps1 similarity index 97% rename from Tests/Rules/AvoidUsingFilePath.tests.ps1 rename to Tests/Disabled Rules/AvoidUsingFilePath.tests.ps1 index 5b34cecdf..50030ee01 100644 --- a/Tests/Rules/AvoidUsingFilePath.tests.ps1 +++ b/Tests/Disabled Rules/AvoidUsingFilePath.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = @' The file path "D:\\Code" of AvoidUsingFilePath.ps1 is rooted. This should be avoided if AvoidUsingFilePath.ps1 is published online '@ diff --git a/Tests/Rules/AvoidUsingFilePathNoViolations.ps1 b/Tests/Disabled Rules/AvoidUsingFilePathNoViolations.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingFilePathNoViolations.ps1 rename to Tests/Disabled Rules/AvoidUsingFilePathNoViolations.ps1 diff --git a/Tests/Rules/CommandNotFound.ps1 b/Tests/Disabled Rules/CommandNotFound.ps1 similarity index 100% rename from Tests/Rules/CommandNotFound.ps1 rename to Tests/Disabled Rules/CommandNotFound.ps1 diff --git a/Tests/Rules/CommandNotFound.tests.ps1 b/Tests/Disabled Rules/CommandNotFound.tests.ps1 similarity index 100% rename from Tests/Rules/CommandNotFound.tests.ps1 rename to Tests/Disabled Rules/CommandNotFound.tests.ps1 diff --git a/Tests/Rules/TypeNotFound.ps1 b/Tests/Disabled Rules/TypeNotFound.ps1 similarity index 100% rename from Tests/Rules/TypeNotFound.ps1 rename to Tests/Disabled Rules/TypeNotFound.ps1 diff --git a/Tests/Rules/TypeNotFound.tests.ps1 b/Tests/Disabled Rules/TypeNotFound.tests.ps1 similarity index 94% rename from Tests/Rules/TypeNotFound.tests.ps1 rename to Tests/Disabled Rules/TypeNotFound.tests.ps1 index fc9b0e9dc..72ed21180 100644 --- a/Tests/Rules/TypeNotFound.tests.ps1 +++ b/Tests/Disabled Rules/TypeNotFound.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module -Verbose ScriptAnalyzer +Import-Module -Verbose PSScriptAnalyzer $violationMessage = "Type Stre is not found" $violationName = "PSTypeNotFound" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/UseTypeAtVariableAssignment.ps1 b/Tests/Disabled Rules/UseTypeAtVariableAssignment.ps1 similarity index 100% rename from Tests/Rules/UseTypeAtVariableAssignment.ps1 rename to Tests/Disabled Rules/UseTypeAtVariableAssignment.ps1 diff --git a/Tests/Rules/UseTypeAtVariableAssignment.tests.ps1 b/Tests/Disabled Rules/UseTypeAtVariableAssignment.tests.ps1 similarity index 95% rename from Tests/Rules/UseTypeAtVariableAssignment.tests.ps1 rename to Tests/Disabled Rules/UseTypeAtVariableAssignment.tests.ps1 index 8dc737e0a..3b2551533 100644 --- a/Tests/Rules/UseTypeAtVariableAssignment.tests.ps1 +++ b/Tests/Disabled Rules/UseTypeAtVariableAssignment.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module -Verbose ScriptAnalyzer +Import-Module -Verbose PSScriptAnalyzer $violationMessage = [regex]::Escape('Specify type at the assignment of variable $test') $violationName = "PSUseTypeAtVariableAssignment" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1 b/Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1 index 17d763601..8b96af38f 100644 --- a/Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1 +++ b/Tests/Engine/CommunityAnalyzerRules/CommunityAnalyzerRules.psm1 @@ -95,7 +95,7 @@ function Measure-RequiresRunAsAdministrator $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; "Extent" = $assignmentAst.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } @@ -106,7 +106,7 @@ function Measure-RequiresRunAsAdministrator $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresRunAsAdministrator; "Extent" = $assignmentAst.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } @@ -195,7 +195,7 @@ function Measure-RequiresModules $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresModules; "Extent" = $ast.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } @@ -209,7 +209,7 @@ function Measure-RequiresModules $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureRequiresModules; "Extent" = $ast.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } @@ -288,7 +288,7 @@ function Measure-LongClassName $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureLongClassName; "Extent" = $sbResult.BoundParameters["TypeName"].Value.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } @@ -346,7 +346,7 @@ function Measure-DeprecatedWMIClass $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureDeprecatedWMIClass; "Extent" = $StringConstantExpressionAst.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } @@ -511,7 +511,7 @@ function Measure-CurlyBracket $result = [Microsoft.Windows.Powershell.ScriptAnalyzer.Generic.DiagnosticRecord]@{"Message" = $Messages.MeasureCurlyBracket; "Extent" = $ast.Extent; "RuleName" = $PSCmdlet.MyInvocation.InvocationName; - "Severity" = "Strict"} + "Severity" = "Information"} $results += $result } } diff --git a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 index 9b0bea2aa..dbbc97f08 100644 --- a/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 +++ b/Tests/Engine/GetScriptAnalyzerRule.tests.ps1 @@ -1,9 +1,8 @@ -Import-Module -Verbose ScriptAnalyzer +Import-Module -Verbose PSScriptAnalyzer $sa = Get-Command Get-ScriptAnalyzerRule $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $singularNouns = "PSUseSingularNouns" $approvedVerbs = "PSUseApprovedVerbs" -$unloadableModule = "PSAvoidUnloadableModule" $dscIdentical = "PSDSCUseIdenticalParametersForDSC" Describe "Test available parameters" { @@ -45,9 +44,8 @@ Describe "Test Name parameters" { } It "works with 3 names" { - $rules = Get-ScriptAnalyzerRule -Name $unloadableModule, $approvedVerbs, $singularNouns - $rules.Count | Should Be 3 - ($rules | Where-Object {$_.Name -eq $unloadableModule}).Count | Should Be 1 + $rules = Get-ScriptAnalyzerRule -Name $approvedVerbs, $singularNouns + $rules.Count | Should Be 2 ($rules | Where-Object {$_.Name -eq $singularNouns}).Count | Should Be 1 ($rules | Where-Object {$_.Name -eq $approvedVerbs}).Count | Should Be 1 } diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index 16aa0862c..53ddb9a02 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $sa = Get-Command Invoke-ScriptAnalyzer $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $singularNouns = "PSUseSingularNouns" @@ -26,16 +26,6 @@ Describe "Test available parameters" { } } - Context "LoggerPath parameters" { - It "has a LoggerPath parameter" { - $params.ContainsKey("LoggerPath") | Should Be $true - } - - It "accepts string array" { - $params["LoggerPath"].ParameterType.FullName | Should Be "System.String[]" - } - } - Context "IncludeRule parameters" { It "has an IncludeRule parameter" { $params.ContainsKey("IncludeRule") | Should Be $true @@ -72,21 +62,21 @@ Describe "Test Path" { } Context "When given a directory" { - $withoutPathWithDirectory = Invoke-ScriptAnalyzer $directory\RecursionDirectoryTest - $withPathWithDirectory = Invoke-ScriptAnalyzer -Path $directory\RecursionDirectoryTest + $withoutPathWithDirectory = Invoke-ScriptAnalyzer -Recurse $directory\RecursionDirectoryTest + $withPathWithDirectory = Invoke-ScriptAnalyzer -Recurse -Path $directory\RecursionDirectoryTest It "Has the same count as without Path parameter"{ $withoutPathWithDirectory.Count -eq $withPathWithDirectory.Count | Should Be $true } - It "Analyzes all the file" { + It "Analyzes all the files" { $globalVarsViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidGlobalVars"} $clearHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingClearHost"} $writeHostViolation = $withPathWithDirectory | Where-Object {$_.RuleName -eq "PSAvoidUsingWriteHost"} Write-Output $globalVarsViolation.Count Write-Output $clearHostViolation.Count Write-Output $writeHostViolation.Count - $globalVarsViolation.Count -eq 1 -and $clearHostViolation.Count -eq 1 -and $writeHostViolation.Count -eq 1 | Should Be $true + $globalVarsViolation.Count -eq 1 -and $writeHostViolation.Count -eq 1 | Should Be $true } } @@ -151,12 +141,12 @@ Describe "Test Exclude And Include" { Describe "Test Severity" { Context "When used correctly" { It "works with one argument" { - $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Strict + $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Information $errors.Count | Should Be 0 } It "works with 2 arguments" { - $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Strict, Warning + $errors = Invoke-ScriptAnalyzer $directory\TestScript.ps1 -Severity Information, Warning $errors.Count | Should Be 2 } } diff --git a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 index 9c4e78ff0..2f0febbb2 100644 --- a/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 +++ b/Tests/Rules/AvoidConvertToSecureStringWithPlainText.tests.ps1 @@ -1,6 +1,6 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer Set-Alias ctss ConvertTo-SecureString -$violationMessage = "File AvoidConvertToSecureStringWithPlainText.ps1 uses ConvertTo-SecureString with plaintext. This will expose secure information. Encrypted standard strings should be used instead." +$violationMessage = "File 'AvoidConvertToSecureStringWithPlainText.ps1' uses ConvertTo-SecureString with plaintext. This will expose secure information. Encrypted standard strings should be used instead." $violationName = "PSAvoidUsingConvertToSecureStringWithPlainText" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidConvertToSecureStringWithPlainText.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 index 9163327a0..469dc6a66 100644 --- a/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 +++ b/Tests/Rules/AvoidDefaultTrueValueSwitchParameter.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "File AvoidDefaultTrueValueSwitchParameter.ps1 has a switch parameter default to true." +Import-Module PSScriptAnalyzer +$violationMessage = "File 'AvoidDefaultTrueValueSwitchParameter.ps1' has a switch parameter default to true." $violationName = "PSAvoidDefaultValueSwitchParameter" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidDefaultTrueValueSwitchParameter.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 index 175a417b4..bcd2fb9d5 100644 --- a/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 +++ b/Tests/Rules/AvoidEmptyCatchBlock.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "Empty catch block is used. Please use Write-Error or throw statements in catch blocks." $violationName = "PSAvoidUsingEmptyCatchBlock" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 b/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 index e7ac86448..537f57024 100644 --- a/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 +++ b/Tests/Rules/AvoidGlobalOrUnitializedVars.tests.ps1 @@ -1,8 +1,8 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $globalMessage = "Found global variable 'Global:1'." $globalName = "PSAvoidGlobalVars" $nonInitializedName = "PSAvoidUninitializedVariable" -$nonInitializedMessage = "Variable a is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." +$nonInitializedMessage = "Variable 'a' is not initialized. Non-global variables must be initialized. To fix a violation of this rule, please initialize non-global variables." $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidGlobalOrUnitializedVars.ps1 $globalViolations = $violations | Where-Object {$_.RuleName -eq $globalName} @@ -18,7 +18,7 @@ Describe "AvoidGlobalVars" { } It "has the correct description message" { - $violations[0].Message | Should Match $violationMessage + $violations[0].Message | Should Match $globalMessage } } diff --git a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 index 8c83d7503..de411f490 100644 --- a/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 +++ b/Tests/Rules/AvoidInvokingEmptyMembers.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "() has non-constant members. Invoking empty members may cause bugs in the script." $violationName = "PSAvoidInvokingEmptyMembers" diff --git a/Tests/Rules/AvoidPositionalParameters.tests.ps1 b/Tests/Rules/AvoidPositionalParameters.tests.ps1 index 022017b32..82be8a726 100644 --- a/Tests/Rules/AvoidPositionalParameters.tests.ps1 +++ b/Tests/Rules/AvoidPositionalParameters.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "Cmdlet Get-Content has positional parameter. Please use named parameters instead of positional parameters when calling a command." +Import-Module PSScriptAnalyzer +$violationMessage = "Cmdlet 'Get-Content' has positional parameter. Please use named parameters instead of positional parameters when calling a command." $violationName = "PSAvoidUsingPositionalParameters" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidPositionalParameters.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidReservedParams.tests.ps1 b/Tests/Rules/AvoidReservedParams.tests.ps1 index b6b70f42b..602af77fd 100644 --- a/Tests/Rules/AvoidReservedParams.tests.ps1 +++ b/Tests/Rules/AvoidReservedParams.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = [regex]::Escape("Verb-Files' defines the reserved common parameter 'Verbose'.") $violationName = "PSReservedParams" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 index 2a73c3b5a..4fab2e16b 100644 --- a/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 +++ b/Tests/Rules/AvoidShouldContinueWithoutForce.tests.ps1 @@ -1,14 +1,14 @@ -Import-Module ScriptAnalyzer -$violationMessage = "Function Verb-Noun in file AvoidShouldContinueShouldProcessWithoutForce.ps1 uses ShouldContinue or ShouldProcess but does not have a boolean force parameter. The force parameter will allow users of the script to bypass ShouldContinue prompt" -$violationName = "PSAvoidShouldContinueShouldProcessWithoutForce" +Import-Module PSScriptAnalyzer +$violationMessage = "Function 'Verb-Noun' in file 'AvoidShouldContinueWithoutForce.ps1' uses ShouldContinue but does not have a boolean force parameter. The force parameter will allow users of the script to bypass ShouldContinue prompt" +$violationName = "PSAvoidShouldContinueWithoutForce" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\AvoidShouldContinueShouldProcessWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} +$violations = Invoke-ScriptAnalyzer $directory\AvoidShouldContinueWithoutForce.ps1 | Where-Object {$_.RuleName -eq $violationName} $noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} -Describe "AvoidShouldContinueShouldProcessWithoutForce" { +Describe "AvoidShouldContinueWithoutForce" { Context "When there are violations" { - It "has 4 avoid ShouldContinue or ShouldProcess without boolean Force parameter violations" { - $violations.Count | Should Be 4 + It "has 2 avoid ShouldContinue without boolean Force parameter violations" { + $violations.Count | Should Be 2 } It "has the correct description message" { diff --git a/Tests/Rules/AvoidTrapStatements.tests.ps1 b/Tests/Rules/AvoidTrapStatements.tests.ps1 index 3888ae03a..4b4aa674f 100644 --- a/Tests/Rules/AvoidTrapStatements.tests.ps1 +++ b/Tests/Rules/AvoidTrapStatements.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "Trap found." $violationName = "PSAvoidTrapStatement" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 index de1dc67dc..8f828d9ac 100644 --- a/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 +++ b/Tests/Rules/AvoidUnloadableModuleOrMissingRequiredFieldInManifest.tests.ps1 @@ -1,48 +1,24 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $missingMessage = "The member 'ModuleVersion' is not present in the module manifest." $missingName = "PSMissingModuleManifestField" -$unloadableMessage = [regex]::Escape("Cannot load the module TestBadModule that the file TestBadModule.psd1 is in.") -$unloadableName = "PSAvoidUnloadableModule" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$violations = Invoke-ScriptAnalyzer $directory\TestBadModule\TestBadModule.psd1 -$missingViolations = $violations | Where-Object {$_.RuleName -eq $missingName} -$unloadableViolations = $violations | Where-Object {$_.RuleName -eq $unloadableName} -$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 -$noMissingViolations = $noViolations | Where-Object {$_.RuleName -eq $missingName} -$noUnloadableViolations = $noViolations | Where-Object {$_.RuleName -eq $unloadableName} - -Describe "AvoidUnloadableModule" { - Context "When there are violations" { - It "has 1 unloadable module violation" { - $unloadableViolations.Count | Should Be 1 - } - - It "has the correct description message" { - $unloadableViolations.Message | Should Match $unloadableMessage - } - } - - Context "When there are no violations" { - It "returns no violations" { - $noUnloadableViolations.Count | Should Be 0 - } - } -} +$violations = Invoke-ScriptAnalyzer $directory\TestBadModule\TestBadModule.psd1 | Where-Object {$_.RuleName -eq $missingName} +$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $missingName} Describe "MissingRequiredFieldModuleManifest" { Context "When there are violations" { It "has 1 missing required field module manifest violation" { - $missingViolations.Count | Should Be 1 + $violations.Count | Should Be 1 } It "has the correct description message" { - $missingViolations.Message | Should Match $missingMessage + $violations.Message | Should Match $missingMessage } } Context "When there are no violations" { It "returns no violations" { - $noMissingViolations.Count | Should Be 0 + $noViolations.Count | Should Be 0 } } } diff --git a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 index bab6dfe3b..e50e9fcdc 100644 --- a/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 +++ b/Tests/Rules/AvoidUserNameAndPasswordParams.tests.ps1 @@ -1,6 +1,6 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer -$violationMessage = "Function TestFunction has both username and password parameters. A credential parameter of type PSCredential should be used." +$violationMessage = "Function 'TestFunction' has both username and password parameters. A credential parameter of type PSCredential should be used." $violationName = "PSAvoidUsingUserNameAndPasswordParams" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidUserNameAndPasswordParams.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidUsingAlias.tests.ps1 b/Tests/Rules/AvoidUsingAlias.tests.ps1 index d2e45ad23..7c9d74db1 100644 --- a/Tests/Rules/AvoidUsingAlias.tests.ps1 +++ b/Tests/Rules/AvoidUsingAlias.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "iex is an alias of Invoke-Expression. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content." +Import-Module PSScriptAnalyzer +$violationMessage = "'iex' is an alias of 'Invoke-Expression'. Alias can introduce possible problems and make scripts hard to maintain. Please consider changing alias to its full content." $violationName = "PSAvoidUsingCmdletAliases" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidUsingAlias.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidUsingClearHostWriteHost.tests.ps1 b/Tests/Rules/AvoidUsingClearHostWriteHost.tests.ps1 deleted file mode 100644 index 2d3d5b323..000000000 --- a/Tests/Rules/AvoidUsingClearHostWriteHost.tests.ps1 +++ /dev/null @@ -1,50 +0,0 @@ -Import-Module ScriptAnalyzer -Set-Alias ctss ConvertTo-SecureString -$consoleWriteMessage = "File AvoidUsingClearHostWriteHost.ps1 uses Console.WriteLine. Using Console to write is not recommended because it may not work in all hosts or there may even be no hosts at all. Use Write-Output instead." -$writeHostMessage = "File AvoidUsingClearHostWriteHost.ps1 uses Write-Host. This is not recommended because it may not work in some hosts or there may even be no hosts at all. Use Write-Output instead." -$clearHostMessage = "File AvoidUsingClearHostWriteHost.ps1 uses Clear-Host. This is not recommended because it may not work in some hosts or there may even be no hosts at all." -$writeHostName = "PSAvoidUsingWriteHost" -$clearHostName = "PSAvoidUsingClearHost" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$invocation = Invoke-ScriptAnalyzer $directory\AvoidUsingClearHostWriteHost.ps1 -$clearHostViolations = $invocation | Where-Object {$_.RuleName -eq $clearHostName} -$writeHostViolations = $invocation | Where-Object {$_.RuleName -eq $writeHostName} -$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingClearHostWriteHostNoViolations.ps1 -$noClearHostViolations = $noViolations | Where-Object {$_.RuleName -eq $writeHostName} -$noWriteHostViolations = $noViolations | Where-Object {$_.RuleName -eq $clearHostName} - -Describe "AvoidUsingClearHost" { - Context "When there are violations" { - It "has 3 Clear-Host violations" { - $clearHostViolations.Count | Should Be 3 - } - - It "has the correct description message for Clear-Host" { - $clearHostViolations[0].Message | Should Match $clearHostMessage - } - } - - Context "When there are no violations" { - It "returns no violations" { - $noClearHostViolations.Count | Should Be 0 - } - } -} - -Describe "AvoidUsingWriteHost" { - Context "When there are violations" { - It "has 3 Write-Host violations" { - $writeHostViolations.Count | Should Be 3 - } - - It "has the correct description message for Write-Host" { - $writeHostViolations[0].Message | Should Match $writeHostMessage - } - } - - Context "When there are no violations" { - It "returns no violations" { - $noWriteHostViolations.Count | Should Be 0 - } - } -} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 index a4c44e29b..c651d482b 100644 --- a/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 +++ b/Tests/Rules/AvoidUsingComputerNameHardcoded.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = [regex]::Escape('The ComputerName parameter of cmdlet Invoke-Command is hardcoded. This will expose sensitive information about the system if the script is shared.') +Import-Module PSScriptAnalyzer +$violationMessage = [regex]::Escape("The ComputerName parameter of cmdlet 'Invoke-Command' is hardcoded. This will expose sensitive information about the system if the script is shared.") $violationName = "PSAvoidUsingComputerNameHardcoded" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidUsingComputerNameHardcoded.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidUsingInternalURLs.tests.ps1 b/Tests/Rules/AvoidUsingInternalURLs.tests.ps1 index 59e9d0dc3..51c090df8 100644 --- a/Tests/Rules/AvoidUsingInternalURLs.tests.ps1 +++ b/Tests/Rules/AvoidUsingInternalURLs.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "could be an internal URL. Using internal URL directly in the script may cause potential information discloure." $violationName = "PSAvoidUsingInternalURLs" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 index 63df90718..1ef064714 100644 --- a/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 +++ b/Tests/Rules/AvoidUsingInvokeExpression.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "Invoke-Expression is used. Please remove Invoke-Expression from script and find other options instead." $violationName = "PSAvoidUsingInvokeExpression" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 index ad5860f2a..2c298a7cf 100644 --- a/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 +++ b/Tests/Rules/AvoidUsingPlainTextForPassword.tests.ps1 @@ -1,6 +1,6 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer -$violationMessage = [regex]::Escape('Parameter $passphrases should use SecureString, otherwise this will expose sensitive information. See ConvertTo-SecureString for more information.') +$violationMessage = [regex]::Escape("Parameter '`$passphrases' should use SecureString, otherwise this will expose sensitive information. See ConvertTo-SecureString for more information.") $violationName = "PSAvoidUsingPlainTextForPassword" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\AvoidUsingPlainTextForPassword.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/AvoidUsingReservedCharOneCharNames.ps1 b/Tests/Rules/AvoidUsingReservedCharNames.ps1 similarity index 100% rename from Tests/Rules/AvoidUsingReservedCharOneCharNames.ps1 rename to Tests/Rules/AvoidUsingReservedCharNames.ps1 diff --git a/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 new file mode 100644 index 000000000..2b5250658 --- /dev/null +++ b/Tests/Rules/AvoidUsingReservedCharNames.tests.ps1 @@ -0,0 +1,24 @@ +Import-Module PSScriptAnalyzer +$reservedCharMessage = "The cmdlet 'Use-#Reserved' uses a reserved char in its name." +$reservedCharName = "PSReservedCmdletChar" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingReservedCharNames.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} +$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object {$_.RuleName -eq $reservedCharName} + +Describe "Avoid Using Reserved Char" { + Context "When there are violations" { + It "has 1 Reserved Char Violation" { + $violations.Count | Should Be 1 + } + + It "has the correct description message" { + $violations[0].Message | Should Match $reservedCharMessage + } + } + + Context "When there are no violations" { + It "has no violations" { + $noViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingReservedCharOneCharNames.tests.ps1 b/Tests/Rules/AvoidUsingReservedCharOneCharNames.tests.ps1 deleted file mode 100644 index 225e3df02..000000000 --- a/Tests/Rules/AvoidUsingReservedCharOneCharNames.tests.ps1 +++ /dev/null @@ -1,48 +0,0 @@ -Import-Module ScriptAnalyzer -$oneCharMessage = "The cmdlet name O only has one character." -$reservedCharMessage = "The cmdlet Use-#Reserved uses a reserved char in its name." -$oneCharName = "PSOneChar" -$reservedCharName = "PSReservedCmdletChar" -$directory = Split-Path -Parent $MyInvocation.MyCommand.Path -$invoke = Invoke-ScriptAnalyzer $directory\AvoidUsingReservedCharOneCharNames.ps1 -$oneCharViolations = $invoke | Where-Object {$_.RuleName -eq $oneCharName} -$reservedCharViolations = $invoke | Where-Object {$_.RuleName -eq $reservedCharName} -$noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 -$noOneCharViolations = $noViolations | Where-Object {$_.RuleName -eq $oneCharName} -$noReservedCharViolations = $noViolations | Where-Object {$_.RuleName -eq $reservedCharName} - -Describe "Avoid Using Reserved Char" { - Context "When there are violations" { - It "has 1 Reserved Char Violation" { - $reservedCharViolations.Count | Should Be 1 - } - - It "has the correct description message" { - $reservedCharViolations[0].Message | Should Match $reservedCharMessage - } - } - - Context "When there are no violations" { - It "has no violations" { - $noOneCharViolations.Count | Should Be 0 - } - } -} - -Describe "Avoid Using One Char" { - Context "When there are violations" { - It "has 1 One Char Violation" { - $oneCharViolations.Count | Should Be 1 - } - - It "has the correct description message" { - $oneCharViolations[0].Message | Should Match $oneCharMessage - } - } - - Context "When there are no violations" { - It "has no violations" { - $noReservedCharViolations.Count | Should Be 0 - } - } -} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingWriteHost.ps1 b/Tests/Rules/AvoidUsingWriteHost.ps1 new file mode 100644 index 000000000..b9ea56344 --- /dev/null +++ b/Tests/Rules/AvoidUsingWriteHost.ps1 @@ -0,0 +1,6 @@ +Clear-Host +cls +Write-Host "aaa" +clear +[System.Console]::Write("abcdefg"); +[System.Console]::WriteLine("No console.writeline plz!"); \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingWriteHost.tests.ps1 b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 new file mode 100644 index 000000000..f9cd926a2 --- /dev/null +++ b/Tests/Rules/AvoidUsingWriteHost.tests.ps1 @@ -0,0 +1,25 @@ +Import-Module PSScriptAnalyzer +Set-Alias ctss ConvertTo-SecureString +$writeHostMessage = [Regex]::Escape("File 'AvoidUsingWriteHost.ps1' uses Write-Host. This is not recommended because it may not work in some hosts or there may even be no hosts at all. Use Write-Output instead.") +$writeHostName = "PSAvoidUsingWriteHost" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\AvoidUsingWriteHost.ps1 | Where-Object {$_.RuleName -eq $writeHostName} +$noViolations = Invoke-ScriptAnalyzer $directory\AvoidUsingWriteHostNoViolations.ps1 | Where-Object {$_.RuleName -eq $clearHostName} + +Describe "AvoidUsingWriteHost" { + Context "When there are violations" { + It "has 3 Write-Host violations" { + $violations.Count | Should Be 3 + } + + It "has the correct description message for Write-Host" { + $violations[0].Message | Should Match $writeHostMessage + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should Be 0 + } + } +} \ No newline at end of file diff --git a/Tests/Rules/AvoidUsingWriteHostNoViolations.ps1 b/Tests/Rules/AvoidUsingWriteHostNoViolations.ps1 new file mode 100644 index 000000000..4dadd1faa --- /dev/null +++ b/Tests/Rules/AvoidUsingWriteHostNoViolations.ps1 @@ -0,0 +1 @@ +Write-Output "This is the correct way to write output" \ No newline at end of file diff --git a/Tests/Rules/BadCmdlet.ps1 b/Tests/Rules/BadCmdlet.ps1 index b93658d0b..546dc31a8 100644 --- a/Tests/Rules/BadCmdlet.ps1 +++ b/Tests/Rules/BadCmdlet.ps1 @@ -50,4 +50,17 @@ End { } -} \ No newline at end of file +} + +# Provide comment help should not be raised here because this is not exported +function NoComment +{ + Write-Verbose "No Comment" +} + +function Comment +{ + Write-Verbose "Should raise providecommenthelp error" +} + +Export-ModuleMember Verb-Files, Comment \ No newline at end of file diff --git a/Tests/Rules/PSCredentialType.tests.ps1 b/Tests/Rules/PSCredentialType.tests.ps1 index ad5047c70..50a5f083c 100644 --- a/Tests/Rules/PSCredentialType.tests.ps1 +++ b/Tests/Rules/PSCredentialType.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "The Credential parameter in Credential must be of the type PSCredential." +Import-Module PSScriptAnalyzer +$violationMessage = "The Credential parameter in 'Credential' must be of the type PSCredential." $violationName = "PSUsePSCredentialType" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\PSCredentialType.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 index 66845d94f..4ef850c55 100644 --- a/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 +++ b/Tests/Rules/PossibleIncorrectComparisonWithNull.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = [regex]::Escape('$null should be on the left side of equality comparisons.') $violationName = "PSPossibleIncorrectComparisonWithNull" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path diff --git a/Tests/Rules/ProvideCommentHelp.tests.ps1 b/Tests/Rules/ProvideCommentHelp.tests.ps1 index e6609ee25..30a183710 100644 --- a/Tests/Rules/ProvideCommentHelp.tests.ps1 +++ b/Tests/Rules/ProvideCommentHelp.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "The cmdlet Verb-Files does not have a help comment." +Import-Module PSScriptAnalyzer +$violationMessage = "The cmdlet 'Verb-Files' does not have a help comment." $violationName = "PSProvideCommentHelp" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} @@ -8,8 +8,8 @@ $noViolations = Invoke-ScriptAnalyzer $directory\GoodCmdlet.ps1 | Where-Object { Describe "ProvideCommentHelp" { Context "When there are violations" { - It "has 1 provide comment help violation" { - $violations.Count | Should Be 1 + It "has 2 provide comment help violations" { + $violations.Count | Should Be 2 } It "has the correct description message" { diff --git a/Tests/Rules/ProvideVerboseMessage.tests.ps1 b/Tests/Rules/ProvideVerboseMessage.tests.ps1 index 35cd8b409..6ae8c639c 100644 --- a/Tests/Rules/ProvideVerboseMessage.tests.ps1 +++ b/Tests/Rules/ProvideVerboseMessage.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "There is no call to Write-Verbose in the function Verb-Files." +Import-Module PSScriptAnalyzer +$violationMessage = [regex]::Escape("There is no call to Write-Verbose in the function ‘Verb-Files’.") $violationName = "PSProvideVerboseMessage" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} @@ -17,7 +17,7 @@ Describe "ProvideVerboseMessage" { } It "Does not count violation in DSC class" { - $dscViolations.Count | Should Be 1 + $dscViolations.Count | Should Be 0 } } diff --git a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.ps1 b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 similarity index 97% rename from Tests/Rules/ReturnCorrectTypesForDSCFunctions.ps1 rename to Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 index 252982c11..f45163f88 100644 --- a/Tests/Rules/ReturnCorrectTypesForDSCFunctions.ps1 +++ b/Tests/Rules/ReturnCorrectTypesForDSCFunctions.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module -Verbose ScriptAnalyzer +Import-Module -Verbose PSScriptAnalyzer $violationMessageDSCResource = "Test-TargetResource function in DSC Resource should return object of type System.Boolean instead of System.Collections.Hashtable" $violationMessageDSCClass = "Test function in DSC Class FileResource should return object of type System.Boolean instead of type System.Int32" diff --git a/Tests/Rules/UseCmdletCorrectly.tests.ps1 b/Tests/Rules/UseCmdletCorrectly.tests.ps1 index 45b20fa3b..360199c58 100644 --- a/Tests/Rules/UseCmdletCorrectly.tests.ps1 +++ b/Tests/Rules/UseCmdletCorrectly.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module -Verbose ScriptAnalyzer -$violationMessage = "Cmdlet Write-Warning may be used incorrectly. Please check that all mandatory parameters are supplied." +Import-Module -Verbose PSScriptAnalyzer +$violationMessage = "Cmdlet 'Write-Warning' may be used incorrectly. Please check that all mandatory parameters are supplied." $violationName = "PSUseCmdletCorrectly" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\UseCmdletCorrectly.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 index ae4845899..fbf791bfc 100644 --- a/Tests/Rules/UseDSCResourceFunctions.tests.ps1 +++ b/Tests/Rules/UseDSCResourceFunctions.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module -Verbose ScriptAnalyzer +Import-Module -Verbose PSScriptAnalyzer $violationMessage = "Missing 'Get-TargetResource' function. DSC Resource must implement Get, Set and Test-TargetResource functions." $classViolationMessage = "Missing 'Set' function. DSC Class must implement Get, Set and Test functions." diff --git a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 index aa43b7381..61b5b34a2 100644 --- a/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 +++ b/Tests/Rules/UseDeclaredVarsMoreThanAssignments.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "The variable declaredVar is assigned but never used." +Import-Module PSScriptAnalyzer +$violationMessage = "The variable 'declaredVar' is assigned but never used." $violationName = "PSUseDeclaredVarsMoreThanAssigments" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\UseDeclaredVarsMoreThanAssignments.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 index 08979d25b..fca63cb6e 100644 --- a/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 +++ b/Tests/Rules/UseIdenticalParametersDSC.tests.ps1 @@ -1,4 +1,4 @@ -Import-Module ScriptAnalyzer +Import-Module PSScriptAnalyzer $violationMessage = "The Test and Set-TargetResource functions of DSC Resource must have the same parameters." $violationName = "PSDSCUseIdenticalParametersForDSC" diff --git a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 index 560a68d7a..908c96d24 100644 --- a/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 +++ b/Tests/Rules/UseShouldProcessCorrectly.tests.ps1 @@ -1,5 +1,5 @@ -Import-Module ScriptAnalyzer -$violationMessage = "Verb-Files has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." +Import-Module PSScriptAnalyzer +$violationMessage = "'Verb-Files' has the ShouldProcess attribute but does not call ShouldProcess/ShouldContinue." $violationName = "PSShouldProcess" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path $violations = Invoke-ScriptAnalyzer $directory\BadCmdlet.ps1 | Where-Object {$_.RuleName -eq $violationName} diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.ps1 new file mode 100644 index 000000000..925a1b809 --- /dev/null +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.ps1 @@ -0,0 +1,11 @@ +function Get-Service +{ + param ([string]$c) +} + +function Get-MyObject{ + [CmdletBinding(SupportsShouldProcess = $false)] + param([string]$c, [int]$d) + +} + diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 new file mode 100644 index 000000000..e5998e00e --- /dev/null +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctions.tests.ps1 @@ -0,0 +1,25 @@ +Import-Module PSScriptAnalyzer +$violationMessage = "Function ’Get-Service’ has verb that could change system state. Therefore, the function has to support 'ShouldProcess'" +$violationName = "PSUseShouldProcessForStateChangingFunctions" +$violationName = "PS.UseShouldProcessForStateChangingFunctions" +$directory = Split-Path -Parent $MyInvocation.MyCommand.Path +$violations = Invoke-ScriptAnalyzer $directory\UseShouldProcessForStateChangingFunctions.ps1 | Where-Object {$_.RuleName -eq $violationName} +$noViolations = Invoke-ScriptAnalyzer $directory\UseShouldProcessForStateChangingFunctionsNoViolations.ps1 | Where-Object {$_.RuleName -eq $violationName} + +Describe "" { + Context "When there are violations" { + It "has 2 violations where ShouldProcess is not supported" { + $violations.Count | Should Be 3 + } + + It "has the correct description message" { + $violations[0].Message | Should Match $violationMessage + } + } + + Context "When there are no violations" { + It "returns no violations" { + $noViolations.Count | Should Be 0 + } + } +} diff --git a/Tests/Rules/UseShouldProcessForStateChangingFunctionsNoViolations.ps1 b/Tests/Rules/UseShouldProcessForStateChangingFunctionsNoViolations.ps1 new file mode 100644 index 000000000..cb4b2cfc9 --- /dev/null +++ b/Tests/Rules/UseShouldProcessForStateChangingFunctionsNoViolations.ps1 @@ -0,0 +1,12 @@ +function Get-Service +{ + [CmdletBinding(SupportShouldSuppress= $false)] + param ([string]$c) +} + +function Test-GetMyObject{ + + param([string]$c, [int]$d) + +} + diff --git a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 index 9f146885b..bd1e49259 100644 --- a/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 +++ b/Tests/Rules/UseSingularNounsReservedVerbs.tests.ps1 @@ -1,6 +1,6 @@ -Import-Module ScriptAnalyzer -$nounViolationMessage = "The cmdlet Verb-Files uses a plural noun. A singular noun should be used instead." -$verbViolationMessage = "The cmdlet Verb-Files uses an unapproved verb." +Import-Module PSScriptAnalyzer +$nounViolationMessage = "The cmdlet 'Verb-Files' uses a plural noun. A singular noun should be used instead." +$verbViolationMessage = "The cmdlet 'Verb-Files' uses an unapproved verb." $nounViolationName = "PSUseSingularNouns" $verbViolationName = "PSUseApprovedVerbs" $directory = Split-Path -Parent $MyInvocation.MyCommand.Path