Skip to content

Commit 3e24e3d

Browse files
committed
Merge pull request #1 from PowerShell/development
Re merge into my branch
2 parents bf30234 + 6b51b94 commit 3e24e3d

File tree

132 files changed

+4623
-1140
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+4623
-1140
lines changed

CHANGELOG.MD

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,76 @@
1+
## Released v1.4.0 (Feb.16, 2016)
2+
###Features:
3+
- IncludeRule and ExcludeRule now consume RuleInfo objects
4+
5+
###Rules:
6+
- Rule to validate HelpMessage parameter attribute value
7+
- Rule to suggest module manifest *ToExport field values for optimizing module loading
8+
9+
###Fixes:
10+
####Engine:
11+
- Fixed bug in engine handling of severity for custom rules - this property was being ignored
12+
- Exclude help files from being Ast parsed
13+
14+
####Rules:
15+
- Emit accurate ast extents for rules - helps VSCode-PowerShell to mark violations better
16+
- Improved heuristics for Singular noun rule - reduce false positives
17+
- Updated credential rules to be less noisy based on community feedback
18+
- Support for [switch] type along with [boolean] for ShouldContinueWithoutForce rule
19+
- Improved handling of deprecated module manifest fields when PSv2.0 is specified in the manifest
20+
21+
## Released v1.3.0 (Jan.19, 2016)
22+
###Features:
23+
- Support for running ScriptAnalyzer on PowerShell version v3 or higher! This means PSv5 is no longer the minimum PS version for ScriptAnalyzer
24+
25+
###Rules:
26+
- [From Community] Rule for warning about backticks that look like line-continuations but are not [MisleadingBacktick rule]
27+
- Ability in default ruleset to recognize PowerShell variable scopes - global, local, script, private
28+
- Ability to use functions as a variable and support for special type of functions like prompt
29+
30+
###Fixes:
31+
####Rules:
32+
- Fix for recognizing PowerShell preference variable ($OFS) in the default ruleset
33+
- Fix for false positive - PSShouldProcess rule requires boolean value
34+
- Fix to account for function scope prefix
35+
- Raise ReservedParam rule only for exported functions as cmdlets
36+
37+
## Released v1.2.0 (Dec.17, 2015)
38+
###Features:
39+
- Support for consuming PowerShell content as streams (-ScriptDefinition)
40+
- ScriptAnalyzer accepts configuration (settings) in the form of a hashtable (-Settings), added sample Settings
41+
- Ability to run default ruleset along with custom ones in the same invocation (-IncludeDefaultRules)
42+
- Recurse Custom Rule Paths (-RecurseCustomRulePath)
43+
- Consistent Engine error handling when working with Settings, Default and Custom Rules
44+
45+
###Rules:
46+
- Rule to detect the presence of default value for Mandatory parameters (AvoidDefaultValueForMandatoryParameter)
47+
48+
###Fixes:
49+
####Engine:
50+
- Engine update to prevent script based injection attacks
51+
- CustomizedRulePath is now called CustomRulePath – Fixes to handle folder paths
52+
- Fixes for RecurseCustomRulePath functionality
53+
- Fix to binplace cmdlet help file as part of build process
54+
- ScriptAnalyzer Profile is now called Settings
55+
- Fix to emit filename in the diagnosticrecord when using Script based custom rules
56+
- Fix to prevent Engine from calling Update-Help for script based custom rules
57+
- Added additional pester tests to take care of test holes in Custom Rule feature
58+
- Post-build error handling improvements, fixed typos in the project
59+
60+
####Rules:
61+
- Fixed bug in Positional parameter rule to trigger only when used with >= 3 positional parameters
62+
- Updated keywords that trigger PSAvoidUsingPlainTextForPassword rule
63+
- Updated ProvideDefaultParameterValue rule to AvoidDefaultValueForMandatoryParameter rule
64+
- Deprecate Internal Url rule based on community feedback, identified additional rules to handle hardcoded paths etc
65+
- Added localhost exceptions for HardCodedComputerName Rule
66+
- Update to Credential based rules to validate the presence of CredentialAttribute and PSCredential type
67+
68+
###Documentation:
69+
- Rule & Cmdlet documentation updates – Cmdlet help file addition
70+
71+
72+
##
73+
174
## Released v1.1.1 (Nov.3, 2015)
275
###Features:
376
- Support for PSDrives when using Invoke-ScriptAnalyzer
File renamed without changes.

Engine/Commands/GetScriptAnalyzerRuleCommand.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ public class GetScriptAnalyzerRuleCommand : PSCmdlet, IOutputWriter
3434
[ValidateNotNullOrEmpty]
3535
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
3636
[Alias("CustomizedRulePath")]
37-
public string CustomRulePath
37+
public string[] CustomRulePath
3838
{
3939
get { return customRulePath; }
4040
set { customRulePath = value; }
4141
}
42-
private string customRulePath;
42+
private string[] customRulePath;
4343

4444
/// <summary>
4545
/// RecurseCustomRulePath: Find rules within subfolders under the path
@@ -91,7 +91,7 @@ protected override void BeginProcessing()
9191
{
9292
string[] rulePaths = Helper.ProcessCustomRulePaths(customRulePath,
9393
this.SessionState, recurseCustomRulePath);
94-
ScriptAnalyzer.Instance.Initialize(this, rulePaths);
94+
ScriptAnalyzer.Instance.Initialize(this, rulePaths, null, null, null, null == rulePaths ? true : false);
9595
}
9696

9797
/// <summary>

Engine/Commands/InvokeScriptAnalyzerCommand.cs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public class InvokeScriptAnalyzerCommand : PSCmdlet, IOutputWriter
4343
/// </summary>
4444
[Parameter(Position = 0,
4545
ParameterSetName = "File",
46-
Mandatory = true)]
46+
Mandatory = true,
47+
ValueFromPipeline = true,
48+
ValueFromPipelineByPropertyName = true)]
4749
[ValidateNotNull]
4850
[Alias("PSPath")]
4951
public string Path
@@ -58,7 +60,9 @@ public string Path
5860
/// </summary>
5961
[Parameter(Position = 0,
6062
ParameterSetName = "ScriptDefinition",
61-
Mandatory = true)]
63+
Mandatory = true,
64+
ValueFromPipeline = true,
65+
ValueFromPipelineByPropertyName = true)]
6266
[ValidateNotNull]
6367
public string ScriptDefinition
6468
{
@@ -74,12 +78,12 @@ public string ScriptDefinition
7478
[ValidateNotNull]
7579
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
7680
[Alias("CustomizedRulePath")]
77-
public string CustomRulePath
81+
public string[] CustomRulePath
7882
{
7983
get { return customRulePath; }
8084
set { customRulePath = value; }
8185
}
82-
private string customRulePath;
86+
private string[] customRulePath;
8387

8488
/// <summary>
8589
/// RecurseCustomRulePath: Find rules within subfolders under the path
@@ -93,6 +97,18 @@ public SwitchParameter RecurseCustomRulePath
9397
}
9498
private bool recurseCustomRulePath;
9599

100+
/// <summary>
101+
/// IncludeDefaultRules: Invoke default rules along with Custom rules
102+
/// </summary>
103+
[Parameter(Mandatory = false)]
104+
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
105+
public SwitchParameter IncludeDefaultRules
106+
{
107+
get { return includeDefaultRules; }
108+
set { includeDefaultRules = value; }
109+
}
110+
private bool includeDefaultRules;
111+
96112
/// <summary>
97113
/// ExcludeRule: Array of names of rules to be disabled.
98114
/// </summary>
@@ -157,17 +173,20 @@ public SwitchParameter SuppressedOnly
157173
private bool suppressedOnly;
158174

159175
/// <summary>
160-
/// Returns path to the file that contains user profile for ScriptAnalyzer
176+
/// Returns path to the file that contains user profile or hash table for ScriptAnalyzer
161177
/// </summary>
162178
[Alias("Profile")]
163179
[Parameter(Mandatory = false)]
164180
[ValidateNotNull]
165-
public string Configuration
181+
public object Settings
166182
{
167-
get { return configuration; }
168-
set { configuration = value; }
183+
get { return settings; }
184+
set { settings = value; }
169185
}
170-
private string configuration;
186+
187+
private object settings;
188+
189+
private bool stopProcessing;
171190

172191
#endregion Parameters
173192

@@ -181,21 +200,33 @@ protected override void BeginProcessing()
181200
string[] rulePaths = Helper.ProcessCustomRulePaths(customRulePath,
182201
this.SessionState, recurseCustomRulePath);
183202

203+
if (!ScriptAnalyzer.Instance.ParseProfile(this.settings, this.SessionState.Path, this))
204+
{
205+
stopProcessing = true;
206+
return;
207+
}
208+
184209
ScriptAnalyzer.Instance.Initialize(
185210
this,
186211
rulePaths,
187212
this.includeRule,
188213
this.excludeRule,
189214
this.severity,
190-
this.suppressedOnly,
191-
this.configuration);
215+
null == rulePaths ? true : this.includeDefaultRules,
216+
this.suppressedOnly);
192217
}
193218

194219
/// <summary>
195220
/// Analyzes the given script/directory.
196221
/// </summary>
197222
protected override void ProcessRecord()
198223
{
224+
if (stopProcessing)
225+
{
226+
stopProcessing = false;
227+
return;
228+
}
229+
199230
if (String.Equals(this.ParameterSetName, "File", StringComparison.OrdinalIgnoreCase))
200231
{
201232
// throws Item Not Found Exception
@@ -211,6 +242,18 @@ protected override void ProcessRecord()
211242
}
212243
}
213244

245+
protected override void EndProcessing()
246+
{
247+
ScriptAnalyzer.Instance.CleanUp();
248+
base.EndProcessing();
249+
}
250+
251+
protected override void StopProcessing()
252+
{
253+
ScriptAnalyzer.Instance.CleanUp();
254+
base.StopProcessing();
255+
}
256+
214257
#endregion
215258

216259
#region Methods

Engine/Generic/AvoidCmdletGeneric.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
2424
public abstract class AvoidCmdletGeneric : IScriptRule
2525
{
2626
/// <summary>
27-
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
27+
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
2828
/// </summary>
2929
/// <param name="ast">The script's ast</param>
3030
/// <param name="fileName">The name of the script file being analyzed</param>
@@ -38,14 +38,14 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
3838

3939
List<String> cmdletNameAndAliases = Microsoft.Windows.PowerShell.ScriptAnalyzer.Helper.Instance.CmdletNameAndAliases(GetCmdletName());
4040

41-
// Iterrates all CommandAsts and check the command name.
41+
// Iterates all CommandAsts and check the command name.
4242
foreach (CommandAst cmdAst in commandAsts)
4343
{
4444
if (cmdAst.GetCommandName() == null) continue;
4545

4646
if (cmdletNameAndAliases.Contains(cmdAst.GetCommandName(), StringComparer.OrdinalIgnoreCase))
4747
{
48-
yield return new DiagnosticRecord(GetError(fileName), cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
48+
yield return new DiagnosticRecord(GetError(fileName), cmdAst.Extent, GetName(), GetDiagnosticSeverity(), fileName);
4949
}
5050
}
5151
}
@@ -97,5 +97,11 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
9797
/// </summary>
9898
/// <returns></returns>
9999
public abstract RuleSeverity GetSeverity();
100+
101+
/// <summary>
102+
/// DiagnosticSeverity: Returns the severity of the rule of type DiagnosticSeverity
103+
/// </summary>
104+
/// <returns></returns>
105+
public abstract DiagnosticSeverity GetDiagnosticSeverity();
100106
}
101107
}

Engine/Generic/AvoidParameterGeneric.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
2323
public abstract class AvoidParameterGeneric : IScriptRule
2424
{
2525
/// <summary>
26-
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
26+
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
2727
/// </summary>
2828
/// <param name="ast">The script's ast</param>
2929
/// <param name="fileName">The name of the script file being analyzed</param>
@@ -35,7 +35,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
3535
// Finds all CommandAsts.
3636
IEnumerable<Ast> commandAsts = ast.FindAll(testAst => testAst is CommandAst, true);
3737

38-
// Iterrates all CommandAsts and check the condition.
38+
// Iterates all CommandAsts and check the condition.
3939
foreach (CommandAst cmdAst in commandAsts)
4040
{
4141
if (CommandCondition(cmdAst) && cmdAst.CommandElements != null)
@@ -44,7 +44,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
4444
{
4545
if (ParameterCondition(cmdAst, ceAst))
4646
{
47-
yield return new DiagnosticRecord(GetError(fileName, cmdAst), cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, cmdAst.GetCommandName());
47+
yield return new DiagnosticRecord(GetError(fileName, cmdAst), cmdAst.Extent, GetName(), GetDiagnosticSeverity(), fileName, cmdAst.GetCommandName());
4848
}
4949
}
5050
}
@@ -102,6 +102,16 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
102102
/// <returns>The source type of the rule.</returns>
103103
public abstract SourceType GetSourceType();
104104

105+
/// <summary>
106+
/// RuleSeverity: Returns the severity of the rule.
107+
/// </summary>
108+
/// <returns></returns>
105109
public abstract RuleSeverity GetSeverity();
110+
111+
/// <summary>
112+
/// DiagnosticSeverity: Returns the severity of the rule of type DiagnosticSeverity
113+
/// </summary>
114+
/// <returns></returns>
115+
public abstract DiagnosticSeverity GetDiagnosticSeverity();
106116
}
107117
}

Engine/Generic/IDSCResourceRule.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@ public interface IDSCResourceRule : IRule
2828
/// <returns>The results of the analysis</returns>
2929
IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName);
3030

31+
#if !PSV3
32+
3133
/// <summary>
3234
/// Analyze dsc classes (if any) in the file
3335
/// </summary>
3436
/// <param name="ast"></param>
3537
/// <param name="fileName"></param>
3638
/// <returns></returns>
3739
IEnumerable<DiagnosticRecord> AnalyzeDSCClass(Ast ast, string fileName);
38-
40+
41+
#endif
42+
3943
}
4044
}

Engine/Generic/ILogger.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface ILogger
3434
string GetName();
3535

3636
/// <summary>
37-
/// GetDescription: Retrives the description of the logger.
37+
/// GetDescription: Retrieves the description of the logger.
3838
/// </summary>
3939
/// <returns>The description of the logger</returns>
4040
string GetDescription();

Engine/Generic/IScriptRule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
2525
public interface IScriptRule : IRule
2626
{
2727
/// <summary>
28-
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
28+
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
2929
/// </summary>
3030
/// <param name="ast">The script's ast</param>
3131
/// <param name="fileName">The name of the script file being analyzed</param>

Engine/Generic/RuleInfo.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ public RuleInfo(string name, string commonName, string description, SourceType s
102102
Description = description;
103103
SourceType = sourceType;
104104
SourceName = sourceName;
105-
Severity = severity;
105+
Severity = severity;
106106
}
107+
108+
public override string ToString()
109+
{
110+
return RuleName;
111+
}
107112
}
108113
}

Engine/Generic/RuleSuppression.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,14 @@ public static List<RuleSuppression> GetSuppressions(IEnumerable<AttributeAst> at
367367
targetAsts = scopeAst.FindAll(item => item is FunctionDefinitionAst && reg.IsMatch((item as FunctionDefinitionAst).Name), true);
368368
goto default;
369369

370+
#if !PSV3
371+
370372
case "class":
371373
targetAsts = scopeAst.FindAll(item => item is TypeDefinitionAst && reg.IsMatch((item as TypeDefinitionAst).Name), true);
372374
goto default;
373375

376+
#endif
377+
374378
default:
375379
break;
376380
}

Engine/Generic/SourceType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public enum SourceType : uint
2323
Builtin = 0,
2424

2525
/// <summary>
26-
/// MANAGED: Indicates the script analyzer rule is contirbuted as a managed rule.
26+
/// MANAGED: Indicates the script analyzer rule is contributed as a managed rule.
2727
/// </summary>
2828
Managed = 1,
2929

0 commit comments

Comments
 (0)