diff --git a/Rules/AvoidUsingDeprecatedManifestFields.cs b/Rules/AvoidUsingDeprecatedManifestFields.cs
new file mode 100644
index 000000000..8e20179cd
--- /dev/null
+++ b/Rules/AvoidUsingDeprecatedManifestFields.cs
@@ -0,0 +1,132 @@
+//
+// 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.Management.Automation.Language;
+using System.Management.Automation;
+using Microsoft.Windows.Powershell.ScriptAnalyzer.Generic;
+using System.ComponentModel.Composition;
+using System.Globalization;
+
+namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
+{
+ ///
+ /// AvoidUsingDeprecatedManifestFields: Run Test Module Manifest to check that no deprecated fields are being used.
+ ///
+ [Export(typeof(IScriptRule))]
+ public class AvoidUsingDeprecatedManifestFields : IScriptRule
+ {
+ ///
+ /// AnalyzeScript: Run Test Module Manifest to check that no deprecated fields are being used.
+ ///
+ /// 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);
+ }
+
+ if (String.Equals(System.IO.Path.GetExtension(fileName), ".psd1", StringComparison.OrdinalIgnoreCase))
+ {
+ var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
+ IEnumerable result = null;
+ try
+ {
+ ps.AddCommand("Test-ModuleManifest");
+ ps.AddParameter("Path", fileName);
+
+ // Suppress warnings emitted during the execution of Test-ModuleManifest
+ // ModuleManifest rule must catch any violations (warnings/errors) and generate DiagnosticRecord(s)
+ ps.AddParameter("WarningAction", ActionPreference.SilentlyContinue);
+ ps.AddParameter("WarningVariable", "Message");
+ ps.AddScript("$Message");
+ result = ps.Invoke();
+
+ }
+ catch
+ {}
+
+ if (result != null)
+ {
+ foreach (var warning in result)
+ {
+ if (warning.BaseObject != null)
+ {
+ yield return
+ new DiagnosticRecord(
+ String.Format(CultureInfo.CurrentCulture, warning.BaseObject.ToString()), ast.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.AvoidUsingDeprecatedManifestFieldsName);
+ }
+
+ ///
+ /// GetCommonName: Retrieves the common name of this rule.
+ ///
+ /// The common name of this rule
+ public string GetCommonName()
+ {
+ return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsCommonName);
+ }
+
+ ///
+ /// GetDescription: Retrieves the description of this rule.
+ ///
+ /// The description of this rule
+ public string GetDescription()
+ {
+ return String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingDeprecatedManifestFieldsDescription);
+ }
+
+ ///
+ /// Method: Retrieves the type of the rule: builtin, managed or module.
+ ///
+ public SourceType GetSourceType()
+ {
+ return SourceType.Builtin;
+ }
+
+ ///
+ /// GetSeverity: Retrieves the severity of the rule: error, warning of information.
+ ///
+ ///
+ public RuleSeverity GetSeverity()
+ {
+ return RuleSeverity.Warning;
+ }
+
+ ///
+ /// Method: Retrieves the module/assembly name the rule is from.
+ ///
+ public string GetSourceName()
+ {
+ return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
+ }
+ }
+}
diff --git a/Rules/ScriptAnalyzerBuiltinRules.csproj b/Rules/ScriptAnalyzerBuiltinRules.csproj
index 9f553cb06..087930117 100644
--- a/Rules/ScriptAnalyzerBuiltinRules.csproj
+++ b/Rules/ScriptAnalyzerBuiltinRules.csproj
@@ -59,6 +59,7 @@
+
diff --git a/Rules/Strings.Designer.cs b/Rules/Strings.Designer.cs
index 3f8180b6c..00f24aa6f 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.34209
+// Runtime Version:4.0.30319.35317
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -510,6 +510,33 @@ internal static string AvoidUsingConvertToSecureStringWithPlainTextName {
}
}
+ ///
+ /// Looks up a localized string similar to Avoid Using Deprecated Manifest Fields.
+ ///
+ internal static string AvoidUsingDeprecatedManifestFieldsCommonName {
+ get {
+ return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsCommonName", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to "ModuleToProcess" is obsolete in the latest PowerShell version. Please update with the latest field "RootModule" in manifest files to avoid PowerShell version inconsistency..
+ ///
+ internal static string AvoidUsingDeprecatedManifestFieldsDescription {
+ get {
+ return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsDescription", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to AvoidUsingDeprecatedManifestFields.
+ ///
+ internal static string AvoidUsingDeprecatedManifestFieldsName {
+ get {
+ return ResourceManager.GetString("AvoidUsingDeprecatedManifestFieldsName", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Avoid Using Empty Catch Block.
///
@@ -1114,7 +1141,7 @@ internal static string ProvideDefaultParameterValueCommonName {
}
///
- /// Looks up a localized string similar to Parameters must have a default value. To fix a violation of this rule, please specify a default value for parameters.
+ /// Looks up a localized string similar to Parameters must have a default value. To fix a violation of this rule, please specify a default value for all parameters.
///
internal static string ProvideDefaultParameterValueDescription {
get {
@@ -1123,7 +1150,7 @@ internal static string ProvideDefaultParameterValueDescription {
}
///
- /// Looks up a localized string similar to Parameter '{0}' is not initialized. Parameters must have a default value. To fix a violation of this rule, please specify a default value for parameters.
+ /// Looks up a localized string similar to Parameter '{0}' is not initialized. Parameters must have a default value. To fix a violation of this rule, please specify a default value for all parameters.
///
internal static string ProvideDefaultParameterValueError {
get {
diff --git a/Rules/Strings.resx b/Rules/Strings.resx
index da0010853..7686518a9 100644
--- a/Rules/Strings.resx
+++ b/Rules/Strings.resx
@@ -726,4 +726,13 @@
ProvideDefaultParameterValue
+
+ Avoid Using Deprecated Manifest Fields
+
+
+ "ModuleToProcess" is obsolete in the latest PowerShell version. Please update with the latest field "RootModule" in manifest files to avoid PowerShell version inconsistency.
+
+
+ AvoidUsingDeprecatedManifestFields
+
\ No newline at end of file
diff --git a/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1 b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1
new file mode 100644
index 000000000..f5729024b
--- /dev/null
+++ b/Tests/Rules/AvoidUsingDeprecatedManifestFields.tests.ps1
@@ -0,0 +1,19 @@
+Import-Module PSScriptAnalyzer
+$violationName = "PSAvoidUsingDeprecatedManifestFields"
+$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
+$violations = Invoke-ScriptAnalyzer $directory\TestBadModule\TestDeprecatedManifestFields.psd1 | Where-Object {$_.RuleName -eq $violationName}
+$noViolations = Invoke-ScriptAnalyzer $directory\TestGoodModule\TestGoodModule.psd1 | Where-Object {$_.RuleName -eq $violationName}
+
+Describe "AvoidUsingDeprecatedManifestFields" {
+ Context "When there are violations" {
+ It "has 1 violations" {
+ $violations.Count | Should Be 1
+ }
+ }
+
+ 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/TestBadModule/TestBadModule.psd1 b/Tests/Rules/TestBadModule/TestBadModule.psd1
index 44d52f161..b8d7bea6c 100644
Binary files a/Tests/Rules/TestBadModule/TestBadModule.psd1 and b/Tests/Rules/TestBadModule/TestBadModule.psd1 differ
diff --git a/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1 b/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1
new file mode 100644
index 000000000..768d5454e
--- /dev/null
+++ b/Tests/Rules/TestBadModule/TestDeprecatedManifestFields.psd1
@@ -0,0 +1,120 @@
+#
+# Module manifest for module 'Deprecated Module manifest fields"
+#
+# Generated by: Microsoft PowerShell Team
+#
+# Generated on: 5/18/2015
+#
+
+@{
+
+# Script module or binary module file associated with this manifest.
+ModuleToProcess ='psscriptanalyzer'
+
+# Version number of this module.
+ModuleVersion = '1.0'
+
+# ID used to uniquely identify this module
+GUID = 'a9f79c02-4503-4300-a022-5e8c01f3449f'
+
+# Author of this module
+Author = ''
+
+# Company or vendor of this module
+CompanyName = ''
+
+# Copyright statement for this module
+Copyright = '(c) 2015 Microsoft. All rights reserved.'
+
+# Description of the functionality provided by this module
+# Description = ''
+
+# Minimum version of the Windows PowerShell engine required by this module
+# PowerShellVersion = ''
+
+# Name of the Windows PowerShell host required by this module
+# PowerShellHostName = ''
+
+# Minimum version of the Windows PowerShell host required by this module
+# PowerShellHostVersion = ''
+
+# Minimum version of Microsoft .NET Framework required by this module
+# DotNetFrameworkVersion = ''
+
+# Minimum version of the common language runtime (CLR) required by this module
+# CLRVersion = ''
+
+# Processor architecture (None, X86, Amd64) required by this module
+# ProcessorArchitecture = ''
+
+# Modules that must be imported into the global environment prior to importing this module
+# RequiredModules = @()
+
+# Assemblies that must be loaded prior to importing this module
+# RequiredAssemblies = @()
+
+# Script files (.ps1) that are run in the caller's environment prior to importing this module.
+# ScriptsToProcess = @()
+
+# Type files (.ps1xml) to be loaded when importing this module
+# TypesToProcess = @()
+
+# Format files (.ps1xml) to be loaded when importing this module
+# FormatsToProcess = @()
+
+# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
+# NestedModules = @()
+
+# Functions to export from this module
+FunctionsToExport = '*'
+
+# Cmdlets to export from this module
+CmdletsToExport = '*'
+
+# Variables to export from this module
+VariablesToExport = '*'
+
+# Aliases to export from this module
+AliasesToExport = '*'
+
+# DSC resources to export from this module
+# DscResourcesToExport = @()
+
+# List of all modules packaged with this module
+# ModuleList = @()
+
+# List of all files packaged with this module
+# FileList = @()
+
+# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable
+#with additional module metadata used by PowerShell.
+PrivateData = @{
+
+ PSData = @{
+
+ # Tags applied to this module. These help with module discovery in online galleries.
+ # Tags = @()
+
+ # A URL to the license for this module.
+ # LicenseUri = ''
+
+ # A URL to the main website for this project.
+ # ProjectUri = ''
+
+ # A URL to an icon representing this module.
+ # IconUri = ''
+
+ # ReleaseNotes of this module
+ # ReleaseNotes = ''
+
+ } # End of PSData hashtable
+
+} # End of PrivateData hashtable
+
+# HelpInfo URI of this module
+# HelpInfoURI = ''
+
+# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
+# DefaultCommandPrefix = ''
+
+}
\ No newline at end of file