diff --git a/README.md b/README.md
index b4b8569298..2a3cce8068 100644
--- a/README.md
+++ b/README.md
@@ -294,6 +294,7 @@ The following conceptual topics exist in the `PSRule` module:
- [Execution.AliasReference](https://aka.ms/ps-rule/options#executionaliasreference)
- [Execution.AliasReferenceWarning](https://aka.ms/ps-rule/options#executionaliasreferencewarning)
- [Execution.DuplicateResourceId](https://aka.ms/ps-rule/options#executionduplicateresourceid)
+ - [Execution.HashAlgorithm](https://aka.ms/ps-rule/options#executionhashalgorithm)
- [Execution.LanguageMode](https://aka.ms/ps-rule/options#executionlanguagemode)
- [Execution.InconclusiveWarning](https://aka.ms/ps-rule/options#executioninconclusivewarning)
- [Execution.InvariantCulture](https://aka.ms/ps-rule/options#executioninvariantculture)
diff --git a/docs/CHANGELOG-v3.md b/docs/CHANGELOG-v3.md
index 3491e53e81..bdf727fbbf 100644
--- a/docs/CHANGELOG-v3.md
+++ b/docs/CHANGELOG-v3.md
@@ -38,6 +38,13 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
What's changed since release v2.9.0:
- General improvements:
+ - **Breaking change:** Switch to use SHA-512 for generating unbound objects by @BernieWhite.
+ [#1155](https://github.com/microsoft/PSRule/issues/1155)
+ - Objects that have no bound name will automatically be assigned a name based on the SHA-512 hash of the object.
+ - Previously a SHA-1 hash was used, however this is no longer considered secure.
+ - The name for unbound objects that are suppressed will change as a result.
+ - Additionally the hash can be changed by setting the `Execution.HashAlgorithm` option.
+ - See [upgrade notes][1] for details.
- Expanded support for `FileHeader` assertion by @BernieWhite.
[#1521](https://github.com/microsoft/PSRule/issues/1521)
- Added support for `.bicepparam`, `.tsp`, `.tsx`, `.editorconfig`, `.ipynb`, and `.toml` files.
diff --git a/docs/concepts/PSRule/en-US/about_PSRule_Options.md b/docs/concepts/PSRule/en-US/about_PSRule_Options.md
index 8fc560c861..8773baf052 100644
--- a/docs/concepts/PSRule/en-US/about_PSRule_Options.md
+++ b/docs/concepts/PSRule/en-US/about_PSRule_Options.md
@@ -18,6 +18,7 @@ The following workspace options are available for use:
- [Execution.AliasReference](#executionaliasreference)
- [Execution.AliasReferenceWarning](#executionaliasreferencewarning)
- [Execution.DuplicateResourceId](#executionduplicateresourceid)
+- [Execution.HashAlgorithm](#executionhashalgorithm)
- [Execution.LanguageMode](#executionlanguagemode)
- [Execution.InconclusiveWarning](#executioninconclusivewarning)
- [Execution.InvariantCulture](#executioninvariantculture)
@@ -88,7 +89,8 @@ Options can be used with the following PSRule cmdlets:
Each of these cmdlets support:
-- Using the `-Option` parameter with an object created with the `New-PSRuleOption` cmdlet. See cmdlet help for syntax and examples.
+- Using the `-Option` parameter with an object created with the `New-PSRuleOption` cmdlet.
+ See cmdlet help for syntax and examples.
- Using the `-Option` parameter with a hashtable object.
- Using the `-Option` parameter with a YAML file path.
@@ -124,7 +126,8 @@ The `Set-PSRuleOption` cmdlet can be used to set options stored in YAML or the Y
Set-PSRuleOption -OutputFormat Yaml;
```
-By default, PSRule will automatically look for a default YAML options file in the current working directory. Alternatively, you can specify a specific file path.
+By default, PSRule will automatically look for a default YAML options file in the current working directory.
+Alternatively, you can specify a specific file path.
For example:
@@ -426,21 +429,25 @@ _TargetName_ is used in output results to identify one object from another.
Many objects could be passed down the pipeline at the same time, so using a _TargetName_ that is meaningful is important.
_TargetName_ is also used for advanced features such as rule suppression.
-The value that PSRule uses for _TargetName_ is configurable. PSRule uses the following logic to determine what _TargetName_ should be used:
+The value that PSRule uses for _TargetName_ is configurable.
+PSRule uses the following logic to determine what _TargetName_ should be used:
- By default PSRule will:
- Use `TargetName` or `Name` properties on the object. These property names are case insensitive.
- If both `TargetName` and `Name` properties exist, `TargetName` will take precedence over `Name`.
- - If neither `TargetName` or `Name` properties exist, a SHA1 hash of the object will be used as _TargetName_.
+ - If neither `TargetName` or `Name` properties exist, a hash of the object will be used as _TargetName_.
+ - The hash algorithm used can be set by the `Execution.HashAlgorithm` option.
- If custom _TargetName_ binding properties are configured, the property names specified will override the defaults.
- If **none** of the configured property names exist, PSRule will revert back to `TargetName` then `Name`.
- If more then one property name is configured, the order they are specified in the configuration determines precedence.
- i.e. The first configured property name will take precedence over the second property name.
- - By default the property name will be matched ignoring case sensitivity. To use a case sensitive match, configure the [Binding.IgnoreCase](#bindingignorecase) option.
+ - By default the property name will be matched ignoring case sensitivity.
+ To use a case sensitive match, configure the [Binding.IgnoreCase](#bindingignorecase) option.
- If a custom _TargetName_ binding function is specified, the function will be evaluated first before any other option.
- If the function returns `$Null` then custom properties, `TargetName` and `Name` properties will be used.
- The custom binding function is executed outside the PSRule engine, so PSRule keywords and variables will not be available.
- - Custom binding functions are blocked in constrained language mode is used. See [language mode](#executionlanguagemode) for more information.
+ - Custom binding functions are blocked in constrained language mode is used.
+ See [language mode](#executionlanguagemode) for more information.
Custom property names to use for binding can be specified using:
@@ -515,11 +522,13 @@ PSRule uses the following logic to determine what _TargetType_ should be used:
- If **none** of the configured property names exist, PSRule will revert back to the type presented by PowerShell.
- If more then one property name is configured, the order they are specified in the configuration determines precedence.
- i.e. The first configured property name will take precedence over the second property name.
- - By default the property name will be matched ignoring case sensitivity. To use a case sensitive match, configure the [`Binding.IgnoreCase`](#bindingignorecase) option.
+ - By default the property name will be matched ignoring case sensitivity.
+ To use a case sensitive match, configure the [`Binding.IgnoreCase`](#bindingignorecase) option.
- If a custom _TargetType_ binding function is specified, the function will be evaluated first before any other option.
- If the function returns `$Null` then custom properties, or the type presented by PowerShell will be used in order instead.
- The custom binding function is executed outside the PSRule engine, so PSRule keywords and variables will not be available.
- - Custom binding functions are blocked in constrained language mode is used. See [language mode](#executionlanguagemode) for more information.
+ - Custom binding functions are blocked in constrained language mode is used.
+ See [language mode](#executionlanguagemode) for more information.
Custom property names to use for binding can be specified using:
@@ -897,6 +906,50 @@ variables:
value: Warn
```
+### Execution.HashAlgorithm
+
+Specifies the hashing algorithm used by the PSRule runtime.
+This hash algorithm is used when generating a resource identifier for an object that does not have a bound name.
+
+By default, the _SHA512_ algorithm is used.
+
+The following algorithms are available for use in PSRule:
+
+- SHA512
+- SHA384
+- SHA256
+
+This option can be specified using:
+
+```powershell
+# PowerShell: Using the Execution.HashAlgorithm hashtable key
+$option = New-PSRuleOption -Option @{ 'Execution.HashAlgorithm' = 'SHA256' };
+```
+
+```yaml
+# YAML: Using the execution/hashAlgorithm property
+execution:
+ hashAlgorithm: SHA256
+```
+
+```bash
+# Bash: Using environment variable
+export PSRULE_EXECUTION_HASHALGORITHM=SHA256
+```
+
+```yaml
+# GitHub Actions: Using environment variable
+env:
+ PSRULE_EXECUTION_HASHALGORITHM: SHA256
+```
+
+```yaml
+# Azure Pipelines: Using environment variable
+variables:
+- name: PSRULE_EXECUTION_HASHALGORITHM
+ value: SHA256
+```
+
### Execution.LanguageMode
Unless PowerShell has been constrained, full language features of PowerShell are available to use within rule definitions.
diff --git a/docs/upgrade-notes.md b/docs/upgrade-notes.md
index f773404f45..8bfe545285 100644
--- a/docs/upgrade-notes.md
+++ b/docs/upgrade-notes.md
@@ -8,6 +8,27 @@ discussion: false
This document contains notes to help upgrade from previous versions of PSRule.
+## Upgrading to v3.0.0
+
+### Unbound object names
+
+When an object is processed by PSRule, it is assigned a name.
+This name is used to identify the object in the output and to suppress the object from future processing.
+
+Prior to _v3.0.0_, the name was generated using a SHA-1 hash of the object.
+The SHA-1 algorithm is no longer considered secure and has been replaced with SHA-512.
+
+From _v3.0.0_, if the name of an object can not be determined, the SHA-512 hash of the object will be used.
+Any objects that have previously been suppressed with a name based on a SHA-1 hash will no longer be suppressed.
+
+To resolve any issue caused by this change, you can:
+
+1. Configure binding by setting the [Binding.TargetName][1] option to set an alternative property to use as the name. _OR_
+2. Update any existing keys set with the [Suppression][2] option to use the new SHA-512 hash.
+
+ [1]: https://aka.ms/ps-rule/options#bindingtargetname
+ [2]: https://aka.ms/ps-rule/options#suppression
+
## Upgrading to v2.0.0
### Resources naming restrictions
diff --git a/schemas/PSRule-options.schema.json b/schemas/PSRule-options.schema.json
index 0d0efa7d94..5ee9c25f23 100644
--- a/schemas/PSRule-options.schema.json
+++ b/schemas/PSRule-options.schema.json
@@ -328,6 +328,18 @@
],
"default": "Error"
},
+ "hashAlgorithm": {
+ "type": "string",
+ "title": "Hash Algorithm",
+ "description": "Configures the hashing algorithm used by the PSRule runtime. By default, SHA512 is used.",
+ "markdownDescription": "Configures the hashing algorithm used by the PSRule runtime.\n\nBy default, `SHA512` is used.\n\n[See help](https://microsoft.github.io/PSRule/v2/concepts/PSRule/en-US/about_PSRule_Options/#executionhashalgorithm)",
+ "enum": [
+ "SHA512",
+ "SHA384",
+ "SHA256"
+ ],
+ "default": "SHA512"
+ },
"languageMode": {
"type": "string",
"title": "Language mode",
diff --git a/src/PSRule.Tool/ClientHelper.cs b/src/PSRule.Tool/ClientHelper.cs
index 3982177ce1..c07b5266ff 100644
--- a/src/PSRule.Tool/ClientHelper.cs
+++ b/src/PSRule.Tool/ClientHelper.cs
@@ -190,7 +190,7 @@ private static PSRuleOption GetOption(ClientHost host)
{
PSRuleOption.UseHostContext(host);
var option = PSRuleOption.FromFileOrEmpty();
- option.Execution.InitialSessionState = Configuration.SessionState.Minimal;
+ option.Execution.InitialSessionState = Options.SessionState.Minimal;
option.Input.Format = InputFormat.File;
option.Output.Style ??= OutputStyle.Client;
return option;
diff --git a/src/PSRule/Configuration/ExecutionActionPreference.cs b/src/PSRule.Types/Options/ExecutionActionPreference.cs
similarity index 96%
rename from src/PSRule/Configuration/ExecutionActionPreference.cs
rename to src/PSRule.Types/Options/ExecutionActionPreference.cs
index 487b3bd677..13e57af5e2 100644
--- a/src/PSRule/Configuration/ExecutionActionPreference.cs
+++ b/src/PSRule.Types/Options/ExecutionActionPreference.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-namespace PSRule.Configuration
+namespace PSRule.Options
{
///
/// Determines the action to take for execution behaviors.
diff --git a/src/PSRule/Configuration/ExecutionOption.cs b/src/PSRule.Types/Options/ExecutionOption.cs
similarity index 95%
rename from src/PSRule/Configuration/ExecutionOption.cs
rename to src/PSRule.Types/Options/ExecutionOption.cs
index d2467b500c..edad84eabb 100644
--- a/src/PSRule/Configuration/ExecutionOption.cs
+++ b/src/PSRule.Types/Options/ExecutionOption.cs
@@ -3,7 +3,7 @@
using System.ComponentModel;
-namespace PSRule.Configuration
+namespace PSRule.Options
{
///
/// Options that configure the execution sandbox.
@@ -13,7 +13,7 @@ namespace PSRule.Configuration
///
public sealed class ExecutionOption : IEquatable
{
- private const LanguageMode DEFAULT_LANGUAGEMODE = Configuration.LanguageMode.FullLanguage;
+ private const LanguageMode DEFAULT_LANGUAGEMODE = Options.LanguageMode.FullLanguage;
private const ExecutionActionPreference DEFAULT_DUPLICATERESOURCEID = ExecutionActionPreference.Error;
private const SessionState DEFAULT_INITIALSESSIONSTATE = SessionState.BuiltIn;
private const ExecutionActionPreference DEFAULT_SUPPRESSIONGROUPEXPIRED = ExecutionActionPreference.Warn;
@@ -23,10 +23,12 @@ public sealed class ExecutionOption : IEquatable
private const ExecutionActionPreference DEFAULT_RULEINCONCLUSIVE = ExecutionActionPreference.Warn;
private const ExecutionActionPreference DEFAULT_INVARIANTCULTURE = ExecutionActionPreference.Warn;
private const ExecutionActionPreference DEFAULT_UNPROCESSEDOBJECT = ExecutionActionPreference.Warn;
+ private const HashAlgorithm DEFAULT_HASHALGORITHM = Options.HashAlgorithm.SHA512;
internal static readonly ExecutionOption Default = new()
{
DuplicateResourceId = DEFAULT_DUPLICATERESOURCEID,
+ HashAlgorithm = DEFAULT_HASHALGORITHM,
LanguageMode = DEFAULT_LANGUAGEMODE,
InitialSessionState = DEFAULT_INITIALSESSIONSTATE,
SuppressionGroupExpired = DEFAULT_SUPPRESSIONGROUPEXPIRED,
@@ -46,6 +48,7 @@ public ExecutionOption()
#pragma warning disable CS0618 // Type or member is obsolete
AliasReferenceWarning = null;
DuplicateResourceId = null;
+ HashAlgorithm = null;
LanguageMode = null;
InconclusiveWarning = null;
InvariantCultureWarning = null;
@@ -74,6 +77,7 @@ public ExecutionOption(ExecutionOption option)
#pragma warning disable CS0618 // Type or member is obsolete
AliasReferenceWarning = option.AliasReferenceWarning;
DuplicateResourceId = option.DuplicateResourceId;
+ HashAlgorithm = option.HashAlgorithm;
LanguageMode = option.LanguageMode;
InconclusiveWarning = option.InconclusiveWarning;
InvariantCultureWarning = option.InvariantCultureWarning;
@@ -103,6 +107,7 @@ public bool Equals(ExecutionOption other)
return other != null &&
AliasReferenceWarning == other.AliasReferenceWarning &&
DuplicateResourceId == other.DuplicateResourceId &&
+ HashAlgorithm == other.HashAlgorithm &&
LanguageMode == other.LanguageMode &&
InconclusiveWarning == other.InconclusiveWarning &&
InvariantCultureWarning == other.InvariantCultureWarning &&
@@ -128,6 +133,7 @@ public override int GetHashCode()
#pragma warning disable CS0618 // Type or member is obsolete
hash = hash * 23 + (AliasReferenceWarning.HasValue ? AliasReferenceWarning.Value.GetHashCode() : 0);
hash = hash * 23 + (DuplicateResourceId.HasValue ? DuplicateResourceId.Value.GetHashCode() : 0);
+ hash = hash * 23 + (HashAlgorithm.HasValue ? HashAlgorithm.Value.GetHashCode() : 0);
hash = hash * 23 + (LanguageMode.HasValue ? LanguageMode.Value.GetHashCode() : 0);
hash = hash * 23 + (InconclusiveWarning.HasValue ? InconclusiveWarning.Value.GetHashCode() : 0);
hash = hash * 23 + (InvariantCultureWarning.HasValue ? InvariantCultureWarning.Value.GetHashCode() : 0);
@@ -157,6 +163,7 @@ internal static ExecutionOption Combine(ExecutionOption o1, ExecutionOption o2)
{
AliasReferenceWarning = o1.AliasReferenceWarning ?? o2.AliasReferenceWarning,
DuplicateResourceId = o1.DuplicateResourceId ?? o2.DuplicateResourceId,
+ HashAlgorithm = o1.HashAlgorithm ?? o2.HashAlgorithm,
LanguageMode = o1.LanguageMode ?? o2.LanguageMode,
InconclusiveWarning = o1.InconclusiveWarning ?? o2.InconclusiveWarning,
NotProcessedWarning = o1.NotProcessedWarning ?? o2.NotProcessedWarning,
@@ -192,6 +199,12 @@ internal static ExecutionOption Combine(ExecutionOption o1, ExecutionOption o2)
[DefaultValue(null)]
public ExecutionActionPreference? DuplicateResourceId { get; set; }
+ ///
+ /// Configures the hashing algorithm used by the PSRule runtime.
+ ///
+ [DefaultValue(null)]
+ public HashAlgorithm? HashAlgorithm { get; set; }
+
///
/// The langauge mode to execute PowerShell code with.
///
@@ -330,6 +343,9 @@ internal static ExecutionOption Combine(ExecutionOption o1, ExecutionOption o2)
///
internal void Load()
{
+ if (Environment.TryEnum("PSRULE_EXECUTION_HASHALGORITHM", out HashAlgorithm hashAlgorithm))
+ HashAlgorithm = hashAlgorithm;
+
#pragma warning disable CS0618 // Type or member is obsolete
if (Environment.TryBool("PSRULE_EXECUTION_ALIASREFERENCEWARNING", out var bvalue))
AliasReferenceWarning = bvalue;
@@ -383,6 +399,9 @@ internal void Load()
///
internal void Load(Dictionary index)
{
+ if (index.TryPopEnum("Execution.HashAlgorithm", out HashAlgorithm hashAlgorithm))
+ HashAlgorithm = hashAlgorithm;
+
#pragma warning disable CS0618 // Type or member is obsolete
if (index.TryPopBool("Execution.AliasReferenceWarning", out var bvalue))
AliasReferenceWarning = bvalue;
diff --git a/src/PSRule.Types/Options/HashAlgorithm.cs b/src/PSRule.Types/Options/HashAlgorithm.cs
new file mode 100644
index 0000000000..9891677f97
--- /dev/null
+++ b/src/PSRule.Types/Options/HashAlgorithm.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace PSRule.Options
+{
+ ///
+ /// Configures the hashing algorithm used by the PSRule runtime.
+ ///
+ [JsonConverter(typeof(StringEnumConverter))]
+ public enum HashAlgorithm
+ {
+ ///
+ /// Use SHA256.
+ ///
+ SHA256,
+
+ ///
+ /// Use SHA384.
+ ///
+ SHA384,
+
+ ///
+ /// Use SHA512.
+ ///
+ SHA512
+ }
+}
diff --git a/src/PSRule/Configuration/LanguageMode.cs b/src/PSRule.Types/Options/LanguageMode.cs
similarity index 96%
rename from src/PSRule/Configuration/LanguageMode.cs
rename to src/PSRule.Types/Options/LanguageMode.cs
index 53a4653ec0..d03a30bdb8 100644
--- a/src/PSRule/Configuration/LanguageMode.cs
+++ b/src/PSRule.Types/Options/LanguageMode.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-namespace PSRule.Configuration
+namespace PSRule.Options
{
///
/// Configures the language mode PowerShell code executes as within PSRule runtime.
diff --git a/src/PSRule/Configuration/SessionState.cs b/src/PSRule.Types/Options/SessionState.cs
similarity index 96%
rename from src/PSRule/Configuration/SessionState.cs
rename to src/PSRule.Types/Options/SessionState.cs
index e330b1afd8..e1c31bfd93 100644
--- a/src/PSRule/Configuration/SessionState.cs
+++ b/src/PSRule.Types/Options/SessionState.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-namespace PSRule.Configuration
+namespace PSRule.Options
{
///
/// Configures how the initial PowerShell sandbox for executing rules is created.
diff --git a/src/PSRule/Common/RunspaceContextDiagnosticExtensions.cs b/src/PSRule/Common/RunspaceContextDiagnosticExtensions.cs
index 7c402e1ce7..cbefaa8eaa 100644
--- a/src/PSRule/Common/RunspaceContextDiagnosticExtensions.cs
+++ b/src/PSRule/Common/RunspaceContextDiagnosticExtensions.cs
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-using PSRule.Configuration;
+using PSRule.Options;
using PSRule.Definitions;
using PSRule.Pipeline;
using PSRule.Resources;
diff --git a/src/PSRule/Configuration/PSRuleOption.cs b/src/PSRule/Configuration/PSRuleOption.cs
index db58cb5c29..a422e0c154 100644
--- a/src/PSRule/Configuration/PSRuleOption.cs
+++ b/src/PSRule/Configuration/PSRuleOption.cs
@@ -36,7 +36,7 @@ public sealed class PSRuleOption : IEquatable, IBaselineV1Spec
Baseline = Options.BaselineOption.Default,
Binding = BindingOption.Default,
Convention = ConventionOption.Default,
- Execution = ExecutionOption.Default,
+ Execution = Options.ExecutionOption.Default,
Include = IncludeOption.Default,
Input = InputOption.Default,
Logging = LoggingOption.Default,
@@ -54,7 +54,7 @@ public PSRuleOption()
Binding = new BindingOption();
Configuration = new ConfigurationOption();
Convention = new ConventionOption();
- Execution = new ExecutionOption();
+ Execution = new Options.ExecutionOption();
Include = new IncludeOption();
Input = new InputOption();
Logging = new LoggingOption();
@@ -75,7 +75,7 @@ private PSRuleOption(string sourcePath, PSRuleOption option)
Binding = new BindingOption(option?.Binding);
Configuration = new ConfigurationOption(option?.Configuration);
Convention = new ConventionOption(option?.Convention);
- Execution = new ExecutionOption(option?.Execution);
+ Execution = new Options.ExecutionOption(option?.Execution);
Include = new IncludeOption(option?.Include);
Input = new InputOption(option?.Input);
Logging = new LoggingOption(option?.Logging);
@@ -110,7 +110,7 @@ private PSRuleOption(string sourcePath, PSRuleOption option)
///
/// Options that configure the execution sandbox.
///
- public ExecutionOption Execution { get; set; }
+ public Options.ExecutionOption Execution { get; set; }
///
/// Options that affect source locations imported for execution.
@@ -210,7 +210,7 @@ private static PSRuleOption Combine(PSRuleOption o1, PSRuleOption o2)
result.Binding = BindingOption.Combine(result.Binding, o2?.Binding);
result.Configuration = ConfigurationOption.Combine(result.Configuration, o2?.Configuration);
result.Convention = ConventionOption.Combine(result.Convention, o2?.Convention);
- result.Execution = ExecutionOption.Combine(result.Execution, o2?.Execution);
+ result.Execution = Options.ExecutionOption.Combine(result.Execution, o2?.Execution);
result.Include = IncludeOption.Combine(result.Include, o2?.Include);
result.Input = InputOption.Combine(result.Input, o2?.Input);
result.Logging = LoggingOption.Combine(result.Logging, o2?.Logging);
diff --git a/src/PSRule/Host/Host.cs b/src/PSRule/Host/Host.cs
index 622a3da961..d2143fb193 100644
--- a/src/PSRule/Host/Host.cs
+++ b/src/PSRule/Host/Host.cs
@@ -147,9 +147,9 @@ internal static class HostState
///
/// Create a default session state.
///
- public static InitialSessionState CreateSessionState(Configuration.SessionState initialSessionState)
+ public static InitialSessionState CreateSessionState(Options.SessionState initialSessionState)
{
- var state = initialSessionState == Configuration.SessionState.Minimal ?
+ var state = initialSessionState == Options.SessionState.Minimal ?
InitialSessionState.CreateDefault2() : InitialSessionState.CreateDefault();
// Add in language elements
diff --git a/src/PSRule/PSRule.psm1 b/src/PSRule/PSRule.psm1
index cb70c293a5..de0e6e74fa 100644
--- a/src/PSRule/PSRule.psm1
+++ b/src/PSRule/PSRule.psm1
@@ -125,7 +125,7 @@ function Invoke-PSRule {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('Format')) {
$Option.Input.Format = $Format;
@@ -283,7 +283,7 @@ function Test-PSRuleTarget {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('Format')) {
$Option.Input.Format = $Format;
@@ -389,7 +389,7 @@ function Get-PSRuleTarget {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('Format')) {
$Option.Input.Format = $Format;
@@ -556,7 +556,7 @@ function Assert-PSRule {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('Format')) {
$Option.Input.Format = $Format;
@@ -718,7 +718,7 @@ function Get-PSRule {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('OutputFormat')) {
$Option.Output.Format = $OutputFormat;
@@ -1051,7 +1051,7 @@ function Get-PSRuleHelp {
# If DeviceGuard is enabled, force a contrained execution environment
if ($isDeviceGuard) {
- $Option.Execution.LanguageMode = [PSRule.Configuration.LanguageMode]::ConstrainedLanguage;
+ $Option.Execution.LanguageMode = [PSRule.Options.LanguageMode]::ConstrainedLanguage;
}
if ($PSBoundParameters.ContainsKey('Culture')) {
$Option.Output.Culture = $Culture;
@@ -1171,7 +1171,7 @@ function New-PSRuleOption {
# Sets the Execution.DuplicateResourceId option
[Parameter(Mandatory = $False)]
[Alias('ExecutionDuplicateResourceId')]
- [PSRule.Configuration.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Configuration.ExecutionActionPreference]::Error,
+ [PSRule.Options.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Options.ExecutionActionPreference]::Error,
# Sets the Execution.InconclusiveWarning option
[Parameter(Mandatory = $False)]
@@ -1186,7 +1186,7 @@ function New-PSRuleOption {
# Sets the Execution.InitialSessionState option
[Parameter(Mandatory = $False)]
[Alias('ExecutionInitialSessionState')]
- [PSRule.Configuration.SessionState]$InitialSessionState = [PSRule.Configuration.SessionState]::BuiltIn,
+ [PSRule.Options.SessionState]$InitialSessionState = [PSRule.Options.SessionState]::BuiltIn,
# Sets the Execution.NotProcessedWarning option
[Parameter(Mandatory = $False)]
@@ -1202,31 +1202,31 @@ function New-PSRuleOption {
# Sets the Execution.SuppressionGroupExpired option
[Parameter(Mandatory = $False)]
[Alias('ExecutionSuppressionGroupExpired')]
- [PSRule.Configuration.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleExcluded option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Configuration.ExecutionActionPreference]::Ignore,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Options.ExecutionActionPreference]::Ignore,
# Sets the Execution.RuleSuppressed option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.AliasReference option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleInconclusive option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.InvariantCulture option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.UnprocessedObject option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Include.Module option
[Parameter(Mandatory = $False)]
@@ -1501,7 +1501,7 @@ function Set-PSRuleOption {
# Sets the Execution.DuplicateResourceId option
[Parameter(Mandatory = $False)]
[Alias('ExecutionDuplicateResourceId')]
- [PSRule.Configuration.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Configuration.ExecutionActionPreference]::Error,
+ [PSRule.Options.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Options.ExecutionActionPreference]::Error,
# Sets the Execution.InconclusiveWarning option
[Parameter(Mandatory = $False)]
@@ -1516,7 +1516,7 @@ function Set-PSRuleOption {
# Sets the Execution.InitialSessionState option
[Parameter(Mandatory = $False)]
[Alias('ExecutionInitialSessionState')]
- [PSRule.Configuration.SessionState]$InitialSessionState = [PSRule.Configuration.SessionState]::BuiltIn,
+ [PSRule.Options.SessionState]$InitialSessionState = [PSRule.Options.SessionState]::BuiltIn,
# Sets the Execution.NotProcessedWarning option
[Parameter(Mandatory = $False)]
@@ -1532,31 +1532,31 @@ function Set-PSRuleOption {
# Sets the Execution.SuppressionGroupExpired option
[Parameter(Mandatory = $False)]
[Alias('ExecutionSuppressionGroupExpired')]
- [PSRule.Configuration.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleExcluded option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Configuration.ExecutionActionPreference]::Ignore,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Options.ExecutionActionPreference]::Ignore,
# Sets the Execution.RuleSuppressed option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.AliasReference option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleInconclusive option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.InvariantCulture option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.UnprocessedObject option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Include.Module option
[Parameter(Mandatory = $False)]
@@ -2278,7 +2278,7 @@ function SetOptions {
# Sets the Execution.DuplicateResourceId option
[Parameter(Mandatory = $False)]
[Alias('ExecutionDuplicateResourceId')]
- [PSRule.Configuration.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Configuration.ExecutionActionPreference]::Error,
+ [PSRule.Options.ExecutionActionPreference]$DuplicateResourceId = [PSRule.Options.ExecutionActionPreference]::Error,
# Sets the Execution.InconclusiveWarning option
[Parameter(Mandatory = $False)]
@@ -2293,7 +2293,7 @@ function SetOptions {
# Sets the Execution.InitialSessionState option
[Parameter(Mandatory = $False)]
[Alias('ExecutionInitialSessionState')]
- [PSRule.Configuration.SessionState]$InitialSessionState = [PSRule.Configuration.SessionState]::BuiltIn,
+ [PSRule.Options.SessionState]$InitialSessionState = [PSRule.Options.SessionState]::BuiltIn,
# Sets the Execution.NotProcessedWarning option
[Parameter(Mandatory = $False)]
@@ -2308,31 +2308,31 @@ function SetOptions {
# Sets the Execution.SuppressionGroupExpired option
[Parameter(Mandatory = $False)]
[Alias('ExecutionSuppressionGroupExpired')]
- [PSRule.Configuration.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$SuppressionGroupExpired = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleExcluded option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Configuration.ExecutionActionPreference]::Ignore,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleExcluded = [PSRule.Options.ExecutionActionPreference]::Ignore,
# Sets the Execution.RuleSuppressed option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleSuppressed = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.AliasReference option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionAliasReference = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.RuleInconclusive option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionRuleInconclusive = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.InvariantCulture option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionInvariantCulture = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Execution.UnprocessedObject option
[Parameter(Mandatory = $False)]
- [PSRule.Configuration.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Configuration.ExecutionActionPreference]::Warn,
+ [PSRule.Options.ExecutionActionPreference]$ExecutionUnprocessedObject = [PSRule.Options.ExecutionActionPreference]::Warn,
# Sets the Include.Module option
[Parameter(Mandatory = $False)]
diff --git a/src/PSRule/Pipeline/GetRuleHelpPipeline.cs b/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
index 3f5c5b5abc..15f555a6e7 100644
--- a/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
+++ b/src/PSRule/Pipeline/GetRuleHelpPipeline.cs
@@ -5,6 +5,7 @@
using System.Management.Automation;
using PSRule.Configuration;
using PSRule.Host;
+using PSRule.Options;
using PSRule.Resources;
using PSRule.Rules;
diff --git a/src/PSRule/Pipeline/PipelineBuilder.cs b/src/PSRule/Pipeline/PipelineBuilder.cs
index 1e34f97a78..8fdd2552ad 100644
--- a/src/PSRule/Pipeline/PipelineBuilder.cs
+++ b/src/PSRule/Pipeline/PipelineBuilder.cs
@@ -8,6 +8,7 @@
using PSRule.Data;
using PSRule.Definitions;
using PSRule.Definitions.Baselines;
+using PSRule.Options;
using PSRule.Pipeline.Output;
using PSRule.Resources;
@@ -179,7 +180,7 @@ public interface IPipelineBuilder
/// Configure the pipeline to use a specific baseline.
///
/// A baseline option or the name of a baseline.
- void Baseline(BaselineOption baseline);
+ void Baseline(Configuration.BaselineOption baseline);
///
/// Build the pipeline.
@@ -284,7 +285,7 @@ internal abstract class PipelineBuilderBase : IPipelineBuilder
private string[] _Include;
private Hashtable _Tag;
- private BaselineOption _Baseline;
+ private Configuration.BaselineOption _Baseline;
private string[] _Convention;
private PathFilter _InputFilter;
private PipelineWriter _Writer;
@@ -365,13 +366,13 @@ public virtual IPipelineBuilder Configure(PSRuleOption option)
/// Use a baseline, either by name or by path.
///
[Obsolete()]
- public void UseBaseline(BaselineOption baseline)
+ public void UseBaseline(Configuration.BaselineOption baseline)
{
Baseline(baseline);
}
///
- public void Baseline(BaselineOption baseline)
+ public void Baseline(Configuration.BaselineOption baseline)
{
if (baseline == null)
return;
@@ -437,7 +438,7 @@ private static bool TryModuleVersion(string moduleVersion, string requiredVersio
protected PipelineContext PrepareContext(BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField)
{
var unresolved = new List();
- if (_Baseline is BaselineOption.BaselineRef baselineRef)
+ if (_Baseline is Configuration.BaselineOption.BaselineRef baselineRef)
unresolved.Add(new BaselineRef(ResolveBaselineGroup(baselineRef.Name), OptionContext.ScopeType.Explicit));
return PipelineContext.New(
diff --git a/src/PSRule/Pipeline/PipelineContext.cs b/src/PSRule/Pipeline/PipelineContext.cs
index da6a895b88..73badf6bdc 100644
--- a/src/PSRule/Pipeline/PipelineContext.cs
+++ b/src/PSRule/Pipeline/PipelineContext.cs
@@ -14,6 +14,7 @@
using PSRule.Definitions.Selectors;
using PSRule.Definitions.SuppressionGroups;
using PSRule.Host;
+using PSRule.Options;
using PSRule.Resources;
using PSRule.Runtime;
using PSRule.Runtime.ObjectPath;
@@ -38,7 +39,6 @@ internal sealed class PipelineContext : IDisposable, IBindingContext
// Objects kept for caching and disposal
private Runspace _Runspace;
- private SHA1Managed _Hash;
// Track whether Dispose has been called.
private bool _Disposed;
@@ -60,14 +60,7 @@ internal sealed class PipelineContext : IDisposable, IBindingContext
internal readonly Stopwatch RunTime;
- public HashAlgorithm ObjectHashAlgorithm
- {
- get
- {
- _Hash ??= new SHA1Managed();
- return _Hash;
- }
- }
+ public System.Security.Cryptography.HashAlgorithm ObjectHashAlgorithm { get; }
private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContext baseline, IList unresolved)
{
@@ -87,6 +80,8 @@ private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineR
Baseline = baseline;
_Unresolved = unresolved ?? new List();
_TrackedIssues = new List();
+
+ ObjectHashAlgorithm = GetHashAlgorithm(option.Execution.HashAlgorithm.GetValueOrDefault(ExecutionOption.Default.HashAlgorithm.Value));
RunId = Environment.GetRunId() ?? ObjectHashAlgorithm.GetDigest(Guid.NewGuid().ToByteArray());
RunTime = Stopwatch.StartNew();
}
@@ -280,6 +275,14 @@ private void ReportIssue(RunspaceContext runspaceContext)
// runspaceContext.WarnMissingApiVersion(_TrackedIssues[i].Kind, _TrackedIssues[i].Id);
}
+ private static System.Security.Cryptography.HashAlgorithm GetHashAlgorithm(Options.HashAlgorithm hashAlgorithm)
+ {
+ if (hashAlgorithm == Options.HashAlgorithm.SHA256)
+ return SHA256.Create();
+
+ return hashAlgorithm == Options.HashAlgorithm.SHA384 ? SHA384.Create() : SHA512.Create();
+ }
+
#region IBindingContext
public bool GetPathExpression(string path, out PathExpression expression)
@@ -307,7 +310,7 @@ private void Dispose(bool disposing)
{
if (disposing)
{
- _Hash?.Dispose();
+ ObjectHashAlgorithm?.Dispose();
_Runspace?.Dispose();
_PathExpressionCache.Clear();
LocalizedDataCache.Clear();
diff --git a/src/PSRule/Pipeline/PipelineHookActions.cs b/src/PSRule/Pipeline/PipelineHookActions.cs
index 2d6afdddb1..1eb4c34a2d 100644
--- a/src/PSRule/Pipeline/PipelineHookActions.cs
+++ b/src/PSRule/Pipeline/PipelineHookActions.cs
@@ -143,7 +143,7 @@ private static string NestedTargetPropertyBinding(string[] propertyNames, bool c
}
///
- /// Calculate a SHA1 hash for an object to use as TargetName.
+ /// Calculate a hash for an object to use as TargetName.
///
/// A PSObject to hash.
/// The TargetName of the object.
@@ -159,7 +159,8 @@ private static string GetUnboundObjectTargetName(object targetObject)
settings.Converters.Insert(0, new PSObjectJsonConverter());
var json = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(targetObject, settings));
- return PipelineContext.CurrentThread.ObjectHashAlgorithm.GetDigest(json);
+ var name = PipelineContext.CurrentThread.ObjectHashAlgorithm.GetDigest(json);
+ return name.Substring(0, name.Length > 50 ? 50 : name.Length);
}
///
diff --git a/src/PSRule/Runtime/RunspaceContext.cs b/src/PSRule/Runtime/RunspaceContext.cs
index a43dbed8e1..508eb42129 100644
--- a/src/PSRule/Runtime/RunspaceContext.cs
+++ b/src/PSRule/Runtime/RunspaceContext.cs
@@ -6,6 +6,7 @@
using System.Management.Automation.Language;
using PSRule.Configuration;
using PSRule.Definitions;
+using PSRule.Options;
using PSRule.Pipeline;
using PSRule.Resources;
using PSRule.Rules;
diff --git a/tests/PSRule.Tests/PSRule.Common.Tests.ps1 b/tests/PSRule.Tests/PSRule.Common.Tests.ps1
index 70303cb089..cec8c482e6 100644
--- a/tests/PSRule.Tests/PSRule.Common.Tests.ps1
+++ b/tests/PSRule.Tests/PSRule.Common.Tests.ps1
@@ -2775,13 +2775,13 @@ Describe 'Binding' -Tag Common, Binding {
$result | Should -Not -BeNullOrEmpty;
$result.Length | Should -Be 7;
$result[0..6].IsSuccess() | Should -BeIn $True;
- $result[0].TargetName | Should -BeIn 'f209c623345144be61087d91f30c17b01c6e86d2';
- $result[1].TargetName | Should -BeIn '28e156a7121bc57b0461029208daf0b48d1c4fd0';
- $result[2].TargetName | Should -BeIn '3b8eeb35831ea8f7b5de4e0cf04f32b9a1233a0d';
- $result[3].TargetName | Should -BeIn '7b3ce68b6c2f7d67dae4210eeb83be69f978e2a8';
- $result[4].TargetName | Should -BeIn '205c97d9248d2cd12db1c55ba421eb8df84b22a7';
- $result[5].TargetName | Should -BeIn '356a192b7913b04c54574d18c28d46e6395428ab';
- $result[6].TargetName | Should -BeIn 'da4b9237bacccdf19c0760cab7aec4a8359010b0';
+ $result[0].TargetName | Should -BeIn 'f3d2f8ce966af96a8d320e8f5c088604324885a0d02f44b174';
+ $result[1].TargetName | Should -BeIn '839b3457fca709821c89e23263a070fdca7cb8c4a86b5862f9';
+ $result[2].TargetName | Should -BeIn '1c23e67aab1f653e2ead0b0e71153d02eb249f1c8382821598';
+ $result[3].TargetName | Should -BeIn '72dd48c5f3cef36c66f5633955719b5cdb5f679539ec39b087';
+ $result[4].TargetName | Should -BeIn '35f8cb2a8d4c26a7d53839be143c5d5b82e1543ce27adb94d4';
+ $result[5].TargetName | Should -BeIn '4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8d';
+ $result[6].TargetName | Should -BeIn '40b244112641dd78dd4f93b6c9190dd46e0099194d5a44257b';
}
It 'Binds to custom name' {
diff --git a/tests/PSRule.Tests/PSRule.Options.Tests.ps1 b/tests/PSRule.Tests/PSRule.Options.Tests.ps1
index 0ba4396a01..25e184d4ee 100644
--- a/tests/PSRule.Tests/PSRule.Options.Tests.ps1
+++ b/tests/PSRule.Tests/PSRule.Options.Tests.ps1
@@ -635,6 +635,34 @@ Describe 'New-PSRuleOption' -Tag 'Option','New-PSRuleOption' {
}
}
+ Context 'Read Execution.HashAlgorithm' {
+ It 'from default' {
+ $option = New-PSRuleOption -Default;
+ $option.Execution.HashAlgorithm | Should -Be 'SHA512';
+ }
+
+ It 'from Hashtable' {
+ $option = New-PSRuleOption -Option @{ 'Execution.HashAlgorithm' = 'SHA256' };
+ $option.Execution.HashAlgorithm | Should -Be 'SHA256';
+ }
+
+ It 'from YAML' {
+ $option = New-PSRuleOption -Option (Join-Path -Path $here -ChildPath 'PSRule.Tests.yml');
+ $option.Execution.HashAlgorithm | Should -Be 'SHA256';
+ }
+
+ It 'from Environment' {
+ try {
+ $Env:PSRULE_EXECUTION_HASHALGORITHM = 'SHA256';
+ $option = New-PSRuleOption;
+ $option.Execution.HashAlgorithm | Should -Be 'SHA256';
+ }
+ finally {
+ Remove-Item 'Env:PSRULE_EXECUTION_HASHALGORITHM' -Force;
+ }
+ }
+ }
+
Context 'Read Execution.LanguageMode' {
It 'from default' {
$option = New-PSRuleOption -Default;
diff --git a/tests/PSRule.Tests/PSRule.Tests.yml b/tests/PSRule.Tests/PSRule.Tests.yml
index 543ad61d1a..6c3d8761e0 100644
--- a/tests/PSRule.Tests/PSRule.Tests.yml
+++ b/tests/PSRule.Tests/PSRule.Tests.yml
@@ -56,6 +56,7 @@ execution:
aliasReference: Ignore
aliasReferenceWarning: false
duplicateResourceId: Warn
+ hashAlgorithm: SHA256
languageMode: ConstrainedLanguage
inconclusiveWarning: false
invariantCulture: Ignore
diff --git a/tests/PSRule.Tests/PipelineTests.cs b/tests/PSRule.Tests/PipelineTests.cs
index e6ec105cbd..84fc350536 100644
--- a/tests/PSRule.Tests/PipelineTests.cs
+++ b/tests/PSRule.Tests/PipelineTests.cs
@@ -9,6 +9,7 @@
using System.Threading;
using Newtonsoft.Json.Linq;
using PSRule.Configuration;
+using PSRule.Options;
using PSRule.Pipeline;
using PSRule.Resources;
using PSRule.Rules;
@@ -163,7 +164,7 @@ public void GetRuleWithBaseline()
"Baseline.Rule.yaml",
"FromFileBaseline.Rule.ps1"
}), option, null);
- builder.Baseline(BaselineOption.FromString("@test"));
+ builder.Baseline(Configuration.BaselineOption.FromString("@test"));
var writer = new TestWriter(option);
var pipeline = builder.Build(writer);
diff --git a/tests/PSRule.Tests/TargetNameBindingTests.cs b/tests/PSRule.Tests/TargetNameBindingTests.cs
index 575cf1a1f6..7ced67040b 100644
--- a/tests/PSRule.Tests/TargetNameBindingTests.cs
+++ b/tests/PSRule.Tests/TargetNameBindingTests.cs
@@ -4,6 +4,7 @@
using System.Management.Automation;
using PSRule.Configuration;
using PSRule.Data;
+using PSRule.Options;
using PSRule.Pipeline;
namespace PSRule
@@ -39,12 +40,17 @@ public void UnboundObjectTargetName()
var pso1 = PSObject.AsPSObject(testObject1);
var pso2 = PSObject.AsPSObject(testObject2);
+ // SHA512
PipelineContext.CurrentThread = PipelineContext.New(GetOption(), null, null, null, null, null, null, null);
- var actual1 = PipelineHookActions.BindTargetName(null, false, false, pso1, out _);
- var actual2 = PipelineHookActions.BindTargetName(null, false, false, pso2, out _);
- Assert.Equal(expected: "f209c623345144be61087d91f30c17b01c6e86d2", actual: actual1);
- Assert.Equal(expected: "f209c623345144be61087d91f30c17b01c6e86d2", actual: actual2);
+ Assert.Equal("f3d2f8ce966af96a8d320e8f5c088604324885a0d02f44b174", PipelineHookActions.BindTargetName(null, false, false, pso1, out _));
+ Assert.Equal("f3d2f8ce966af96a8d320e8f5c088604324885a0d02f44b174", PipelineHookActions.BindTargetName(null, false, false, pso2, out _));
+
+ // SHA256
+ PipelineContext.CurrentThread = PipelineContext.New(GetOption(HashAlgorithm.SHA256), null, null, null, null, null, null, null);
+
+ Assert.Equal("67327c8cd8622d17cf1702a76cbbb685e9ef260ce39c9f6779", PipelineHookActions.BindTargetName(null, false, false, pso1, out _));
+ Assert.Equal("67327c8cd8622d17cf1702a76cbbb685e9ef260ce39c9f6779", PipelineHookActions.BindTargetName(null, false, false, pso2, out _));
}
[Fact]
@@ -68,9 +74,13 @@ public void PreferTargetInfo()
Assert.Null(path);
}
- private static PSRuleOption GetOption()
+ private static PSRuleOption GetOption(HashAlgorithm? hashAlgorithm = null)
{
- return new PSRuleOption();
+ var option = new PSRuleOption();
+ if (hashAlgorithm != null)
+ option.Execution.HashAlgorithm = hashAlgorithm;
+
+ return option;
}
}
}