Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
8e6bf17
Edited WriteHost rule strings.
juneb Nov 6, 2015
06d4972
Merge pull request #349 from juneb/development
raghushantha Nov 6, 2015
26dcceb
Update message in Test case for WriteHost Rule
raghushantha Nov 6, 2015
7ef6ce7
Update README.md
raghushantha Nov 9, 2015
8e3a0cd
Updated Engine to use AddCommand to prevent Script Based injection at…
raghushantha Nov 10, 2015
4454618
Check for null Description Property in the returned help content
raghushantha Nov 10, 2015
3929d66
Merge pull request #353 from PowerShell/AddScriptBugFixBranch
raghushantha Nov 10, 2015
5866510
Initial commit for ScriptDefinition
Nov 12, 2015
5701167
First draft of cmdlet help file
juneb Nov 12, 2015
006d957
Fix test failures
Nov 12, 2015
251436f
Merge pull request #357 from PowerShell/ScriptDefinition
Nov 12, 2015
c5ae0db
Merge pull request #359 from juneb/development
raghushantha Nov 13, 2015
c48f74b
Update README.md
raghushantha Nov 18, 2015
d28f8cc
Renames CustomizedRulePath parameter and modifies its behavior.
Nov 18, 2015
36bd577
Fixes a bug in library usage test cmdlet
Nov 21, 2015
900de11
Modifies library usage test cmdlet.
Nov 21, 2015
25ba9bd
Fixes customRulePath parameter in library test
Nov 21, 2015
50ea056
Adds profile parameter to the cmdlet in library tests
Nov 21, 2015
dbe3143
Creates a workaround the failing tests.
Nov 21, 2015
48e2535
Merge pull request #365 from PowerShell/FixCustomizedRulePathTrailing…
Nov 23, 2015
91b61bd
Bug Fixes when using Recurse functionality. Fix to Binplace cmdlet he…
raghushantha Nov 24, 2015
dc6c18f
Give profile alias configuration and provide some sample configurations
Nov 24, 2015
25bbd2d
Fix to emit Filename when using Script Based Rules
raghushantha Nov 24, 2015
99e4c5e
Reintroduced warnigns on issues with Composition
raghushantha Nov 24, 2015
e305f8e
Merge pull request #368 from PowerShell/CustomRulePathFixBranch
raghushantha Nov 24, 2015
f09842a
Merge pull request #369 from PowerShell/AddExampleConfiguration
Nov 24, 2015
bb5ee27
Switch profile and configuration
Nov 24, 2015
b09da3c
Merge pull request #370 from PowerShell/SwitchProfileAndConfiguration
Nov 24, 2015
d650bcd
Customize/CustomRulePath, RecurseCustomRulePath, ScriptDefinition
juneb Nov 25, 2015
02dad54
Fix for #371
kilasuit Nov 25, 2015
9b4cc93
Merge pull request #373 from juneb/development
raghushantha Nov 25, 2015
bf30234
Updated Pester test that I forgot in last commit
kilasuit Nov 25, 2015
b5c991b
Merge pull request #374 from kilasuit/development
raghushantha Nov 25, 2015
ef6d8a6
Change Provide Default Parameter Value to Avoid Default Value For Man…
Nov 25, 2015
da45614
Fix test failures
Nov 25, 2015
e406f26
Merge pull request #382 from PowerShell/ProvideDefaultValueForMandato…
Nov 25, 2015
80b788a
Script Analyzer shouldn't automatically update help for modules
raghushantha Nov 30, 2015
028af94
Added Warning + updated failing tests
raghushantha Dec 1, 2015
bc3cdb0
Cleaned up more warnings in tests
raghushantha Dec 1, 2015
466b04c
Fixed Syntax issue in the test script
raghushantha Dec 1, 2015
1c36127
Merge pull request #384 from PowerShell/UpdateHelpFixBranch
raghushantha Dec 1, 2015
a1b4528
Deprecate Internal Url Rule
raghushantha Dec 1, 2015
07ae095
Fix failing test
raghushantha Dec 1, 2015
3b3f0ed
Merge pull request #389 from PowerShell/DeprecateInternalUrlRuleBranch
raghushantha Dec 1, 2015
be025c8
Added localhost exceptions for HardCodedComputerName Rule
raghushantha Dec 1, 2015
86b936f
Fixed issues in the original rule, added more testing
raghushantha Dec 2, 2015
f880cf1
Add an extra check for CredentialAttribute for the credential rules
Dec 2, 2015
21269c8
Change logic to check for both CredentialAttribute and PSCredential type
Dec 2, 2015
7b1a13a
Merge pull request #391 from PowerShell/AddCredentialAttributeCheck
Dec 2, 2015
710b43b
Merge pull request #390 from PowerShell/HardCodedComputerNameRuleFixB…
raghushantha Dec 2, 2015
f258a87
Throw error instead of warning for profiles
Dec 2, 2015
ac11a2d
Change remaining warning to error
Dec 2, 2015
cbf5b07
Merge pull request #392 from PowerShell/ThrowErrorInsteadOfWarningFor…
Dec 2, 2015
dfb70f6
Exclude Default RuleSet when using with CustomRule feature
raghushantha Dec 3, 2015
c279303
Merge pull request #393 from PowerShell/ProfileFixBranch
raghushantha Dec 3, 2015
03beec1
Enforce that pscredential attribute must come before credentialattribute
Dec 3, 2015
07f1f2b
Merge pull request #394 from PowerShell/FixCredentialBug
Dec 3, 2015
efdfba9
Improve post-build command, fix spelling mistakes.
Dec 9, 2015
3735e37
Fix post-build in both csproj files.
Dec 9, 2015
e284305
Merge pull request #399 from korygill/development
raghushantha Dec 14, 2015
84e7b43
Add ability to supply collection of custom rule paths
raghushantha Dec 14, 2015
0e111e4
Debug failing test
raghushantha Dec 14, 2015
3ba1596
Updates to Test
raghushantha Dec 14, 2015
a748d20
Merge pull request #402 from PowerShell/CustomRulePathFixBranch
raghushantha Dec 14, 2015
d849e11
Add a new switch parameter to run default rules along with custom ones
raghushantha Dec 15, 2015
23b22e7
Added Test cases, plugged Test Holes
raghushantha Dec 15, 2015
aa40394
Fix failing tests
raghushantha Dec 15, 2015
00e3be3
Merge pull request #403 from PowerShell/IncludeDefaultRulesBranch
raghushantha Dec 15, 2015
c39b041
Update PSScriptAnalyzer.psd1
raghushantha Dec 15, 2015
84079a9
Allow scriptanalyzer to accept configuration in the form of a hashtable
Dec 15, 2015
53bc3ff
Fix merged conflict that caused test failures
Dec 15, 2015
0cf22a1
Change configuration to settings
Dec 16, 2015
42472a0
Merge pull request #404 from PowerShell/HashtableConfiguration
Dec 16, 2015
40538cb
Update CHANGELOG.MD
raghushantha Dec 16, 2015
51f9d93
Update appveyor.yml
raghushantha Dec 16, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,40 @@
## Released v1.2.0 (Dec.17, 2015)
###Features:
- Support for consuming PowerShell content as streams (-ScriptDefinition)
- ScriptAnalyzer accepts configuration (settings) in the form of a hashtable (-Settings), added sample Settings
- Ability to run default ruleset along with custom ones in the same invocation (-IncludeDefaultRules)
- Recurse Custom Rule Paths (-RecurseCustomRulePath)
- Consistent Engine error handling when working with Settings, Default and Custom Rules

###Rules:
- Rule to detect the presence of default value for Mandatory parameters (AvoidDefaultValueForMandatoryParameter)

###Fixes:
####Engine:
- Engine update to prevent script based injection attacks
- CustomizedRulePath is now called CustomRulePath – Fixes to handle folder paths
- Fixes for RecurseCustomRulePath functionality
- Fix to binplace cmdlet help file as part of build process
- ScriptAnalyzer Profile is now called Settings
- Fix to emit filename in the diagnosticrecord when using Script based custom rules
- Fix to prevent Engine from calling Update-Help for script based custom rules
- Added additional pester tests to take care of test holes in Custom Rule feature
- Post-build error handling improvements, fixed typos in the project

####Rules:
- Fixed bug in Positional parameter rule to trigger only when used with > 3 positional parameters
- Updated keywords that trigger PSAvoidUsingPlainTextForPassword rule
- Updated ProvideDefaultParameterValue rule to AvoidDefaultValueForMandatoryParameter rule
- Deprecate Internal Url rule based on community feedback, identified additional rules to handle hardcoded paths etc
- Added localhost exceptions for HardCodedComputerName Rule
- Update to Credential based rules to validate the presence of CredentialAttribute and PSCredential type

###Documentation:
- Rule & Cmdlet documentation updates – Cmdlet help file addition


##

## Released v1.1.1 (Nov.3, 2015)
###Features:
- Support for PSDrives when using Invoke-ScriptAnalyzer
Expand Down
25 changes: 20 additions & 5 deletions Engine/Commands/GetScriptAnalyzerRuleCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,25 @@ public class GetScriptAnalyzerRuleCommand : PSCmdlet, IOutputWriter
[Parameter(Mandatory = false)]
[ValidateNotNullOrEmpty]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] CustomizedRulePath
[Alias("CustomizedRulePath")]
public string[] CustomRulePath
{
get { return customizedRulePath; }
set { customizedRulePath = value; }
get { return customRulePath; }
set { customRulePath = value; }
}
private string[] customizedRulePath;
private string[] customRulePath;

/// <summary>
/// RecurseCustomRulePath: Find rules within subfolders under the path
/// </summary>
[Parameter(Mandatory = false)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public SwitchParameter RecurseCustomRulePath
{
get { return recurseCustomRulePath; }
set { recurseCustomRulePath = value; }
}
private bool recurseCustomRulePath;

/// <summary>
/// Name: The name of a specific rule to list.
Expand Down Expand Up @@ -76,7 +89,9 @@ public string[] Severity
/// </summary>
protected override void BeginProcessing()
{
ScriptAnalyzer.Instance.Initialize(this, customizedRulePath);
string[] rulePaths = Helper.ProcessCustomRulePaths(customRulePath,
this.SessionState, recurseCustomRulePath);
ScriptAnalyzer.Instance.Initialize(this, rulePaths, null, null, null, null == rulePaths ? true : false);
}

/// <summary>
Expand Down
132 changes: 111 additions & 21 deletions Engine/Commands/InvokeScriptAnalyzerCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Commands
/// <summary>
/// InvokeScriptAnalyzerCommand: Cmdlet to statically check PowerShell scripts.
/// </summary>
[Cmdlet(VerbsLifecycle.Invoke, "ScriptAnalyzer", HelpUri = "http://go.microsoft.com/fwlink/?LinkId=525914")]
[Cmdlet(VerbsLifecycle.Invoke,
"ScriptAnalyzer",
DefaultParameterSetName="File",
HelpUri = "http://go.microsoft.com/fwlink/?LinkId=525914")]
public class InvokeScriptAnalyzerCommand : PSCmdlet, IOutputWriter
{
#region Parameters
/// <summary>
/// Path: The path to the file or folder to invoke PSScriptAnalyzer on.
/// </summary>
[Parameter(Position = 0, Mandatory = true)]
[Parameter(Position = 0,
ParameterSetName = "File",
Mandatory = true)]
[ValidateNotNull]
[Alias("PSPath")]
public string Path
Expand All @@ -48,18 +53,57 @@ public string Path
}
private string path;

/// <summary>
/// ScriptDefinition: a script definition in the form of a string to run rules on.
/// </summary>
[Parameter(Position = 0,
ParameterSetName = "ScriptDefinition",
Mandatory = true)]
[ValidateNotNull]
public string ScriptDefinition
{
get { return scriptDefinition; }
set { scriptDefinition = value; }
}
private string scriptDefinition;

/// <summary>
/// CustomRulePath: The path to the file containing custom rules to run.
/// </summary>
[Parameter(Mandatory = false)]
[ValidateNotNull]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] CustomizedRulePath
[Alias("CustomizedRulePath")]
public string[] CustomRulePath
{
get { return customRulePath; }
set { customRulePath = value; }
}
private string[] customRulePath;

/// <summary>
/// RecurseCustomRulePath: Find rules within subfolders under the path
/// </summary>
[Parameter(Mandatory = false)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public SwitchParameter RecurseCustomRulePath
{
get { return customizedRulePath; }
set { customizedRulePath = value; }
get { return recurseCustomRulePath; }
set { recurseCustomRulePath = value; }
}
private string[] customizedRulePath;
private bool recurseCustomRulePath;

/// <summary>
/// IncludeDefaultRules: Invoke default rules along with Custom rules
/// </summary>
[Parameter(Mandatory = false)]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public SwitchParameter IncludeDefaultRules
{
get { return includeDefaultRules; }
set { includeDefaultRules = value; }
}
private bool includeDefaultRules;

/// <summary>
/// ExcludeRule: Array of names of rules to be disabled.
Expand Down Expand Up @@ -125,16 +169,20 @@ public SwitchParameter SuppressedOnly
private bool suppressedOnly;

/// <summary>
/// Returns path to the file that contains user profile for ScriptAnalyzer
/// Returns path to the file that contains user profile or hash table for ScriptAnalyzer
/// </summary>
[Alias("Profile")]
[Parameter(Mandatory = false)]
[ValidateNotNull]
public string Profile
public object Settings
{
get { return profile; }
set { profile = value; }
get { return settings; }
set { settings = value; }
}
private string profile;

private object settings;

private bool stopProcessing;

#endregion Parameters

Expand All @@ -145,37 +193,79 @@ public string Profile
/// </summary>
protected override void BeginProcessing()
{
string[] rulePaths = Helper.ProcessCustomRulePaths(customRulePath,
this.SessionState, recurseCustomRulePath);

if (!ScriptAnalyzer.Instance.ParseProfile(this.settings, this.SessionState.Path, this))
{
stopProcessing = true;
return;
}

ScriptAnalyzer.Instance.Initialize(
this,
customizedRulePath,
rulePaths,
this.includeRule,
this.excludeRule,
this.severity,
this.suppressedOnly,
this.profile);
null == rulePaths ? true : this.includeDefaultRules,
this.suppressedOnly);
}

/// <summary>
/// Analyzes the given script/directory.
/// </summary>
protected override void ProcessRecord()
{
// throws Item Not Found Exception
Collection<PathInfo> paths = this.SessionState.Path.GetResolvedPSPathFromPSPath(path);
foreach (PathInfo p in paths)
if (stopProcessing)
{
stopProcessing = false;
return;
}

if (String.Equals(this.ParameterSetName, "File", StringComparison.OrdinalIgnoreCase))
{
// throws Item Not Found Exception
Collection<PathInfo> paths = this.SessionState.Path.GetResolvedPSPathFromPSPath(path);
foreach (PathInfo p in paths)
{
ProcessPathOrScriptDefinition(this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(p.Path));
}
}
else if (String.Equals(this.ParameterSetName, "ScriptDefinition", StringComparison.OrdinalIgnoreCase))
{
ProcessPath(this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(p.Path));
ProcessPathOrScriptDefinition(scriptDefinition);
}
}

protected override void EndProcessing()
{
ScriptAnalyzer.Instance.CleanUp();
base.EndProcessing();
}

protected override void StopProcessing()
{
ScriptAnalyzer.Instance.CleanUp();
base.StopProcessing();
}

#endregion

#region Methods

private void ProcessPath(string path)
private void ProcessPathOrScriptDefinition(string pathOrScriptDefinition)
{
IEnumerable<DiagnosticRecord> diagnosticsList =
ScriptAnalyzer.Instance.AnalyzePath(path, this.recurse);
IEnumerable<DiagnosticRecord> diagnosticsList = Enumerable.Empty<DiagnosticRecord>();

if (String.Equals(this.ParameterSetName, "File", StringComparison.OrdinalIgnoreCase))
{
diagnosticsList = ScriptAnalyzer.Instance.AnalyzePath(pathOrScriptDefinition, this.recurse);
}
else if (String.Equals(this.ParameterSetName, "ScriptDefinition", StringComparison.OrdinalIgnoreCase))
{
diagnosticsList = ScriptAnalyzer.Instance.AnalyzeScriptDefinition(pathOrScriptDefinition);
}

//Output through loggers
foreach (ILogger logger in ScriptAnalyzer.Instance.Loggers)
Expand Down
10 changes: 10 additions & 0 deletions Engine/Configurations/CmdletDesign.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@{
IncludeRules=@('PSUseApprovedVerbs',
'PSReservedCmdletChar',
'PSReservedParams',
'PSShouldProcess',
'PSUseShouldProcessForStateChangingFunctions',
'PSUseSingularNouns',
'PSMissingModuleManifestField',
'PSAvoidDefaultValueSwitchParameter')
}
3 changes: 3 additions & 0 deletions Engine/Configurations/DSC.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@{
IncludeRules=@('PSDSC*')
}
11 changes: 11 additions & 0 deletions Engine/Configurations/ScriptFunctions.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@{
IncludeRules=@('PSAvoidUsingCmdletAliases',
'PSAvoidUsingWMICmdlet',
'PSAvoidUsingEmptyCatchBlock',
'PSUseCmdletCorrectly',
'PSUseShouldProcessForStateChangingFunctions',
'PSAvoidUsingPositionalParameters',
'PSAvoidGlobalVars',
'PSUseDeclaredVarsMoreThanAssignments',
'PSAvoidUsingInvokeExpression')
}
8 changes: 8 additions & 0 deletions Engine/Configurations/ScriptSecurity.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@{
IncludeRules=@('PSAvoidUsingPlainTextForPassword',
'PSAvoidUsingComputerNameHardcoded',
'PSAvoidUsingConvertToSecureStringWithPlainText',
'PSUsePSCredentialType',
'PSAvoidUsingUserNameAndPasswordParams',
'PSAvoidUsingFilePath')
}
4 changes: 4 additions & 0 deletions Engine/Configurations/ScriptingStyle.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@{
IncludeRules=@('PSProvideCommentHelp',
'PSAvoidUsingWriteHost')
}
4 changes: 2 additions & 2 deletions Engine/Generic/AvoidCmdletGeneric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
public abstract class AvoidCmdletGeneric : IScriptRule
{
/// <summary>
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
/// </summary>
/// <param name="ast">The script's ast</param>
/// <param name="fileName">The name of the script file being analyzed</param>
Expand All @@ -38,7 +38,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)

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

// Iterrates all CommandAsts and check the command name.
// Iterates all CommandAsts and check the command name.
foreach (CommandAst cmdAst in commandAsts)
{
if (cmdAst.GetCommandName() == null) continue;
Expand Down
4 changes: 2 additions & 2 deletions Engine/Generic/AvoidParameterGeneric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
public abstract class AvoidParameterGeneric : IScriptRule
{
/// <summary>
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
/// </summary>
/// <param name="ast">The script's ast</param>
/// <param name="fileName">The name of the script file being analyzed</param>
Expand All @@ -35,7 +35,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
// Finds all CommandAsts.
IEnumerable<Ast> commandAsts = ast.FindAll(testAst => testAst is CommandAst, true);

// Iterrates all CommandAsts and check the condition.
// Iterates all CommandAsts and check the condition.
foreach (CommandAst cmdAst in commandAsts)
{
if (CommandCondition(cmdAst) && cmdAst.CommandElements != null)
Expand Down
11 changes: 10 additions & 1 deletion Engine/Generic/DiagnosticRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,16 @@ public string ScriptName
{
get { return scriptName; }
//Trim down to the leaf element of the filePath and pass it to Diagnostic Record
set { scriptName = System.IO.Path.GetFileName(value); }
set {
if (!string.IsNullOrWhiteSpace(value))
{
scriptName = System.IO.Path.GetFileName(value);
}
else
{
scriptName = string.Empty;
}
}
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Engine/Generic/ILogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface ILogger
string GetName();

/// <summary>
/// GetDescription: Retrives the description of the logger.
/// GetDescription: Retrieves the description of the logger.
/// </summary>
/// <returns>The description of the logger</returns>
string GetDescription();
Expand Down
2 changes: 1 addition & 1 deletion Engine/Generic/IScriptRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic
public interface IScriptRule : IRule
{
/// <summary>
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the anaylsis.
/// AnalyzeScript: Analyzes the given Ast and returns DiagnosticRecords based on the analysis.
/// </summary>
/// <param name="ast">The script's ast</param>
/// <param name="fileName">The name of the script file being analyzed</param>
Expand Down
Loading