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