mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 12:45:47 +00:00
Move group policy settings and enable policy controlled logging in PowerShell Core (#5791)
Make PowerShell Core reads group policy settings from different registry keys (Windows only) and the configuration files (both Windows and Unix). - On Windows, move to different GPO registry keys. - On both Windows and Unix, read GPO related settings from the configuration file `powershell.config.json`. - On Windows, the policy settings in registry take precedence over the configuration file. - Enable policy controlled logging and transcription on Unix.
This commit is contained in:
31 files changed
+1503
-787
No files matched your search
+13
-12
@@ -1364,7 +1364,8 @@ function Test-PSPesterResults
|
||||
|
||||
function Start-PSxUnit {
|
||||
[CmdletBinding()]param(
|
||||
[string] $TestResultsFile = "XUnitResults.xml"
|
||||
[string] $SequentialTestResultsFile = "SequentialXUnitResults.xml",
|
||||
[string] $ParallelTestResultsFile = "ParallelXUnitResults.xml"
|
||||
)
|
||||
|
||||
# Add .NET CLI tools to PATH
|
||||
@@ -1375,9 +1376,11 @@ function Start-PSxUnit {
|
||||
throw "PowerShell must be built before running tests!"
|
||||
}
|
||||
|
||||
if(Test-Path $TestResultsFile)
|
||||
{
|
||||
Remove-Item $TestResultsFile -Force -ErrorAction SilentlyContinue
|
||||
if (Test-Path $SequentialTestResultsFile) {
|
||||
Remove-Item $SequentialTestResultsFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (Test-Path $ParallelTestResultsFile) {
|
||||
Remove-Item $ParallelTestResultsFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1386,12 +1389,7 @@ function Start-PSxUnit {
|
||||
# Path manipulation to obtain test project output directory
|
||||
dotnet restore
|
||||
|
||||
# --fx-version workaround required due to https://github.com/dotnet/cli/issues/7901#issuecomment-343323674
|
||||
if($Environment.IsWindows)
|
||||
{
|
||||
dotnet xunit --fx-version 2.0.0 -xml $TestResultsFile
|
||||
}
|
||||
else
|
||||
if(-not $Environment.IsWindows)
|
||||
{
|
||||
if($Environment.IsMacOS)
|
||||
{
|
||||
@@ -1419,9 +1417,12 @@ function Start-PSxUnit {
|
||||
{
|
||||
throw "Dependencies $requiredDependencies not met."
|
||||
}
|
||||
|
||||
dotnet xunit --fx-version 2.0.0 -configuration $Options.configuration -xml $TestResultsFile
|
||||
}
|
||||
|
||||
# '-fxversion' workaround required due to https://github.com/dotnet/cli/issues/7901#issuecomment-343323674
|
||||
# Run sequential tests first, and then run the tests that can execute in parallel
|
||||
dotnet xunit -fxversion 2.0.0 -configuration $Options.configuration -xml $SequentialTestResultsFile -namespace "PSTests.Sequential" -parallel none
|
||||
dotnet xunit -fxversion 2.0.0 -configuration $Options.configuration -xml $ParallelTestResultsFile -namespace "PSTests.Parallel" -nobuild
|
||||
}
|
||||
finally {
|
||||
Pop-Location
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Diagnostics;
|
||||
@@ -463,29 +464,17 @@ namespace Microsoft.PowerShell
|
||||
}
|
||||
}
|
||||
|
||||
private static string s_groupPolicyBase = @"Software\Policies\Microsoft\Windows\PowerShell";
|
||||
private static string s_consoleSessionConfigurationKey = "ConsoleSessionConfiguration";
|
||||
private static string s_enableConsoleSessionConfiguration = "EnableConsoleSessionConfiguration";
|
||||
private static string s_consoleSessionConfigurationName = "ConsoleSessionConfigurationName";
|
||||
private static string GetConfigurationNameFromGroupPolicy()
|
||||
{
|
||||
// Current user policy takes precedence.
|
||||
var groupPolicySettings = Utils.GetGroupPolicySetting(s_groupPolicyBase, s_consoleSessionConfigurationKey, Utils.RegCurrentUserThenLocalMachine);
|
||||
if (groupPolicySettings != null)
|
||||
var consoleSessionSetting = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
if (consoleSessionSetting != null)
|
||||
{
|
||||
object keyValue;
|
||||
if (groupPolicySettings.TryGetValue(s_enableConsoleSessionConfiguration, out keyValue))
|
||||
if (consoleSessionSetting.EnableConsoleSessionConfiguration == true)
|
||||
{
|
||||
if (String.Equals(keyValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
|
||||
if (!string.IsNullOrEmpty(consoleSessionSetting.ConsoleSessionConfigurationName))
|
||||
{
|
||||
if (groupPolicySettings.TryGetValue(s_consoleSessionConfigurationName, out keyValue))
|
||||
{
|
||||
string consoleSessionConfigurationName = keyValue.ToString();
|
||||
if (!string.IsNullOrEmpty(consoleSessionConfigurationName))
|
||||
{
|
||||
return consoleSessionConfigurationName;
|
||||
}
|
||||
}
|
||||
return consoleSessionSetting.ConsoleSessionConfigurationName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1643,59 +1643,6 @@ namespace System.Management.Automation
|
||||
|
||||
internal ExecutionContext Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads the path for the appropriate shellID from the registry.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="shellID">
|
||||
/// The ID of the shell to retrieve the path for.
|
||||
/// </param>
|
||||
///
|
||||
/// <returns>
|
||||
/// The path to the shell represented by the shellID.
|
||||
/// </returns>
|
||||
///
|
||||
/// <remarks>
|
||||
/// The shellID must be registered in the Windows Registry in either
|
||||
/// the HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE hive under
|
||||
/// Software/Microsoft/MSH/<ShellID> and are searched in that order.
|
||||
/// </remarks>
|
||||
///
|
||||
internal static string GetShellPathFromRegistry(string shellID)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
#if !UNIX
|
||||
try
|
||||
{
|
||||
RegistryKey shellKey = Registry.LocalMachine.OpenSubKey(Utils.GetRegistryConfigurationPath(shellID));
|
||||
if (shellKey != null)
|
||||
{
|
||||
// verify the value kind as a string
|
||||
RegistryValueKind kind = shellKey.GetValueKind("path");
|
||||
|
||||
if (kind == RegistryValueKind.ExpandString ||
|
||||
kind == RegistryValueKind.String)
|
||||
{
|
||||
result = shellKey.GetValue("path") as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ignore these exceptions and return an empty or null result
|
||||
catch (SecurityException)
|
||||
{
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static PSModuleAutoLoadingPreference GetCommandDiscoveryPreference(ExecutionContext context, VariablePath variablePath, string environmentVariable)
|
||||
{
|
||||
Dbg.Assert(context != null, "context cannot be Null");
|
||||
|
||||
@@ -11,6 +11,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Management.Automation.Security;
|
||||
@@ -4749,28 +4750,18 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
moduleNames = null;
|
||||
ModuleLoggingGroupPolicyStatus status = ModuleLoggingGroupPolicyStatus.Undefined;
|
||||
Dictionary<string, object> groupPolicySettings = Utils.GetGroupPolicySetting("ModuleLogging", Utils.RegLocalMachineThenCurrentUser);
|
||||
|
||||
if (groupPolicySettings != null)
|
||||
var moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
if (moduleLogging != null)
|
||||
{
|
||||
object enableModuleLoggingValue = null;
|
||||
if (groupPolicySettings.TryGetValue("EnableModuleLogging", out enableModuleLoggingValue))
|
||||
if (moduleLogging.EnableModuleLogging == false)
|
||||
{
|
||||
if (String.Equals(enableModuleLoggingValue.ToString(), "0", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ModuleLoggingGroupPolicyStatus.Disabled;
|
||||
}
|
||||
|
||||
if (String.Equals(enableModuleLoggingValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
status = ModuleLoggingGroupPolicyStatus.Enabled;
|
||||
|
||||
object moduleNamesValue = null;
|
||||
if (groupPolicySettings.TryGetValue("ModuleNames", out moduleNamesValue))
|
||||
{
|
||||
moduleNames = new List<String>((string[])moduleNamesValue);
|
||||
}
|
||||
}
|
||||
status = ModuleLoggingGroupPolicyStatus.Disabled;
|
||||
}
|
||||
else if (moduleLogging.EnableModuleLogging == true)
|
||||
{
|
||||
status = ModuleLoggingGroupPolicyStatus.Enabled;
|
||||
moduleNames = moduleLogging.ModuleNames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Language;
|
||||
using Microsoft.PowerShell.Commands;
|
||||
@@ -977,8 +978,8 @@ namespace System.Management.Automation
|
||||
internal static string SetModulePath()
|
||||
{
|
||||
string currentModulePath = GetExpandedEnvironmentVariable(Constants.PSModulePathEnvVar, EnvironmentVariableTarget.Process);
|
||||
string systemWideModulePath = ConfigPropertyAccessor.Instance.GetModulePath(ConfigPropertyAccessor.PropertyScope.SystemWide);
|
||||
string personalModulePath = ConfigPropertyAccessor.Instance.GetModulePath(ConfigPropertyAccessor.PropertyScope.CurrentUser);
|
||||
string systemWideModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.SystemWide);
|
||||
string personalModulePath = PowerShellConfig.Instance.GetModulePath(ConfigScope.CurrentUser);
|
||||
|
||||
string newModulePathString = GetModulePath(currentModulePath, systemWideModulePath, personalModulePath);
|
||||
|
||||
|
||||
+191
-251
@@ -1,206 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Xml;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using Microsoft.Win32;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Management.Automation.Internal;
|
||||
|
||||
|
||||
namespace System.Management.Automation
|
||||
namespace System.Management.Automation.Configuration
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Leverages the strategy pattern to abstract away the details of gathering properties from outside sources.
|
||||
/// Note: This is a class so that it can be internal.
|
||||
/// </summary>
|
||||
internal abstract class ConfigPropertyAccessor
|
||||
internal enum ConfigScope
|
||||
{
|
||||
#region Statics
|
||||
/// <summary>
|
||||
/// Static constructor to instantiate an instance
|
||||
/// </summary>
|
||||
static ConfigPropertyAccessor()
|
||||
{
|
||||
Instance = new JsonConfigFileAccessor();
|
||||
}
|
||||
/// <summary>
|
||||
/// The instance of the ConfigPropertyAccessor to use to interact with properties.
|
||||
/// Derived classes should not be directly instantiated.
|
||||
/// </summary>
|
||||
internal static readonly ConfigPropertyAccessor Instance;
|
||||
// SystemWide configuration applies to all users.
|
||||
SystemWide = 0,
|
||||
|
||||
#endregion // Statics
|
||||
|
||||
#region Enums
|
||||
|
||||
/// <summary>
|
||||
/// Describes the scope of the property query.
|
||||
/// SystemWide properties apply to all users.
|
||||
/// CurrentUser properties apply to the current user that is impersonated.
|
||||
/// </summary>
|
||||
internal enum PropertyScope
|
||||
{
|
||||
SystemWide = 0,
|
||||
CurrentUser = 1
|
||||
}
|
||||
|
||||
#endregion // Enums
|
||||
|
||||
#region Interface Methods
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKLM:\System\CurrentControlSet\Control\Session Manager\Environment
|
||||
/// Proposed value = %ProgramFiles%\PowerShell\Modules by default
|
||||
///
|
||||
/// Note: There is no setter because this value is immutable.
|
||||
/// </summary>
|
||||
/// <returns>Module path values from the config file.</returns>
|
||||
internal abstract string GetModulePath(PropertyScope scope);
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKCU and HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
|
||||
/// Proposed value = Existing default execution policy if not already specified
|
||||
/// </summary>
|
||||
/// <param name="scope">Where it should check for the value.</param>
|
||||
/// <param name="shellId">The shell associated with this policy. Typically, it is "Microsoft.PowerShell"</param>
|
||||
/// <returns></returns>
|
||||
internal abstract string GetExecutionPolicy(PropertyScope scope, string shellId);
|
||||
internal abstract void RemoveExecutionPolicy(PropertyScope scope, string shellId);
|
||||
internal abstract void SetExecutionPolicy(PropertyScope scope, string shellId, string executionPolicy);
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKLM\SOFTWARE\Microsoft\PowerShell\1\ShellIds
|
||||
/// Proposed value = existing default. Probably "1"
|
||||
/// </summary>
|
||||
/// <returns>Whether console prompting should happen.</returns>
|
||||
internal abstract bool GetConsolePrompting();
|
||||
internal abstract void SetConsolePrompting(bool shouldPrompt);
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKLM\SOFTWARE\Microsoft\PowerShell
|
||||
/// Proposed value = Existing default. Probably "0"
|
||||
/// </summary>
|
||||
/// <returns>Boolean indicating whether Update-Help should prompt</returns>
|
||||
internal abstract bool GetDisablePromptToUpdateHelp();
|
||||
internal abstract void SetDisablePromptToUpdateHelp(bool prompt);
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKCU and HKLM\Software\Policies\Microsoft\Windows\PowerShell\UpdatableHelp
|
||||
/// Proposed value = blank.This should be supported though
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal abstract string GetDefaultSourcePath();
|
||||
internal abstract void SetDefaultSourcePath(string defaultPath);
|
||||
|
||||
#if UNIX
|
||||
/// <summary>
|
||||
/// Gets the application identity (name) to use for writing to syslog.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The string identity to use for writing to syslog.
|
||||
/// <para>
|
||||
/// The default value is 'powershell'
|
||||
/// </para>
|
||||
/// </returns>
|
||||
internal abstract string GetSysLogIdentity();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log level filter.
|
||||
/// </summary>
|
||||
/// <returns>One of the PSLevel values indicating the level to log.
|
||||
/// <para>
|
||||
/// The default value is PSLevel.Informational
|
||||
/// </para>
|
||||
/// </returns>
|
||||
internal abstract PSLevel GetLogLevel();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitmask of the PSChannel values to log.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A bitmask of PSChannel.Operational and/or PSChannel.Analytic
|
||||
/// <para>
|
||||
/// The default value is PSChannel.Operational
|
||||
/// </para>
|
||||
/// </returns>
|
||||
internal abstract PSChannel GetLogChannels();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bitmask of keywords to log.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A bitmask of PSKeyword values.
|
||||
/// <para>
|
||||
/// The default value is all keywords other than UseAlwaysAnalytic
|
||||
/// </para>
|
||||
/// </returns>
|
||||
internal abstract PSKeyword GetLogKeywords();
|
||||
|
||||
#endif // UNIX
|
||||
#endregion // Interface Methods
|
||||
// CurrentUser configuration applies to the current user.
|
||||
CurrentUser = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JSON configuration file accessor
|
||||
///
|
||||
/// Reads from and writes to configuration files. The values stored were
|
||||
/// originally stored in the Windows registry.
|
||||
/// Reads from and writes to the JSON configuration files.
|
||||
/// The config values were originally stored in the Windows registry.
|
||||
/// </summary>
|
||||
internal class JsonConfigFileAccessor : ConfigPropertyAccessor
|
||||
internal sealed class PowerShellConfig
|
||||
{
|
||||
// Provide a singleton
|
||||
private static readonly PowerShellConfig s_instance = new PowerShellConfig();
|
||||
internal static PowerShellConfig Instance => s_instance;
|
||||
|
||||
private string psHomeConfigDirectory;
|
||||
private string appDataConfigDirectory;
|
||||
private const string configFileName = "PowerShellProperties.json";
|
||||
private const string configFileName = "powershell.config.json";
|
||||
|
||||
/// <summary>
|
||||
/// Lock used to enable multiple concurrent readers and singular write locks within a
|
||||
/// single process.
|
||||
/// TODO: This solution only works for IO from a single process. A more robust solution is needed to enable ReaderWriterLockSlim behavior between processes.
|
||||
/// Lock used to enable multiple concurrent readers and singular write locks within a single process.
|
||||
/// TODO: This solution only works for IO from a single process.
|
||||
/// A more robust solution is needed to enable ReaderWriterLockSlim behavior between processes.
|
||||
/// </summary>
|
||||
private ReaderWriterLockSlim fileLock = new ReaderWriterLockSlim();
|
||||
|
||||
internal JsonConfigFileAccessor()
|
||||
private PowerShellConfig()
|
||||
{
|
||||
//
|
||||
// Sets the system-wide configuration directory
|
||||
//
|
||||
Assembly assembly = typeof(PSObject).GetTypeInfo().Assembly;
|
||||
psHomeConfigDirectory = Path.GetDirectoryName(assembly.Location);
|
||||
psHomeConfigDirectory = Utils.DefaultPowerShellAppBase;
|
||||
|
||||
//
|
||||
// Sets the per-user configuration directory
|
||||
// Note: This directory may or may not exist depending upon the
|
||||
// execution scenario. Writes will attempt to create the directory
|
||||
// if it does not already exist.
|
||||
//
|
||||
appDataConfigDirectory = Utils.GetUserConfigurationDirectory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This value is not writable via the API and must be set using a text editor.
|
||||
/// Existing Key = HKLM:\System\CurrentControlSet\Control\Session Manager\Environment
|
||||
/// Proposed value = %ProgramFiles%\PowerShell\Modules by default
|
||||
/// Note: There is no setter because this value is immutable.
|
||||
/// </summary>
|
||||
/// <param name="scope"></param>
|
||||
/// <param name="scope">Whether this is a system-wide or per-user setting.</param>
|
||||
/// <returns>Value if found, null otherwise. The behavior matches ModuleIntrinsics.GetExpandedEnvironmentVariable().</returns>
|
||||
internal override string GetModulePath(PropertyScope scope)
|
||||
internal string GetModulePath(ConfigScope scope)
|
||||
{
|
||||
string scopeDirectory = psHomeConfigDirectory;
|
||||
|
||||
// Defaults to system wide.
|
||||
if (PropertyScope.CurrentUser == scope)
|
||||
{
|
||||
scopeDirectory = appDataConfigDirectory;
|
||||
}
|
||||
|
||||
string scopeDirectory = scope == ConfigScope.SystemWide ? psHomeConfigDirectory : appDataConfigDirectory;
|
||||
string fileName = Path.Combine(scopeDirectory, configFileName);
|
||||
|
||||
string modulePath = ReadValueFromFile<string>(fileName, Constants.PSModulePathEnvVar);
|
||||
@@ -217,7 +76,7 @@ namespace System.Management.Automation
|
||||
///
|
||||
/// Schema:
|
||||
/// {
|
||||
/// "shell ID string","ExecutionPolicy" : "execution policy string"
|
||||
/// "shell-ID-string:ExecutionPolicy" : "execution policy string"
|
||||
/// }
|
||||
///
|
||||
/// TODO: In a single config file, it might be better to nest this. It is unnecessary complexity until a need arises for more nested values.
|
||||
@@ -225,13 +84,13 @@ namespace System.Management.Automation
|
||||
/// <param name="scope">Whether this is a system-wide or per-user setting.</param>
|
||||
/// <param name="shellId">The shell associated with this policy. Typically, it is "Microsoft.PowerShell"</param>
|
||||
/// <returns>The execution policy if found. Null otherwise.</returns>
|
||||
internal override string GetExecutionPolicy(PropertyScope scope, string shellId)
|
||||
internal string GetExecutionPolicy(ConfigScope scope, string shellId)
|
||||
{
|
||||
string execPolicy = null;
|
||||
string scopeDirectory = psHomeConfigDirectory;
|
||||
|
||||
// Defaults to system wide.
|
||||
if(PropertyScope.CurrentUser == scope)
|
||||
if(ConfigScope.CurrentUser == scope)
|
||||
{
|
||||
scopeDirectory = appDataConfigDirectory;
|
||||
}
|
||||
@@ -247,12 +106,12 @@ namespace System.Management.Automation
|
||||
return execPolicy;
|
||||
}
|
||||
|
||||
internal override void RemoveExecutionPolicy(PropertyScope scope, string shellId)
|
||||
internal void RemoveExecutionPolicy(ConfigScope scope, string shellId)
|
||||
{
|
||||
string scopeDirectory = psHomeConfigDirectory;
|
||||
|
||||
// Defaults to system wide.
|
||||
if (PropertyScope.CurrentUser == scope)
|
||||
if (ConfigScope.CurrentUser == scope)
|
||||
{
|
||||
scopeDirectory = appDataConfigDirectory;
|
||||
}
|
||||
@@ -262,12 +121,12 @@ namespace System.Management.Automation
|
||||
RemoveValueFromFile<string>(fileName, valueName);
|
||||
}
|
||||
|
||||
internal override void SetExecutionPolicy(PropertyScope scope, string shellId, string executionPolicy)
|
||||
internal void SetExecutionPolicy(ConfigScope scope, string shellId, string executionPolicy)
|
||||
{
|
||||
string scopeDirectory = psHomeConfigDirectory;
|
||||
|
||||
// Defaults to system wide.
|
||||
if (PropertyScope.CurrentUser == scope)
|
||||
if (ConfigScope.CurrentUser == scope)
|
||||
{
|
||||
// Exceptions are not caught so that they will propagate to the
|
||||
// host for display to the user.
|
||||
@@ -292,13 +151,13 @@ namespace System.Management.Automation
|
||||
/// }
|
||||
/// </summary>
|
||||
/// <returns>Whether console prompting should happen. If the value cannot be read it defaults to false.</returns>
|
||||
internal override bool GetConsolePrompting()
|
||||
internal bool GetConsolePrompting()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
return ReadValueFromFile<bool>(fileName, "ConsolePrompting");
|
||||
}
|
||||
|
||||
internal override void SetConsolePrompting(bool shouldPrompt)
|
||||
internal void SetConsolePrompting(bool shouldPrompt)
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
WriteValueToFile<bool>(fileName, "ConsolePrompting", shouldPrompt);
|
||||
@@ -314,46 +173,26 @@ namespace System.Management.Automation
|
||||
/// }
|
||||
/// </summary>
|
||||
/// <returns>Boolean indicating whether Update-Help should prompt. If the value cannot be read, it defaults to false.</returns>
|
||||
internal override bool GetDisablePromptToUpdateHelp()
|
||||
internal bool GetDisablePromptToUpdateHelp()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
return ReadValueFromFile<bool>(fileName, "DisablePromptToUpdateHelp");
|
||||
}
|
||||
|
||||
internal override void SetDisablePromptToUpdateHelp(bool prompt)
|
||||
internal void SetDisablePromptToUpdateHelp(bool prompt)
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
WriteValueToFile<bool>(fileName, "DisablePromptToUpdateHelp", prompt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Existing Key = HKCU and HKLM\Software\Policies\Microsoft\Windows\PowerShell\UpdatableHelp
|
||||
/// Proposed value = blank.This should be supported though
|
||||
///
|
||||
/// Schema:
|
||||
/// {
|
||||
/// "DefaultSourcePath" : "path to local updatable help location"
|
||||
/// }
|
||||
/// Corresponding settings of the original Group Policies
|
||||
/// </summary>
|
||||
/// <returns>The source path if found, null otherwise.</returns>
|
||||
internal override string GetDefaultSourcePath()
|
||||
internal PowerShellPolicies GetPowerShellPolicies(ConfigScope scope)
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
|
||||
string rawExecPolicy = ReadValueFromFile<string>(fileName, "DefaultSourcePath");
|
||||
|
||||
if (!String.IsNullOrEmpty(rawExecPolicy))
|
||||
{
|
||||
return rawExecPolicy;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override void SetDefaultSourcePath(string defaultPath)
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
|
||||
WriteValueToFile<string>(fileName, "DefaultSourcePath", defaultPath);
|
||||
string scopeDirectory = (scope == ConfigScope.SystemWide) ? psHomeConfigDirectory : appDataConfigDirectory;
|
||||
string fileName = Path.Combine(scopeDirectory, configFileName);
|
||||
return ReadValueFromFile<PowerShellPolicies>(fileName, nameof(PowerShellPolicies));
|
||||
}
|
||||
|
||||
#if UNIX
|
||||
@@ -361,12 +200,9 @@ namespace System.Management.Automation
|
||||
/// Gets the identity name to use for writing to syslog.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The string identity to use for writing to syslog.
|
||||
/// <para>
|
||||
/// The default value is 'powershell'.
|
||||
/// </para>
|
||||
/// The string identity to use for writing to syslog. The default value is 'powershell'.
|
||||
/// </returns>
|
||||
internal override string GetSysLogIdentity()
|
||||
internal string GetSysLogIdentity()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
string identity = ReadValueFromFile<string>(fileName, "LogIdentity");
|
||||
@@ -382,12 +218,10 @@ namespace System.Management.Automation
|
||||
/// <summary>
|
||||
/// Gets the log level filter.
|
||||
/// </summary>
|
||||
/// <returns>One of the PSLevel values indicating the level to log.
|
||||
/// <para>
|
||||
/// The default value is PSLevel.Informational.
|
||||
/// </para>
|
||||
/// <returns>
|
||||
/// One of the PSLevel values indicating the level to log. The default value is PSLevel.Informational.
|
||||
/// </returns>
|
||||
internal override PSLevel GetLogLevel()
|
||||
internal PSLevel GetLogLevel()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
string levelName = ReadValueFromFile<string>(fileName, "LogLevel");
|
||||
@@ -418,12 +252,9 @@ namespace System.Management.Automation
|
||||
/// Gets the bitmask of the PSChannel values to log.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A bitmask of PSChannel.Operational and/or PSChannel.Analytic.
|
||||
/// <para>
|
||||
/// The default value is PSChannel.Operational.
|
||||
/// </para>
|
||||
/// A bitmask of PSChannel.Operational and/or PSChannel.Analytic. The default value is PSChannel.Operational.
|
||||
/// </returns>
|
||||
internal override PSChannel GetLogChannels()
|
||||
internal PSChannel GetLogChannels()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
string values = ReadValueFromFile<string>(fileName, "LogChannels");
|
||||
@@ -464,12 +295,9 @@ namespace System.Management.Automation
|
||||
/// Gets the bitmask of keywords to log.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A bitmask of PSKeyword values.
|
||||
/// <para>
|
||||
/// The default value is all keywords other than UseAlwaysAnalytic.
|
||||
/// </para>
|
||||
/// A bitmask of PSKeyword values. The default value is all keywords other than UseAlwaysAnalytic.
|
||||
/// </returns>
|
||||
internal override PSKeyword GetLogKeywords()
|
||||
internal PSKeyword GetLogKeywords()
|
||||
{
|
||||
string fileName = Path.Combine(psHomeConfigDirectory, configFileName);
|
||||
string values = ReadValueFromFile<string>(fileName, "LogKeywords");
|
||||
@@ -502,48 +330,36 @@ namespace System.Management.Automation
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // UNIX
|
||||
|
||||
private T ReadValueFromFile<T>(string fileName, string key)
|
||||
|
||||
private T ReadValueFromFile<T>(string fileName, string key, T defaultValue = default(T),
|
||||
Func<JToken, JsonSerializer, T, T> readImpl = null)
|
||||
{
|
||||
if (!File.Exists(fileName)) { return defaultValue; }
|
||||
|
||||
// Open file for reading, but allow multiple readers
|
||||
fileLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
// Open file for reading, but allow multiple readers
|
||||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
using (StreamReader streamRdr = new StreamReader(fs))
|
||||
using (JsonTextReader jsonReader = new JsonTextReader(streamRdr))
|
||||
using (var streamReader = new StreamReader(fileName))
|
||||
using (var jsonReader = new JsonTextReader(streamReader))
|
||||
{
|
||||
// Safely determines whether there is content to read from the file
|
||||
bool isReadSuccess = jsonReader.Read();
|
||||
if (isReadSuccess)
|
||||
var settings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.None, MaxDepth = 10 };
|
||||
var serializer = JsonSerializer.Create(settings);
|
||||
|
||||
var configData = serializer.Deserialize<JObject>(jsonReader);
|
||||
if (configData != null && configData.TryGetValue(key, StringComparison.OrdinalIgnoreCase, out JToken jToken))
|
||||
{
|
||||
JObject jsonObject = (JObject) JToken.ReadFrom(jsonReader);
|
||||
JToken value = jsonObject.GetValue(key);
|
||||
if (null != value)
|
||||
{
|
||||
return value.ToObject<T>();
|
||||
}
|
||||
return readImpl != null ? readImpl(jToken, serializer, defaultValue) : jToken.ToObject<T>(serializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
// The file doesn't exist. Treat this the same way as if the
|
||||
// key was not present in the file.
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
// A directory in the path does not exist. Treat this as if the
|
||||
// key is not present in the file.
|
||||
}
|
||||
finally
|
||||
{
|
||||
fileLock.ExitReadLock();
|
||||
}
|
||||
|
||||
return default(T);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -677,5 +493,129 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Namespace System.Management.Automation
|
||||
|
||||
#region GroupPolicy Configs
|
||||
|
||||
/// <summary>
|
||||
/// The GroupPolicy related settings used in PowerShell are as follows in Registry:
|
||||
/// - Software\Policies\Microsoft\PowerShellCore -- { EnableScripts (0 or 1); ExecutionPolicy (string) }
|
||||
/// SubKeys Name-Value-Pairs
|
||||
/// - ScriptBlockLogging { EnableScriptBlockLogging (0 or 1); EnableScriptBlockInvocationLogging (0 or 1) }
|
||||
/// - ModuleLogging { EnableModuleLogging (0 or 1); ModuleNames (string[]) }
|
||||
/// - Transcription { EnableTranscripting (0 or 1); OutputDirectory (string); EnableInvocationHeader (0 or 1) }
|
||||
/// - UpdatableHelp { DefaultSourcePath (string) }
|
||||
/// - ConsoleSessionConfiguration { EnableConsoleSessionConfiguration (0 or 1); ConsoleSessionConfigurationName (string) }
|
||||
/// - Software\Policies\Microsoft\Windows\EventLog
|
||||
/// SubKeys Name-Value-Pairs
|
||||
/// - ProtectedEventLogging { EnableProtectedEventLogging (0 or 1); EncryptionCertificate (string[]) }
|
||||
///
|
||||
/// The JSON representation is in sync with the 'PowerShellPolicies' type. Here is an example:
|
||||
/// {
|
||||
/// "PowerShellPolicies": {
|
||||
/// "ScriptExecution": {
|
||||
/// "ExecutionPolicy": "RemoteSigned"
|
||||
/// },
|
||||
/// "ScriptBlockLogging": {
|
||||
/// "EnableScriptBlockInvocationLogging": true,
|
||||
/// "EnableScriptBlockLogging": false
|
||||
/// },
|
||||
/// "ProtectedEventLogging": {
|
||||
/// "EnableProtectedEventLogging": false,
|
||||
/// "EncryptionCertificate": [
|
||||
/// "Joe"
|
||||
/// ]
|
||||
/// },
|
||||
/// "Transcription": {
|
||||
/// "EnableTranscripting": true,
|
||||
/// "EnableInvocationHeader": true,
|
||||
/// "OutputDirectory": "c:\\tmp"
|
||||
/// },
|
||||
/// "UpdatableHelp": {
|
||||
/// "DefaultSourcePath": "f:\\temp"
|
||||
/// },
|
||||
/// "ConsoleSessionConfiguration": {
|
||||
/// "EnableConsoleSessionConfiguration": true,
|
||||
/// "ConsoleSessionConfigurationName": "name"
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </summary>
|
||||
internal sealed class PowerShellPolicies
|
||||
{
|
||||
public ScriptExecution ScriptExecution { get; set; }
|
||||
public ScriptBlockLogging ScriptBlockLogging { get; set; }
|
||||
public ModuleLogging ModuleLogging { get; set; }
|
||||
public ProtectedEventLogging ProtectedEventLogging { get; set; }
|
||||
public Transcription Transcription { get; set; }
|
||||
public UpdatableHelp UpdatableHelp { get; set; }
|
||||
public ConsoleSessionConfiguration ConsoleSessionConfiguration { get; set; }
|
||||
}
|
||||
|
||||
internal abstract class PolicyBase { }
|
||||
|
||||
/// <summary>
|
||||
/// Setting about ScriptExecution
|
||||
/// </summary>
|
||||
internal sealed class ScriptExecution : PolicyBase
|
||||
{
|
||||
public string ExecutionPolicy { get; set; }
|
||||
public bool? EnableScripts { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about ScriptBlockLogging
|
||||
/// </summary>
|
||||
internal sealed class ScriptBlockLogging : PolicyBase
|
||||
{
|
||||
public bool? EnableScriptBlockInvocationLogging { get; set; }
|
||||
public bool? EnableScriptBlockLogging { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about ModuleLogging
|
||||
/// </summary>
|
||||
internal sealed class ModuleLogging : PolicyBase
|
||||
{
|
||||
public bool? EnableModuleLogging { get; set; }
|
||||
public string[] ModuleNames { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about Transcription
|
||||
/// </summary>
|
||||
internal sealed class Transcription : PolicyBase
|
||||
{
|
||||
public bool? EnableTranscripting { get; set; }
|
||||
public bool? EnableInvocationHeader { get; set; }
|
||||
public string OutputDirectory { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about UpdatableHelp
|
||||
/// </summary>
|
||||
internal sealed class UpdatableHelp : PolicyBase
|
||||
{
|
||||
public bool? EnableUpdateHelpDefaultSourcePath { get; set; }
|
||||
public string DefaultSourcePath { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about ConsoleSessionConfiguration
|
||||
/// </summary>
|
||||
internal sealed class ConsoleSessionConfiguration : PolicyBase
|
||||
{
|
||||
public bool? EnableConsoleSessionConfiguration { get; set; }
|
||||
public string ConsoleSessionConfigurationName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Setting about ProtectedEventLogging
|
||||
/// </summary>
|
||||
internal sealed class ProtectedEventLogging : PolicyBase
|
||||
{
|
||||
public bool? EnableProtectedEventLogging { get; set; }
|
||||
public string[] EncryptionCertificate { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -5,6 +5,7 @@ Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
using System.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Security;
|
||||
using System.Reflection;
|
||||
@@ -233,12 +234,11 @@ namespace System.Management.Automation
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static string DefaultPowerShellAppBase { get; } = GetApplicationBase(DefaultPowerShellShellID);
|
||||
|
||||
internal static string DefaultPowerShellAppBase => GetApplicationBase(DefaultPowerShellShellID);
|
||||
internal static string GetApplicationBase(string shellId)
|
||||
{
|
||||
// Use the location of SMA.dll as the application base.
|
||||
Assembly assembly = typeof(PSObject).GetTypeInfo().Assembly;
|
||||
Assembly assembly = typeof(PSObject).Assembly;
|
||||
return Path.GetDirectoryName(assembly.Location);
|
||||
}
|
||||
|
||||
@@ -497,125 +497,210 @@ namespace System.Management.Automation
|
||||
/// </summary>
|
||||
internal static string ModuleDirectory = Path.Combine(ProductNameForDirectory, "Modules");
|
||||
|
||||
internal static string GetRegistryConfigurationPrefix()
|
||||
{
|
||||
// For 3.0 PowerShell, we still use "1" as the registry version key for
|
||||
// Snapin and Custom shell lookup/discovery.
|
||||
// For 3.0 PowerShell, we use "3" as the registry version key only for Engine
|
||||
// related data like ApplicationBase etc.
|
||||
return "SOFTWARE\\Microsoft\\PowerShell\\" + PSVersionInfo.RegistryVersion1Key + "\\ShellIds";
|
||||
}
|
||||
internal readonly static ConfigScope[] SystemWideOnlyConfig = new[] { ConfigScope.SystemWide };
|
||||
internal readonly static ConfigScope[] CurrentUserOnlyConfig = new[] { ConfigScope.CurrentUser };
|
||||
internal readonly static ConfigScope[] SystemWideThenCurrentUserConfig = new[] { ConfigScope.SystemWide, ConfigScope.CurrentUser };
|
||||
internal readonly static ConfigScope[] CurrentUserThenSystemWideConfig = new[] { ConfigScope.CurrentUser, ConfigScope.SystemWide };
|
||||
|
||||
internal static string GetRegistryConfigurationPath(string shellID)
|
||||
internal static T GetPolicySetting<T>(ConfigScope[] preferenceOrder) where T : PolicyBase, new()
|
||||
{
|
||||
return GetRegistryConfigurationPrefix() + "\\" + shellID;
|
||||
}
|
||||
|
||||
// Calling static members of 'Registry' on UNIX will raise 'PlatformNotSupportedException'
|
||||
#if UNIX
|
||||
internal static RegistryKey[] RegLocalMachine = null;
|
||||
internal static RegistryKey[] RegCurrentUser = null;
|
||||
internal static RegistryKey[] RegLocalMachineThenCurrentUser = null;
|
||||
internal static RegistryKey[] RegCurrentUserThenLocalMachine = null;
|
||||
#else
|
||||
internal static RegistryKey[] RegLocalMachine = new[] { Registry.LocalMachine };
|
||||
internal static RegistryKey[] RegCurrentUser = new[] { Registry.CurrentUser };
|
||||
internal static RegistryKey[] RegLocalMachineThenCurrentUser = new[] { Registry.LocalMachine, Registry.CurrentUser };
|
||||
internal static RegistryKey[] RegCurrentUserThenLocalMachine = new[] { Registry.CurrentUser, Registry.LocalMachine };
|
||||
T policy = null;
|
||||
#if !UNIX
|
||||
// On Windows, group policy settings from registry take precedence.
|
||||
// If the requested policy is not defined in registry, we query the configuration file.
|
||||
policy = GetPolicySettingFromGPO<T>(preferenceOrder);
|
||||
if (policy != null) { return policy; }
|
||||
#endif
|
||||
|
||||
internal static Dictionary<string, object> GetGroupPolicySetting(string settingName, RegistryKey[] preferenceOrder)
|
||||
{
|
||||
string groupPolicyBase = "Software\\Policies\\Microsoft\\Windows\\PowerShell";
|
||||
return GetGroupPolicySetting(groupPolicyBase, settingName, preferenceOrder);
|
||||
policy = GetPolicySettingFromConfigFile<T>(preferenceOrder);
|
||||
return policy;
|
||||
}
|
||||
|
||||
// We use a static to avoid creating "extra garbage."
|
||||
private static Dictionary<string, object> s_emptyDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly static ConcurrentDictionary<ConfigScope, PowerShellPolicies> s_cachedPoliciesFromConfigFile =
|
||||
new ConcurrentDictionary<ConfigScope, PowerShellPolicies>();
|
||||
|
||||
internal static Dictionary<string, object> GetGroupPolicySetting(string groupPolicyBase, string settingName, RegistryKey[] preferenceOrder)
|
||||
/// <summary>
|
||||
/// Get a specific kind of policy setting from the configuration file.
|
||||
/// </summary>
|
||||
private static T GetPolicySettingFromConfigFile<T>(ConfigScope[] preferenceOrder) where T : PolicyBase, new()
|
||||
{
|
||||
#if UNIX
|
||||
return s_emptyDictionary;
|
||||
#else
|
||||
lock (s_cachedGroupPolicySettings)
|
||||
foreach (ConfigScope scope in preferenceOrder)
|
||||
{
|
||||
// Return cached information, if we have it
|
||||
Dictionary<string, object> settings;
|
||||
if ((s_cachedGroupPolicySettings.TryGetValue(settingName, out settings)) &&
|
||||
!InternalTestHooks.BypassGroupPolicyCaching)
|
||||
PowerShellPolicies policies;
|
||||
if (InternalTestHooks.BypassGroupPolicyCaching)
|
||||
{
|
||||
return settings;
|
||||
policies = PowerShellConfig.Instance.GetPowerShellPolicies(scope);
|
||||
}
|
||||
|
||||
if (!String.Equals(".", settingName, StringComparison.OrdinalIgnoreCase))
|
||||
else if (!s_cachedPoliciesFromConfigFile.TryGetValue(scope, out policies))
|
||||
{
|
||||
groupPolicyBase += "\\" + settingName;
|
||||
}
|
||||
|
||||
settings = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (RegistryKey searchKey in preferenceOrder)
|
||||
{
|
||||
try
|
||||
// Use lock here to reduce the contention on accessing the configuration file
|
||||
lock (s_cachedPoliciesFromConfigFile)
|
||||
{
|
||||
// Look up the machine-wide group policy
|
||||
using (RegistryKey key = searchKey.OpenSubKey(groupPolicyBase))
|
||||
policies = s_cachedPoliciesFromConfigFile.GetOrAdd(scope, PowerShellConfig.Instance.GetPowerShellPolicies);
|
||||
}
|
||||
}
|
||||
|
||||
if (policies != null)
|
||||
{
|
||||
PolicyBase result = null;
|
||||
switch (typeof(T).Name)
|
||||
{
|
||||
case nameof(ScriptExecution): result = policies.ScriptExecution; break;
|
||||
case nameof(ScriptBlockLogging): result = policies.ScriptBlockLogging; break;
|
||||
case nameof(ModuleLogging): result = policies.ModuleLogging; break;
|
||||
case nameof(ProtectedEventLogging): result = policies.ProtectedEventLogging; break;
|
||||
case nameof(Transcription): result = policies.Transcription; break;
|
||||
case nameof(UpdatableHelp): result = policies.UpdatableHelp; break;
|
||||
case nameof(ConsoleSessionConfiguration): result = policies.ConsoleSessionConfiguration; break;
|
||||
default: Diagnostics.Assert(false, "Should be unreachable code. Update this switch block when new PowerShell policy types are added."); break;
|
||||
}
|
||||
if (result != null) { return (T) result; }
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#if !UNIX
|
||||
private static readonly Dictionary<string, string> GroupPolicyKeys = new Dictionary<string, string>
|
||||
{
|
||||
{nameof(ScriptExecution), @"Software\Policies\Microsoft\PowerShellCore"},
|
||||
{nameof(ScriptBlockLogging), @"Software\Policies\Microsoft\PowerShellCore\ScriptBlockLogging"},
|
||||
{nameof(ModuleLogging), @"Software\Policies\Microsoft\PowerShellCore\ModuleLogging"},
|
||||
{nameof(ProtectedEventLogging), @"Software\Policies\Microsoft\Windows\EventLog\ProtectedEventLogging"},
|
||||
{nameof(Transcription), @"Software\Policies\Microsoft\PowerShellCore\Transcription"},
|
||||
{nameof(UpdatableHelp), @"Software\Policies\Microsoft\PowerShellCore\UpdatableHelp"},
|
||||
{nameof(ConsoleSessionConfiguration), @"Software\Policies\Microsoft\PowerShellCore\ConsoleSessionConfiguration"}
|
||||
};
|
||||
private readonly static ConcurrentDictionary<Tuple<ConfigScope, string>, PolicyBase> s_cachedPoliciesFromRegistry =
|
||||
new ConcurrentDictionary<Tuple<ConfigScope, string>, PolicyBase>();
|
||||
|
||||
/// <summary>
|
||||
/// The implementation of fetching a specific kind of policy setting from the given configuration scope.
|
||||
/// </summary>
|
||||
private static T GetPolicySettingFromGPOImpl<T>(ConfigScope scope) where T : PolicyBase, new()
|
||||
{
|
||||
Type tType = typeof(T);
|
||||
// SystemWide scope means 'LocalMachine' root key when query from registry
|
||||
RegistryKey rootKey = (scope == ConfigScope.SystemWide) ? Registry.LocalMachine : Registry.CurrentUser;
|
||||
|
||||
GroupPolicyKeys.TryGetValue(tType.Name, out string gpoKeyPath);
|
||||
Diagnostics.Assert(gpoKeyPath != null, StringUtil.Format("The GPO registry key path should be pre-defined for {0}", tType.Name));
|
||||
|
||||
using (RegistryKey gpoKey = rootKey.OpenSubKey(gpoKeyPath))
|
||||
{
|
||||
// If the corresponding GPO key doesn't exist, return null
|
||||
if (gpoKey == null) { return null; }
|
||||
|
||||
// The corresponding GPO key exists, then create an instance of T
|
||||
// and populate its properties with the settings
|
||||
object tInstance = Activator.CreateInstance(tType, nonPublic: true);
|
||||
var properties = tType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
bool isAnyPropertySet = false;
|
||||
|
||||
string[] valueNames = gpoKey.GetValueNames();
|
||||
string[] subKeyNames = gpoKey.GetSubKeyNames();
|
||||
var valueNameSet = valueNames.Length > 0 ? new HashSet<string>(valueNames, StringComparer.OrdinalIgnoreCase) : null;
|
||||
var subKeyNameSet = subKeyNames.Length > 0 ? new HashSet<string>(subKeyNames, StringComparer.OrdinalIgnoreCase) : null;
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
string settingName = property.Name;
|
||||
object rawRegistryValue = null;
|
||||
|
||||
// Get the raw value from registry.
|
||||
if (valueNameSet != null && valueNameSet.Contains(settingName))
|
||||
{
|
||||
rawRegistryValue = gpoKey.GetValue(settingName);
|
||||
}
|
||||
else if (subKeyNameSet != null && subKeyNameSet.Contains(settingName))
|
||||
{
|
||||
using (RegistryKey subKey = gpoKey.OpenSubKey(settingName))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
foreach (string subkeyName in key.GetValueNames())
|
||||
{
|
||||
// A null or empty subkey name string corresponds to a (Default) key.
|
||||
// If it is null, make it an empty string which the Dictionary can handle.
|
||||
string keyName = subkeyName ?? string.Empty;
|
||||
|
||||
settings[keyName] = key.GetValue(keyName);
|
||||
}
|
||||
|
||||
foreach (string subkeyName in key.GetSubKeyNames())
|
||||
{
|
||||
// A null or empty subkey name string corresponds to a (Default) key.
|
||||
// If it is null, make it an empty string which the Dictionary can handle.
|
||||
string keyName = subkeyName ?? string.Empty;
|
||||
|
||||
using (RegistryKey subkey = key.OpenSubKey(keyName))
|
||||
{
|
||||
if (subkey != null)
|
||||
{
|
||||
settings[keyName] = subkey.GetValueNames();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (subKey != null) { rawRegistryValue = subKey.GetValueNames(); }
|
||||
}
|
||||
}
|
||||
catch (System.Security.SecurityException)
|
||||
|
||||
// Get the actual property value based on the property type.
|
||||
// If the final property value is not null, then set the property.
|
||||
if (rawRegistryValue != null)
|
||||
{
|
||||
// User doesn't have access to open group policy key
|
||||
Type propertyType = property.PropertyType;
|
||||
object propertyValue = null;
|
||||
|
||||
switch (propertyType)
|
||||
{
|
||||
case var _ when propertyType == typeof(bool?):
|
||||
if (rawRegistryValue is int rawIntValue)
|
||||
{
|
||||
if (rawIntValue == 1) { propertyValue = true; }
|
||||
else if (rawIntValue == 0) { propertyValue = false; }
|
||||
}
|
||||
break;
|
||||
case var _ when propertyType == typeof(string):
|
||||
if (rawRegistryValue is string rawStringValue)
|
||||
{
|
||||
propertyValue = rawStringValue;
|
||||
}
|
||||
break;
|
||||
case var _ when propertyType == typeof(string[]):
|
||||
if (rawRegistryValue is string[] rawStringArrayValue)
|
||||
{
|
||||
propertyValue = rawStringArrayValue;
|
||||
}
|
||||
else if (rawRegistryValue is string stringValue)
|
||||
{
|
||||
propertyValue = new string[] { stringValue };
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Diagnostics.Assert(false, "Should be unreachable code. Update this switch block when properties of new types are added to PowerShell policy types.");
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the property if the value is not null
|
||||
if (propertyValue != null)
|
||||
{
|
||||
property.SetValue(tInstance, propertyValue);
|
||||
isAnyPropertySet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No group policy settings, then return null
|
||||
if (settings.Count == 0)
|
||||
{
|
||||
settings = null;
|
||||
}
|
||||
|
||||
// Cache the data
|
||||
if (!InternalTestHooks.BypassGroupPolicyCaching)
|
||||
{
|
||||
s_cachedGroupPolicySettings[settingName] = settings;
|
||||
}
|
||||
|
||||
return settings;
|
||||
// If no property is set, then we consider this policy as undefined
|
||||
return isAnyPropertySet ? (T) tInstance : null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
private static ConcurrentDictionary<string, Dictionary<string, object>> s_cachedGroupPolicySettings =
|
||||
new ConcurrentDictionary<string, Dictionary<string, object>>();
|
||||
|
||||
/// <summary>
|
||||
/// Get a specific kind of policy setting from the group policy registry key.
|
||||
/// </summary>
|
||||
private static T GetPolicySettingFromGPO<T>(ConfigScope[] preferenceOrder) where T : PolicyBase, new()
|
||||
{
|
||||
PolicyBase policy = null;
|
||||
foreach (ConfigScope scope in preferenceOrder)
|
||||
{
|
||||
if (InternalTestHooks.BypassGroupPolicyCaching)
|
||||
{
|
||||
policy = GetPolicySettingFromGPOImpl<T>(scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
var key = Tuple.Create(scope, typeof(T).Name);
|
||||
if (!s_cachedPoliciesFromRegistry.TryGetValue(key, out policy))
|
||||
{
|
||||
lock (s_cachedPoliciesFromRegistry)
|
||||
{
|
||||
policy = s_cachedPoliciesFromRegistry.GetOrAdd(key, tuple => GetPolicySettingFromGPOImpl<T>(tuple.Item1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (policy != null) { return (T) policy; }
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Scheduled job module name.
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace System.Management.Automation.Runspaces
|
||||
RegistryKey key;
|
||||
try
|
||||
{
|
||||
key = Registry.LocalMachine.OpenSubKey(Utils.GetRegistryConfigurationPrefix());
|
||||
key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds");
|
||||
}
|
||||
catch (System.Security.SecurityException)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Security;
|
||||
using System.Globalization;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using Microsoft.PowerShell.Commands;
|
||||
using System.Threading;
|
||||
@@ -909,9 +910,8 @@ namespace System.Management.Automation.Host
|
||||
/// </summary>
|
||||
internal static TranscriptionOption GetSystemTranscriptOption(TranscriptionOption currentTranscript)
|
||||
{
|
||||
Dictionary<string, object> groupPolicySettings = Utils.GetGroupPolicySetting("Transcription", Utils.RegLocalMachineThenCurrentUser);
|
||||
|
||||
if (groupPolicySettings != null)
|
||||
var transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
if (transcription != null)
|
||||
{
|
||||
// If we have an existing system transcript for this process, use that.
|
||||
// Otherwise, populate the static variable with the result of the group policy setting.
|
||||
@@ -921,7 +921,7 @@ namespace System.Management.Automation.Host
|
||||
{
|
||||
if (systemTranscript == null)
|
||||
{
|
||||
systemTranscript = PSHostUserInterface.GetTranscriptOptionFromSettings(groupPolicySettings, currentTranscript);
|
||||
systemTranscript = PSHostUserInterface.GetTranscriptOptionFromSettings(transcription, currentTranscript);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -931,44 +931,31 @@ namespace System.Management.Automation.Host
|
||||
internal static TranscriptionOption systemTranscript = null;
|
||||
private static Object s_systemTranscriptLock = new Object();
|
||||
|
||||
private static TranscriptionOption GetTranscriptOptionFromSettings(Dictionary<string, object> settings, TranscriptionOption currentTranscript)
|
||||
private static TranscriptionOption GetTranscriptOptionFromSettings(Transcription transcriptConfig, TranscriptionOption currentTranscript)
|
||||
{
|
||||
TranscriptionOption transcript = null;
|
||||
|
||||
object keyValue = null;
|
||||
if (settings.TryGetValue("EnableTranscripting", out keyValue))
|
||||
if (transcriptConfig.EnableTranscripting == true)
|
||||
{
|
||||
if (String.Equals(keyValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
|
||||
if (currentTranscript != null)
|
||||
{
|
||||
if (currentTranscript != null)
|
||||
{
|
||||
return currentTranscript;
|
||||
}
|
||||
|
||||
transcript = new TranscriptionOption();
|
||||
|
||||
// Pull out the transcript path
|
||||
object outputDirectoryValue = null;
|
||||
if (settings.TryGetValue("OutputDirectory", out outputDirectoryValue))
|
||||
{
|
||||
string outputDirectoryString = outputDirectoryValue as string;
|
||||
transcript.Path = GetTranscriptPath(outputDirectoryString, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
transcript.Path = GetTranscriptPath();
|
||||
}
|
||||
|
||||
// Pull out the "enable invocation header"
|
||||
object enableInvocationHeaderValue = null;
|
||||
if (settings.TryGetValue("EnableInvocationHeader", out enableInvocationHeaderValue))
|
||||
{
|
||||
if (String.Equals("1", enableInvocationHeaderValue.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
transcript.IncludeInvocationHeader = true;
|
||||
}
|
||||
}
|
||||
return currentTranscript;
|
||||
}
|
||||
|
||||
transcript = new TranscriptionOption();
|
||||
|
||||
// Pull out the transcript path
|
||||
if (transcriptConfig.OutputDirectory != null)
|
||||
{
|
||||
transcript.Path = GetTranscriptPath(transcriptConfig.OutputDirectory, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
transcript.Path = GetTranscriptPath();
|
||||
}
|
||||
|
||||
// Pull out the "enable invocation header"
|
||||
transcript.IncludeInvocationHeader = transcriptConfig.EnableInvocationHeader == true;
|
||||
}
|
||||
|
||||
return transcript;
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Language;
|
||||
using System.Management.Automation.Runspaces;
|
||||
@@ -1234,13 +1235,14 @@ namespace System.Management.Automation
|
||||
|
||||
internal static void LogScriptBlockCreation(ScriptBlock scriptBlock, bool force)
|
||||
{
|
||||
if (force || ShouldLogScriptBlockActivity("EnableScriptBlockLogging"))
|
||||
ScriptBlockLogging logSetting = GetScriptBlockLoggingSetting();
|
||||
if (force || logSetting?.EnableScriptBlockLogging == true)
|
||||
{
|
||||
if (!scriptBlock.HasLogged || InternalTestHooks.ForceScriptBlockLogging)
|
||||
{
|
||||
// If script block logging is explicitly disabled, or it's from a trusted
|
||||
// file or internal, skip logging.
|
||||
if (ScriptBlockLoggingExplicitlyDisabled() ||
|
||||
if (logSetting?.EnableScriptBlockLogging == false ||
|
||||
scriptBlock.ScriptBlockData.IsProductCode)
|
||||
{
|
||||
return;
|
||||
@@ -1284,18 +1286,17 @@ namespace System.Management.Automation
|
||||
|
||||
private static bool WriteScriptBlockToLog(ScriptBlock scriptBlock, int segment, int segments, string textToLog)
|
||||
{
|
||||
// See if we need to encrypt the event log message. This info is all cached by Utils.GetGroupPolicySetting(),
|
||||
// so we're not hitting the registry for every script block we compile.
|
||||
Dictionary<string, object> protectedEventLoggingSettings = Utils.GetGroupPolicySetting(
|
||||
"Software\\Policies\\Microsoft\\Windows\\EventLog", "ProtectedEventLogging", Utils.RegLocalMachine);
|
||||
if (protectedEventLoggingSettings != null)
|
||||
// See if we need to encrypt the event log message. This info is all cached by Utils.GetPolicySetting(),
|
||||
// so we're not hitting the configuration file for every script block we compile.
|
||||
ProtectedEventLogging logSetting = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
if (logSetting != null)
|
||||
{
|
||||
lock (s_syncObject)
|
||||
{
|
||||
// Populates the encryptionRecipients list from the Group Policy, if possible. If not possible,
|
||||
// does all appropriate logging and encryptionRecipients is 'null'. 'CouldLog' being false
|
||||
// implies the engine wasn't ready for logging yet.
|
||||
bool couldLog = GetAndValidateEncryptionRecipients(scriptBlock);
|
||||
bool couldLog = GetAndValidateEncryptionRecipients(scriptBlock, logSetting);
|
||||
if (!couldLog)
|
||||
{
|
||||
return false;
|
||||
@@ -1345,109 +1346,92 @@ namespace System.Management.Automation
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool GetAndValidateEncryptionRecipients(ScriptBlock scriptBlock)
|
||||
private static bool GetAndValidateEncryptionRecipients(ScriptBlock scriptBlock, ProtectedEventLogging logSetting)
|
||||
{
|
||||
Dictionary<string, object> protectedEventLoggingSettings = Utils.GetGroupPolicySetting(
|
||||
"Software\\Policies\\Microsoft\\Windows\\EventLog", "ProtectedEventLogging", Utils.RegLocalMachine);
|
||||
|
||||
// See if protected event logging is enabled
|
||||
object enableProtectedEventLogging = null;
|
||||
if (protectedEventLoggingSettings.TryGetValue("EnableProtectedEventLogging", out enableProtectedEventLogging))
|
||||
if (logSetting.EnableProtectedEventLogging == true)
|
||||
{
|
||||
if (String.Equals("1", enableProtectedEventLogging.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||
// Get the encryption certificate
|
||||
if (logSetting.EncryptionCertificate != null)
|
||||
{
|
||||
// Get the encryption certificate
|
||||
object encryptionCertificate = null;
|
||||
if (protectedEventLoggingSettings.TryGetValue("EncryptionCertificate", out encryptionCertificate))
|
||||
ErrorRecord error = null;
|
||||
ExecutionContext executionContext = LocalPipeline.GetExecutionContextFromTLS();
|
||||
SessionState sessionState = null;
|
||||
|
||||
// Use the session state from the current pipeline, if it exists.
|
||||
if (executionContext != null)
|
||||
{
|
||||
ErrorRecord error = null;
|
||||
ExecutionContext executionContext = LocalPipeline.GetExecutionContextFromTLS();
|
||||
SessionState sessionState = null;
|
||||
sessionState = executionContext.SessionState;
|
||||
}
|
||||
|
||||
// Use the session state from the current pipeline, if it exists.
|
||||
if (executionContext != null)
|
||||
// If the engine hasn't started up yet, then we're just compiling script
|
||||
// blocks. We'll have to log them when they are used and we have an engine
|
||||
// to work with.
|
||||
if (sessionState == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string fullCertificateContent = String.Join(Environment.NewLine, logSetting.EncryptionCertificate);
|
||||
|
||||
// If the certificate has changed, drop all of our cached information
|
||||
ResetCertificateCacheIfNeeded(fullCertificateContent);
|
||||
|
||||
// If we have valid recipients, no need for further analysis.
|
||||
if (s_encryptionRecipients != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we've already verified all of the properties of the cert we care about (even if it
|
||||
// didn't result in a valid cert), return now.
|
||||
if (s_hasProcessedCertificate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve the certificate to a recipient
|
||||
CmsMessageRecipient recipient = new CmsMessageRecipient(fullCertificateContent);
|
||||
recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error);
|
||||
s_hasProcessedCertificate = true;
|
||||
|
||||
// If there's an error that we haven't already reported, report it in the event log.
|
||||
// We only do this once, as the error will always be the same for a given certificate.
|
||||
if (error != null)
|
||||
{
|
||||
// If we got an error resolving the encryption certificate, log a warning and continue
|
||||
// logging the (unencrypted) message anyways. Logging trumps protected logging -
|
||||
// being able to detect that an attacker has compromised a box outweighs the danger of the
|
||||
// attacker seeing potentially sensitive data. Because if they aren't detected, then
|
||||
// they can just wait on the compromised box and see the sensitive data eventually anyways.
|
||||
string errorMessage = StringUtil.Format(SecuritySupportStrings.CouldNotUseCertificate, error.ToString());
|
||||
PSEtwLog.LogOperationalError(PSEventId.ScriptBlock_Compile_Detail, PSOpcode.Create, PSTask.ExecuteCommand, PSKeyword.UseAlwaysAnalytic,
|
||||
0, 0, errorMessage, scriptBlock.Id.ToString(), scriptBlock.File ?? String.Empty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now, save the certificate. We'll be comfortable using this one from now on.
|
||||
s_encryptionRecipients = new CmsMessageRecipient[] { recipient };
|
||||
|
||||
// Check if the certificate has a private key, and report a warning if so.
|
||||
// We only do this once, as the error will always be the same for a given certificate.
|
||||
foreach (X509Certificate2 validationCertificate in recipient.Certificates)
|
||||
{
|
||||
if (validationCertificate.HasPrivateKey)
|
||||
{
|
||||
sessionState = executionContext.SessionState;
|
||||
}
|
||||
// Only log the first line of what we pulled from the configuration. If this is a path, this will have enough information.
|
||||
// If this is the actual certificate, only include the first line of the certificate content so that we're not permanently keeping the private
|
||||
// key in the log.
|
||||
string certificateForLog = fullCertificateContent;
|
||||
if (logSetting.EncryptionCertificate.Length > 1)
|
||||
{
|
||||
certificateForLog = logSetting.EncryptionCertificate[1];
|
||||
}
|
||||
|
||||
// If the engine hasn't started up yet, then we're just compiling script
|
||||
// blocks. We'll have to log them when they are used and we have an engine
|
||||
// to work with.
|
||||
if (sessionState == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] encryptionCertificateContent = encryptionCertificate as string[];
|
||||
string fullCertificateContent = null;
|
||||
if (encryptionCertificateContent != null)
|
||||
{
|
||||
fullCertificateContent = String.Join(Environment.NewLine, encryptionCertificateContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
fullCertificateContent = encryptionCertificate as string;
|
||||
}
|
||||
|
||||
// If the certificate has changed, drop all of our cached information
|
||||
ResetCertificateCacheIfNeeded(fullCertificateContent);
|
||||
|
||||
// If we have valid recipients, no need for further analysis.
|
||||
if (s_encryptionRecipients != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we've already verified all of the properties of the cert we care about (even if it
|
||||
// didn't result in a valid cert), return now.
|
||||
if (s_hasProcessedCertificate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve the certificate to a recipient
|
||||
CmsMessageRecipient recipient = new CmsMessageRecipient(fullCertificateContent);
|
||||
recipient.Resolve(sessionState, ResolutionPurpose.Encryption, out error);
|
||||
s_hasProcessedCertificate = true;
|
||||
|
||||
// If there's an error that we haven't already reported, report it in the event log.
|
||||
// We only do this once, as the error will always be the same for a given certificate.
|
||||
if (error != null)
|
||||
{
|
||||
// If we got an error resolving the encryption certificate, log a warning and continue
|
||||
// logging the (unencrypted) message anyways. Logging trumps protected logging -
|
||||
// being able to detect that an attacker has compromised a box outweighs the danger of the
|
||||
// attacker seeing potentially sensitive data. Because if they aren't detected, then
|
||||
// they can just wait on the compromised box and see the sensitive data eventually anyways.
|
||||
string errorMessage = StringUtil.Format(SecuritySupportStrings.CouldNotUseCertificate, error.ToString());
|
||||
string errorMessage = StringUtil.Format(SecuritySupportStrings.CertificateContainsPrivateKey, certificateForLog);
|
||||
PSEtwLog.LogOperationalError(PSEventId.ScriptBlock_Compile_Detail, PSOpcode.Create, PSTask.ExecuteCommand, PSKeyword.UseAlwaysAnalytic,
|
||||
0, 0, errorMessage, scriptBlock.Id.ToString(), scriptBlock.File ?? String.Empty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now, save the certificate. We'll be comfortable using this one from now on.
|
||||
s_encryptionRecipients = new CmsMessageRecipient[] { recipient };
|
||||
|
||||
// Check if the certificate has a private key, and report a warning if so.
|
||||
// We only do this once, as the error will always be the same for a given certificate.
|
||||
foreach (X509Certificate2 validationCertificate in recipient.Certificates)
|
||||
{
|
||||
if (validationCertificate.HasPrivateKey)
|
||||
{
|
||||
// Only log the first line of what we pulled from the registry. If this is a path, this will have enough information.
|
||||
// If this is the actual certificate, only include the first line of the certificate content so that we're not permanently keeping the private
|
||||
// key in the log.
|
||||
string certificateForLog = fullCertificateContent;
|
||||
if ((encryptionCertificateContent != null) && (encryptionCertificateContent.Length > 1))
|
||||
{
|
||||
certificateForLog = encryptionCertificateContent[1];
|
||||
}
|
||||
|
||||
string errorMessage = StringUtil.Format(SecuritySupportStrings.CertificateContainsPrivateKey, certificateForLog);
|
||||
PSEtwLog.LogOperationalError(PSEventId.ScriptBlock_Compile_Detail, PSOpcode.Create, PSTask.ExecuteCommand, PSKeyword.UseAlwaysAnalytic,
|
||||
0, 0, errorMessage, scriptBlock.Id.ToString(), scriptBlock.File ?? String.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1472,23 +1456,9 @@ namespace System.Management.Automation
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ShouldLogScriptBlockActivity(string activity)
|
||||
private static ScriptBlockLogging GetScriptBlockLoggingSetting()
|
||||
{
|
||||
// If script block logging is turned on, log this one.
|
||||
Dictionary<string, object> groupPolicySettings = Utils.GetGroupPolicySetting("ScriptBlockLogging", Utils.RegLocalMachineThenCurrentUser);
|
||||
if (groupPolicySettings != null)
|
||||
{
|
||||
object logScriptBlockExecution = null;
|
||||
if (groupPolicySettings.TryGetValue(activity, out logScriptBlockExecution))
|
||||
{
|
||||
if (String.Equals("1", logScriptBlockExecution.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
}
|
||||
|
||||
// Quick check for script blocks that may have suspicious content. If this
|
||||
@@ -1808,27 +1778,6 @@ namespace System.Management.Automation
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static bool ScriptBlockLoggingExplicitlyDisabled()
|
||||
{
|
||||
// Verify they haven't explicitly turned off script block logging.
|
||||
Dictionary<string, object> groupPolicySettings = Utils.GetGroupPolicySetting("ScriptBlockLogging", Utils.RegLocalMachineThenCurrentUser);
|
||||
if (groupPolicySettings != null)
|
||||
{
|
||||
object logScriptBlockExecution;
|
||||
if (groupPolicySettings.TryGetValue("EnableScriptBlockLogging", out logScriptBlockExecution))
|
||||
{
|
||||
// If it is configured and explicitly disabled, return true.
|
||||
// (Don't even auto-log ones with suspicious content)
|
||||
if (String.Equals("0", logScriptBlockExecution.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static void LogScriptBlockStart(ScriptBlock scriptBlock, Guid runspaceId)
|
||||
{
|
||||
// When invoking, log the creation of the script block if it has suspicious
|
||||
@@ -1843,7 +1792,7 @@ namespace System.Management.Automation
|
||||
// properly analyzed the script block's security.
|
||||
LogScriptBlockCreation(scriptBlock, forceLogCreation);
|
||||
|
||||
if (ShouldLogScriptBlockActivity("EnableScriptBlockInvocationLogging"))
|
||||
if (GetScriptBlockLoggingSetting()?.EnableScriptBlockInvocationLogging == true)
|
||||
{
|
||||
PSEtwLog.LogOperationalVerbose(PSEventId.ScriptBlock_Invoke_Start_Detail, PSOpcode.Create, PSTask.CommandStart, PSKeyword.UseAlwaysAnalytic,
|
||||
scriptBlock.Id.ToString(), runspaceId.ToString());
|
||||
@@ -1852,7 +1801,7 @@ namespace System.Management.Automation
|
||||
|
||||
internal static void LogScriptBlockEnd(ScriptBlock scriptBlock, Guid runspaceId)
|
||||
{
|
||||
if (ShouldLogScriptBlockActivity("EnableScriptBlockInvocationLogging"))
|
||||
if (GetScriptBlockLoggingSetting()?.EnableScriptBlockInvocationLogging == true)
|
||||
{
|
||||
PSEtwLog.LogOperationalVerbose(PSEventId.ScriptBlock_Invoke_Complete_Detail, PSOpcode.Create, PSTask.CommandStop, PSKeyword.UseAlwaysAnalytic,
|
||||
scriptBlock.Id.ToString(), runspaceId.ToString());
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Globalization;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Net;
|
||||
using System.ComponentModel;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
@@ -1665,14 +1666,9 @@ namespace System.Management.Automation.Help
|
||||
/// <returns></returns>
|
||||
internal string GetDefaultSourcePath()
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigPropertyAccessor.Instance.GetDefaultSourcePath();
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var updatableHelpSetting = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
string defaultSourcePath = updatableHelpSetting?.DefaultSourcePath;
|
||||
return String.IsNullOrEmpty(defaultSourcePath) ? null : defaultSourcePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1682,7 +1678,7 @@ namespace System.Management.Automation.Help
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigPropertyAccessor.Instance.SetDisablePromptToUpdateHelp(true);
|
||||
PowerShellConfig.Instance.SetDisablePromptToUpdateHelp(true);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
@@ -1712,7 +1708,7 @@ namespace System.Management.Automation.Help
|
||||
return false;
|
||||
}
|
||||
|
||||
return ConfigPropertyAccessor.Instance.GetDisablePromptToUpdateHelp();
|
||||
return PowerShellConfig.Instance.GetDisablePromptToUpdateHelp();
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
|
||||
@@ -134,54 +134,23 @@ namespace System.Management.Automation
|
||||
/// <returns></returns>
|
||||
private static Collection<LogProvider> CreateLogProvider(string shellId)
|
||||
{
|
||||
#if V2
|
||||
try
|
||||
{
|
||||
Assembly crimsonAssembly = Assembly.Load(_crimsonLogProviderAssemblyName);
|
||||
|
||||
if (crimsonAssembly != null)
|
||||
{
|
||||
LogProvider logProvider = (LogProvider)crimsonAssembly.CreateInstance(_crimsonLogProviderTypeName,
|
||||
false, // don't ignore case
|
||||
BindingFlags.CreateInstance,
|
||||
null, // use default binder
|
||||
null,
|
||||
null, // use current culture
|
||||
null // no special activation attributes
|
||||
);
|
||||
|
||||
System.Diagnostics.Debug.Assert(logProvider != null);
|
||||
return logProvider;
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_trace.TraceException(e);
|
||||
}
|
||||
catch (BadImageFormatException e)
|
||||
{
|
||||
_trace.TraceException(e);
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
_trace.TraceException(e);
|
||||
}
|
||||
catch (TargetInvocationException e)
|
||||
{
|
||||
_trace.TraceException(e);
|
||||
}
|
||||
#endif
|
||||
Collection<LogProvider> providers = new Collection<LogProvider>();
|
||||
// Porting note: Linux does not support ETW
|
||||
#if !UNIX
|
||||
|
||||
try
|
||||
{
|
||||
#if !CORECLR //TODO:CORECLR EventLogLogProvider not handled yet
|
||||
LogProvider eventLogLogProvider = new EventLogLogProvider(shellId);
|
||||
providers.Add(eventLogLogProvider);
|
||||
#endif
|
||||
|
||||
#if UNIX
|
||||
LogProvider sysLogProvider = new PSSysLogProvider();
|
||||
providers.Add(sysLogProvider);
|
||||
#else
|
||||
LogProvider etwLogProvider = new PSEtwLogProvider();
|
||||
providers.Add(etwLogProvider);
|
||||
#endif
|
||||
|
||||
return providers;
|
||||
}
|
||||
@@ -198,7 +167,7 @@ namespace System.Management.Automation
|
||||
// when running as non-admin user. In that case, we will default
|
||||
// to dummy log.
|
||||
}
|
||||
#endif
|
||||
|
||||
providers.Add(new DummyLogProvider());
|
||||
return providers;
|
||||
}
|
||||
|
||||
File renamed without changes.
@@ -11,6 +11,7 @@ using System.IO;
|
||||
using Microsoft.PowerShell;
|
||||
using Microsoft.PowerShell.Commands;
|
||||
using Microsoft.Win32;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
@@ -141,7 +142,6 @@ namespace System.Management.Automation.Internal
|
||||
throw new PlatformNotSupportedException();
|
||||
#else
|
||||
string executionPolicy = "Restricted";
|
||||
string preferenceKey = Utils.GetRegistryConfigurationPath(shellId);
|
||||
|
||||
switch (policy)
|
||||
{
|
||||
@@ -174,12 +174,11 @@ namespace System.Management.Automation.Internal
|
||||
// They want to remove it
|
||||
if (policy == ExecutionPolicy.Undefined)
|
||||
{
|
||||
ConfigPropertyAccessor.Instance.RemoveExecutionPolicy(ConfigPropertyAccessor.PropertyScope.CurrentUser, shellId);
|
||||
CleanKeyParents(Registry.CurrentUser, preferenceKey);
|
||||
PowerShellConfig.Instance.RemoveExecutionPolicy(ConfigScope.CurrentUser, shellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigPropertyAccessor.Instance.SetExecutionPolicy(ConfigPropertyAccessor.PropertyScope.CurrentUser, shellId, executionPolicy);
|
||||
PowerShellConfig.Instance.SetExecutionPolicy(ConfigScope.CurrentUser, shellId, executionPolicy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -189,12 +188,11 @@ namespace System.Management.Automation.Internal
|
||||
// They want to remove it
|
||||
if (policy == ExecutionPolicy.Undefined)
|
||||
{
|
||||
ConfigPropertyAccessor.Instance.RemoveExecutionPolicy(ConfigPropertyAccessor.PropertyScope.SystemWide, shellId);
|
||||
CleanKeyParents(Registry.LocalMachine, preferenceKey);
|
||||
PowerShellConfig.Instance.RemoveExecutionPolicy(ConfigScope.SystemWide, shellId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigPropertyAccessor.Instance.SetExecutionPolicy(ConfigPropertyAccessor.PropertyScope.SystemWide, shellId, executionPolicy);
|
||||
PowerShellConfig.Instance.SetExecutionPolicy(ConfigScope.SystemWide, shellId, executionPolicy);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -202,50 +200,6 @@ namespace System.Management.Automation.Internal
|
||||
#endif
|
||||
}
|
||||
|
||||
// Clean up the parents of a registry key as long as they
|
||||
// contain at most a single child
|
||||
private static void CleanKeyParents(RegistryKey baseKey, string keyPath)
|
||||
{
|
||||
#if CORECLR
|
||||
if (!Platform.IsInbox)
|
||||
return;
|
||||
#endif
|
||||
using (RegistryKey key = baseKey.OpenSubKey(keyPath, true))
|
||||
{
|
||||
// Verify the child key has no children
|
||||
if ((key == null) || ((key.ValueCount == 0) && (key.SubKeyCount == 0)))
|
||||
{
|
||||
// If so, split the key into its path elements
|
||||
string[] parentKeys = keyPath.Split(Utils.Separators.Backslash);
|
||||
|
||||
// Verify we aren't traveling into SOFTWARE\Microsoft
|
||||
if (parentKeys.Length <= 2)
|
||||
return;
|
||||
|
||||
string currentItem = parentKeys[parentKeys.Length - 1];
|
||||
|
||||
// Figure out the parent key name
|
||||
string parentKeyPath = keyPath.Remove(keyPath.Length - currentItem.Length - 1);
|
||||
|
||||
// Open the parent, and clear the child key
|
||||
if (key != null)
|
||||
{
|
||||
using (RegistryKey parentKey = baseKey.OpenSubKey(parentKeyPath, true))
|
||||
{
|
||||
parentKey.DeleteSubKey(currentItem, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Now, process the parent key
|
||||
CleanKeyParents(baseKey, parentKeyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static ExecutionPolicy GetExecutionPolicy(string shellId)
|
||||
{
|
||||
foreach (ExecutionPolicyScope scope in ExecutionPolicyScopePreferences)
|
||||
@@ -556,41 +510,31 @@ namespace System.Management.Automation.Internal
|
||||
/// <returns>NULL if it is not defined at this level</returns>
|
||||
private static string GetGroupPolicyValue(string shellId, ExecutionPolicyScope scope)
|
||||
{
|
||||
RegistryKey[] scopeKey = null;
|
||||
ConfigScope[] scopeKey = null;
|
||||
|
||||
switch (scope)
|
||||
{
|
||||
case ExecutionPolicyScope.MachinePolicy:
|
||||
{
|
||||
scopeKey = Utils.RegLocalMachine;
|
||||
}; break;
|
||||
scopeKey = Utils.SystemWideOnlyConfig;
|
||||
break;
|
||||
|
||||
case ExecutionPolicyScope.UserPolicy:
|
||||
{
|
||||
scopeKey = Utils.RegCurrentUser;
|
||||
}; break;
|
||||
scopeKey = Utils.CurrentUserOnlyConfig;
|
||||
break;
|
||||
}
|
||||
|
||||
Dictionary<string, object> groupPolicySettings = Utils.GetGroupPolicySetting(".", scopeKey);
|
||||
if (groupPolicySettings == null)
|
||||
var scriptExecutionSetting = Utils.GetPolicySetting<ScriptExecution>(scopeKey);
|
||||
if (scriptExecutionSetting != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Object enableScriptsValue = null;
|
||||
if (groupPolicySettings.TryGetValue("EnableScripts", out enableScriptsValue))
|
||||
{
|
||||
if (String.Equals(enableScriptsValue.ToString(), "0", StringComparison.OrdinalIgnoreCase))
|
||||
if (scriptExecutionSetting.EnableScripts == false)
|
||||
{
|
||||
// Script execution is explicitly disabled
|
||||
return "Restricted";
|
||||
}
|
||||
else if (String.Equals(enableScriptsValue.ToString(), "1", StringComparison.OrdinalIgnoreCase))
|
||||
else if (scriptExecutionSetting.EnableScripts == true)
|
||||
{
|
||||
Object executionPolicyValue = null;
|
||||
if (groupPolicySettings.TryGetValue("ExecutionPolicy", out executionPolicyValue))
|
||||
{
|
||||
return executionPolicyValue.ToString();
|
||||
}
|
||||
// Script execution is explicitly enabled
|
||||
return scriptExecutionSetting.ExecutionPolicy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -608,11 +552,11 @@ namespace System.Management.Automation.Internal
|
||||
{
|
||||
// 1: Look up the current-user preference
|
||||
case ExecutionPolicyScope.CurrentUser:
|
||||
return ConfigPropertyAccessor.Instance.GetExecutionPolicy(ConfigPropertyAccessor.PropertyScope.CurrentUser, shellId);
|
||||
return PowerShellConfig.Instance.GetExecutionPolicy(ConfigScope.CurrentUser, shellId);
|
||||
|
||||
// 2: Look up the system-wide preference
|
||||
case ExecutionPolicyScope.LocalMachine:
|
||||
return ConfigPropertyAccessor.Instance.GetExecutionPolicy(ConfigPropertyAccessor.PropertyScope.SystemWide, shellId);
|
||||
return PowerShellConfig.Instance.GetExecutionPolicy(ConfigScope.SystemWide, shellId);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Copyright (C) Microsoft. All rights reserved.
|
||||
//
|
||||
using System.Diagnostics.Eventing;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
@@ -24,10 +25,10 @@ namespace System.Management.Automation.Tracing
|
||||
/// </summary>
|
||||
static PSSysLogProvider()
|
||||
{
|
||||
s_provider = new SysLogProvider(ConfigPropertyAccessor.Instance.GetSysLogIdentity(),
|
||||
ConfigPropertyAccessor.Instance.GetLogLevel(),
|
||||
ConfigPropertyAccessor.Instance.GetLogKeywords(),
|
||||
ConfigPropertyAccessor.Instance.GetLogChannels());
|
||||
s_provider = new SysLogProvider(PowerShellConfig.Instance.GetSysLogIdentity(),
|
||||
PowerShellConfig.Instance.GetLogLevel(),
|
||||
PowerShellConfig.Instance.GetLogKeywords(),
|
||||
PowerShellConfig.Instance.GetLogChannels());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace System.Management.Automation.Tracing
|
||||
/// Initializes a new instance of this class.
|
||||
/// </summary>
|
||||
/// <param name="applicationId">The log identity name used to identify the application in syslog.</param>
|
||||
/// <param name="level">The trace lavel to enable.</param>
|
||||
/// <param name="level">The trace level to enable.</param>
|
||||
/// <param name="keywords">The keywords to enable.</param>
|
||||
/// <param name="channels">The output channels to enable.</param>
|
||||
public SysLogProvider(string applicationId, PSLevel level, PSKeyword keywords, PSChannel channels)
|
||||
@@ -313,6 +313,13 @@ namespace System.Management.Automation.Tracing
|
||||
/// <param name="args">The payload for the log message.</param>
|
||||
public void Log(PSEventId eventId, PSChannel channel, PSTask task, PSOpcode opcode, PSLevel level, PSKeyword keyword, params object[] args)
|
||||
{
|
||||
if (keyword == PSKeyword.UseAlwaysAnalytic)
|
||||
{
|
||||
// Use the 'DefaultKeywords' to work around the default keyword filter.
|
||||
// Note that the PSKeyword argument is not really used in writing SysLog.
|
||||
keyword = PSSysLogProvider.DefaultKeywords;
|
||||
}
|
||||
|
||||
if (ShouldLog(level, keyword, channel))
|
||||
{
|
||||
int threadId = Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\powershell\Program.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
|
||||
<Content Include="..\System.Management.Automation\PowerShellProperties.json">
|
||||
<Link>PowerShellProperties.json</Link>
|
||||
<Content Include="..\System.Management.Automation\powershell.config.json">
|
||||
<Link>powershell.config.json</Link>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Include="..\Modules\Windows-Core\**\*;..\Modules\Windows-Core+Full\**\*;..\Modules\Shared\**\*">
|
||||
|
||||
@@ -2,7 +2,7 @@ using Xunit;
|
||||
using System;
|
||||
using System.Management.Automation.Language;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class PSEnumerableBinderTests
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class PlatformTests
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ using Xunit;
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class PSTypeExtensionsTests
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ using Microsoft.PowerShell;
|
||||
using Microsoft.PowerShell.Commands;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public class FileSystemProviderTests: IDisposable
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ using Xunit;
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
// Not static because a test requires non-const variables
|
||||
public class MshSnapinInfoTests
|
||||
|
||||
@@ -0,0 +1,900 @@
|
||||
using Xunit;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Configuration;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace PSTests.Sequential
|
||||
{
|
||||
public class PowerShellPolicyFixture : IDisposable
|
||||
{
|
||||
private const string configFileName = "powershell.config.json";
|
||||
private readonly string systemWideConfigFile;
|
||||
private readonly string currentUserConfigFile;
|
||||
|
||||
private readonly string systemWideConfigBackupFile;
|
||||
private readonly string currentUserConfigBackupFile;
|
||||
|
||||
private readonly string systemWideConfigDirectory;
|
||||
private readonly string currentUserConfigDirectory;
|
||||
|
||||
private readonly JsonSerializer serializer;
|
||||
|
||||
private readonly PowerShellPolicies systemWidePolicies;
|
||||
private readonly PowerShellPolicies currentUserPolicies;
|
||||
|
||||
private readonly bool originalTestHookValue;
|
||||
|
||||
public PowerShellPolicyFixture()
|
||||
{
|
||||
systemWideConfigDirectory = Utils.DefaultPowerShellAppBase;
|
||||
currentUserConfigDirectory = Utils.GetUserConfigurationDirectory();
|
||||
|
||||
if (!Directory.Exists(currentUserConfigDirectory))
|
||||
{
|
||||
// Create the CurrentUser config directory if it doesn't exist
|
||||
Directory.CreateDirectory(currentUserConfigDirectory);
|
||||
}
|
||||
|
||||
systemWideConfigFile = Path.Combine(systemWideConfigDirectory, configFileName);
|
||||
currentUserConfigFile = Path.Combine(currentUserConfigDirectory, configFileName);
|
||||
|
||||
if (File.Exists(systemWideConfigFile))
|
||||
{
|
||||
systemWideConfigBackupFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
File.Move(systemWideConfigFile, systemWideConfigBackupFile);
|
||||
}
|
||||
if (File.Exists(currentUserConfigFile))
|
||||
{
|
||||
currentUserConfigBackupFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
File.Move(currentUserConfigFile, currentUserConfigBackupFile);
|
||||
}
|
||||
|
||||
var settings = new JsonSerializerSettings()
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.None,
|
||||
MaxDepth = 10,
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
serializer = JsonSerializer.Create(settings);
|
||||
|
||||
systemWidePolicies = new PowerShellPolicies()
|
||||
{
|
||||
ScriptExecution = new ScriptExecution() { ExecutionPolicy = "RemoteSigned", EnableScripts = true },
|
||||
ScriptBlockLogging = new ScriptBlockLogging() { EnableScriptBlockInvocationLogging = true, EnableScriptBlockLogging = false },
|
||||
ModuleLogging = new ModuleLogging() { EnableModuleLogging = false, ModuleNames = new string[] { "PSReadline", "PowerShellGet" } },
|
||||
ProtectedEventLogging = new ProtectedEventLogging() { EnableProtectedEventLogging = false, EncryptionCertificate = new string[] { "Joe" } },
|
||||
Transcription = new Transcription() { EnableInvocationHeader = true, EnableTranscripting = true, OutputDirectory = "c:\tmp" },
|
||||
UpdatableHelp = new UpdatableHelp() { DefaultSourcePath = "f:\temp" },
|
||||
ConsoleSessionConfiguration = new ConsoleSessionConfiguration() { EnableConsoleSessionConfiguration = true, ConsoleSessionConfigurationName = "name" }
|
||||
};
|
||||
|
||||
currentUserPolicies = new PowerShellPolicies()
|
||||
{
|
||||
ScriptExecution = new ScriptExecution() { ExecutionPolicy = "RemoteSigned" },
|
||||
ScriptBlockLogging = new ScriptBlockLogging() { EnableScriptBlockLogging = false },
|
||||
ModuleLogging = new ModuleLogging() { EnableModuleLogging = false },
|
||||
ProtectedEventLogging = new ProtectedEventLogging() { EncryptionCertificate = new string[] { "Joe" } }
|
||||
};
|
||||
|
||||
// Set the test hook to disable policy caching
|
||||
originalTestHookValue = InternalTestHooks.BypassGroupPolicyCaching;
|
||||
InternalTestHooks.BypassGroupPolicyCaching = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CleanupConfigFiles();
|
||||
if (systemWideConfigBackupFile != null)
|
||||
{
|
||||
File.Move(systemWideConfigBackupFile, systemWideConfigFile);
|
||||
}
|
||||
|
||||
if (currentUserConfigBackupFile != null)
|
||||
{
|
||||
File.Move(currentUserConfigBackupFile, currentUserConfigFile);
|
||||
}
|
||||
InternalTestHooks.BypassGroupPolicyCaching = originalTestHookValue;
|
||||
}
|
||||
|
||||
internal PowerShellPolicies SystemWidePolicies
|
||||
{
|
||||
get { return systemWidePolicies; }
|
||||
}
|
||||
|
||||
internal PowerShellPolicies CurrentUserPolicies
|
||||
{
|
||||
get { return currentUserPolicies; }
|
||||
}
|
||||
|
||||
#region Compare_Policy_Settings
|
||||
|
||||
internal void CompareScriptExecution(ScriptExecution a, ScriptExecution b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableScripts, b.EnableScripts);
|
||||
Assert.Equal(a.ExecutionPolicy, b.ExecutionPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareScriptBlockLogging(ScriptBlockLogging a, ScriptBlockLogging b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableScriptBlockInvocationLogging, b.EnableScriptBlockInvocationLogging);
|
||||
Assert.Equal(a.EnableScriptBlockLogging, b.EnableScriptBlockLogging);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareModuleLogging(ModuleLogging a, ModuleLogging b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableModuleLogging, b.EnableModuleLogging);
|
||||
if (a.ModuleNames == null)
|
||||
{
|
||||
Assert.Null(b.ModuleNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.ModuleNames.Length, b.ModuleNames.Length);
|
||||
for (int i = 0; i < a.ModuleNames.Length; i++)
|
||||
{
|
||||
Assert.Equal(a.ModuleNames[i], b.ModuleNames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareProtectedEventLogging(ProtectedEventLogging a, ProtectedEventLogging b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableProtectedEventLogging, b.EnableProtectedEventLogging);
|
||||
if (a.EncryptionCertificate == null)
|
||||
{
|
||||
Assert.Null(b.EncryptionCertificate);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EncryptionCertificate.Length, b.EncryptionCertificate.Length);
|
||||
for (int i = 0; i < a.EncryptionCertificate.Length; i++)
|
||||
{
|
||||
Assert.Equal(a.EncryptionCertificate[i], b.EncryptionCertificate[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareTranscription(Transcription a, Transcription b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableTranscripting, b.EnableTranscripting);
|
||||
Assert.Equal(a.EnableInvocationHeader, b.EnableInvocationHeader);
|
||||
Assert.Equal(a.OutputDirectory, b.OutputDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareUpdatableHelp(UpdatableHelp a, UpdatableHelp b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.DefaultSourcePath, b.DefaultSourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareConsoleSessionConfiguration(ConsoleSessionConfiguration a, ConsoleSessionConfiguration b)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
Assert.Null(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(a.EnableConsoleSessionConfiguration, b.EnableConsoleSessionConfiguration);
|
||||
Assert.Equal(a.ConsoleSessionConfigurationName, b.ConsoleSessionConfigurationName);
|
||||
}
|
||||
}
|
||||
|
||||
internal void CompareTwoPolicies(PowerShellPolicies a, PowerShellPolicies b)
|
||||
{
|
||||
// Compare 'ScriptExecution' settings
|
||||
CompareScriptExecution(a.ScriptExecution, b.ScriptExecution);
|
||||
|
||||
// Compare 'ScriptBlockLogging' settings
|
||||
CompareScriptBlockLogging(a.ScriptBlockLogging, b.ScriptBlockLogging);
|
||||
|
||||
// Compare 'ModuleLogging' settings
|
||||
CompareModuleLogging(a.ModuleLogging, b.ModuleLogging);
|
||||
|
||||
// Compare 'ProtectedEventLogging' settings
|
||||
CompareProtectedEventLogging(a.ProtectedEventLogging, b.ProtectedEventLogging);
|
||||
|
||||
// Compare 'Transcription' settings
|
||||
CompareTranscription(a.Transcription, b.Transcription);
|
||||
|
||||
// Compare 'UpdatableHelp' settings
|
||||
CompareUpdatableHelp(a.UpdatableHelp, b.UpdatableHelp);
|
||||
|
||||
// Compare 'ConsoleSessionConfiguration' settings
|
||||
CompareConsoleSessionConfiguration(a.ConsoleSessionConfiguration, b.ConsoleSessionConfiguration);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration_File_Setup
|
||||
|
||||
public void CleanupConfigFiles()
|
||||
{
|
||||
if (File.Exists(systemWideConfigFile))
|
||||
{
|
||||
File.Delete(systemWideConfigFile);
|
||||
}
|
||||
if (File.Exists(currentUserConfigFile))
|
||||
{
|
||||
File.Delete(currentUserConfigFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupConfigFile1()
|
||||
{
|
||||
CleanupConfigFiles();
|
||||
|
||||
// System wide config file has all policy settings
|
||||
var systemWideConfig = new { ConsolePrompting = true, PowerShellPolicies = systemWidePolicies };
|
||||
using (var streamWriter = new StreamWriter(systemWideConfigFile))
|
||||
{
|
||||
serializer.Serialize(streamWriter, systemWideConfig);
|
||||
}
|
||||
|
||||
// Current user config file has partial policy settings
|
||||
var currentUserConfig = new { DisablePromptToUpdateHelp = false, PowerShellPolicies = currentUserPolicies };
|
||||
using (var streamWriter = new StreamWriter(currentUserConfigFile))
|
||||
{
|
||||
serializer.Serialize(streamWriter, currentUserConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupConfigFile2()
|
||||
{
|
||||
CleanupConfigFiles();
|
||||
|
||||
// System wide config file has all policy settings
|
||||
var systemWideConfig = new { ConsolePrompting = true, PowerShellPolicies = systemWidePolicies };
|
||||
using (var streamWriter = new StreamWriter(systemWideConfigFile))
|
||||
{
|
||||
serializer.Serialize(streamWriter, systemWideConfig);
|
||||
}
|
||||
|
||||
// Current user config file is empty
|
||||
CreateEmptyFile(currentUserConfigFile);
|
||||
}
|
||||
|
||||
public void SetupConfigFile3()
|
||||
{
|
||||
CleanupConfigFiles();
|
||||
|
||||
// System wide config file is empty
|
||||
CreateEmptyFile(systemWideConfigFile);
|
||||
|
||||
// Current user config file has partial policy settings
|
||||
var currentUserConfig = new { DisablePromptToUpdateHelp = false, PowerShellPolicies = currentUserPolicies };
|
||||
using (var streamWriter = new StreamWriter(currentUserConfigFile))
|
||||
{
|
||||
serializer.Serialize(streamWriter, currentUserConfig);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetupConfigFile4()
|
||||
{
|
||||
CleanupConfigFiles();
|
||||
// System wide config file is empty
|
||||
CreateEmptyFile(systemWideConfigFile);
|
||||
// Current user config file is empty
|
||||
CreateEmptyFile(currentUserConfigFile);
|
||||
}
|
||||
|
||||
private void CreateEmptyFile(string fileName)
|
||||
{
|
||||
File.Create(fileName).Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class PowerShellPolicyTests : IClassFixture<PowerShellPolicyFixture>
|
||||
{
|
||||
PowerShellPolicyFixture fixture;
|
||||
|
||||
public PowerShellPolicyTests(PowerShellPolicyFixture fixture)
|
||||
{
|
||||
this.fixture = fixture;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesNotEmpty()
|
||||
{
|
||||
fixture.SetupConfigFile1();
|
||||
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
|
||||
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
|
||||
|
||||
Assert.NotNull(sysPolicies);
|
||||
Assert.NotNull(userPolicies);
|
||||
|
||||
fixture.CompareTwoPolicies(sysPolicies, fixture.SystemWidePolicies);
|
||||
fixture.CompareTwoPolicies(userPolicies, fixture.CurrentUserPolicies);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PowerShellConfig_GetPowerShellPolicies_EmptyUserConfig()
|
||||
{
|
||||
fixture.SetupConfigFile2();
|
||||
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
|
||||
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
|
||||
|
||||
Assert.NotNull(sysPolicies);
|
||||
Assert.Null(userPolicies);
|
||||
|
||||
fixture.CompareTwoPolicies(sysPolicies, fixture.SystemWidePolicies);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PowerShellConfig_GetPowerShellPolicies_EmptySystemConfig()
|
||||
{
|
||||
fixture.SetupConfigFile3();
|
||||
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
|
||||
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
|
||||
|
||||
Assert.Null(sysPolicies);
|
||||
Assert.NotNull(userPolicies);
|
||||
|
||||
fixture.CompareTwoPolicies(userPolicies, fixture.CurrentUserPolicies);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesEmpty()
|
||||
{
|
||||
fixture.SetupConfigFile4();
|
||||
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
|
||||
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
|
||||
|
||||
Assert.Null(sysPolicies);
|
||||
Assert.Null(userPolicies);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PowerShellConfig_GetPowerShellPolicies_BothConfigFilesNotExist()
|
||||
{
|
||||
fixture.CleanupConfigFiles();
|
||||
var sysPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.SystemWide);
|
||||
var userPolicies = PowerShellConfig.Instance.GetPowerShellPolicies(ConfigScope.CurrentUser);
|
||||
|
||||
Assert.Null(sysPolicies);
|
||||
Assert.Null(userPolicies);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utils_GetPolicySetting_BothConfigFilesNotEmpty()
|
||||
{
|
||||
fixture.SetupConfigFile1();
|
||||
|
||||
ScriptExecution scriptExecution;
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.SystemWidePolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.CurrentUserPolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.SystemWidePolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.CurrentUserPolicies.ScriptExecution);
|
||||
|
||||
ScriptBlockLogging scriptBlockLogging;
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.SystemWidePolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.CurrentUserPolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.SystemWidePolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.CurrentUserPolicies.ScriptBlockLogging);
|
||||
|
||||
ModuleLogging moduleLogging;
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.SystemWidePolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.CurrentUserPolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.SystemWidePolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.CurrentUserPolicies.ModuleLogging);
|
||||
|
||||
ProtectedEventLogging protectedEventLogging;
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.SystemWidePolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.CurrentUserPolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.SystemWidePolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.CurrentUserPolicies.ProtectedEventLogging);
|
||||
|
||||
// The CurrentUser config doesn't contain any settings for 'Transcription', 'UpdatableHelp' and 'ConsoleSessionConfiguration'
|
||||
Transcription transcription;
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
UpdatableHelp updatableHelp;
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
ConsoleSessionConfiguration consoleSessionConfiguration;
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utils_GetPolicySetting_EmptyUserConfig()
|
||||
{
|
||||
fixture.SetupConfigFile2();
|
||||
|
||||
// The CurrentUser config is empty
|
||||
ScriptExecution scriptExecution;
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.SystemWidePolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.SystemWidePolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.SystemWidePolicies.ScriptExecution);
|
||||
|
||||
ScriptBlockLogging scriptBlockLogging;
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.SystemWidePolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.SystemWidePolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.SystemWidePolicies.ScriptBlockLogging);
|
||||
|
||||
ModuleLogging moduleLogging;
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.SystemWidePolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.SystemWidePolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.SystemWidePolicies.ModuleLogging);
|
||||
|
||||
ProtectedEventLogging protectedEventLogging;
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.SystemWidePolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.SystemWidePolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.SystemWidePolicies.ProtectedEventLogging);
|
||||
|
||||
Transcription transcription;
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareTranscription(transcription, fixture.SystemWidePolicies.Transcription);
|
||||
|
||||
UpdatableHelp updatableHelp;
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, fixture.SystemWidePolicies.UpdatableHelp);
|
||||
|
||||
ConsoleSessionConfiguration consoleSessionConfiguration;
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, fixture.SystemWidePolicies.ConsoleSessionConfiguration);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utils_GetPolicySetting_EmptySystemConfig()
|
||||
{
|
||||
fixture.SetupConfigFile3();
|
||||
|
||||
// The SystemWide config is empty
|
||||
ScriptExecution scriptExecution;
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.CurrentUserPolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.CurrentUserPolicies.ScriptExecution);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, fixture.CurrentUserPolicies.ScriptExecution);
|
||||
|
||||
ScriptBlockLogging scriptBlockLogging;
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.CurrentUserPolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.CurrentUserPolicies.ScriptBlockLogging);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, fixture.CurrentUserPolicies.ScriptBlockLogging);
|
||||
|
||||
ModuleLogging moduleLogging;
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.CurrentUserPolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.CurrentUserPolicies.ModuleLogging);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, fixture.CurrentUserPolicies.ModuleLogging);
|
||||
|
||||
ProtectedEventLogging protectedEventLogging;
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.CurrentUserPolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.CurrentUserPolicies.ProtectedEventLogging);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, fixture.CurrentUserPolicies.ProtectedEventLogging);
|
||||
|
||||
// The CurrentUser config doesn't contain any settings for 'Transcription', 'UpdatableHelp' and 'ConsoleSessionConfiguration'
|
||||
Transcription transcription;
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
UpdatableHelp updatableHelp;
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
ConsoleSessionConfiguration consoleSessionConfiguration;
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utils_GetPolicySetting_BothConfigFilesEmpty()
|
||||
{
|
||||
fixture.SetupConfigFile4();
|
||||
|
||||
// Both config files are empty
|
||||
ScriptExecution scriptExecution;
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
ScriptBlockLogging scriptBlockLogging;
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
ModuleLogging moduleLogging;
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
ProtectedEventLogging protectedEventLogging;
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
// The CurrentUser config doesn't contain any settings for 'Transcription', 'UpdatableHelp' and 'ConsoleSessionConfiguration'
|
||||
Transcription transcription;
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
UpdatableHelp updatableHelp;
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
ConsoleSessionConfiguration consoleSessionConfiguration;
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Utils_GetPolicySetting_BothConfigFilesNotExist()
|
||||
{
|
||||
fixture.CleanupConfigFiles();
|
||||
|
||||
// Both config files don't exist
|
||||
ScriptExecution scriptExecution;
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
scriptExecution = Utils.GetPolicySetting<ScriptExecution>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptExecution(scriptExecution, null);
|
||||
|
||||
ScriptBlockLogging scriptBlockLogging;
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
scriptBlockLogging = Utils.GetPolicySetting<ScriptBlockLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareScriptBlockLogging(scriptBlockLogging, null);
|
||||
|
||||
ModuleLogging moduleLogging;
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
moduleLogging = Utils.GetPolicySetting<ModuleLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareModuleLogging(moduleLogging, null);
|
||||
|
||||
ProtectedEventLogging protectedEventLogging;
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
protectedEventLogging = Utils.GetPolicySetting<ProtectedEventLogging>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareProtectedEventLogging(protectedEventLogging, null);
|
||||
|
||||
// The CurrentUser config doesn't contain any settings for 'Transcription', 'UpdatableHelp' and 'ConsoleSessionConfiguration'
|
||||
Transcription transcription;
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
transcription = Utils.GetPolicySetting<Transcription>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareTranscription(transcription, null);
|
||||
|
||||
UpdatableHelp updatableHelp;
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
updatableHelp = Utils.GetPolicySetting<UpdatableHelp>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareUpdatableHelp(updatableHelp, null);
|
||||
|
||||
ConsoleSessionConfiguration consoleSessionConfiguration;
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserOnlyConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.SystemWideThenCurrentUserConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
|
||||
consoleSessionConfiguration = Utils.GetPolicySetting<ConsoleSessionConfiguration>(Utils.CurrentUserThenSystemWideConfig);
|
||||
fixture.CompareConsoleSessionConfiguration(consoleSessionConfiguration, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ using Xunit;
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class PSVersionInfoTests
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Runspaces;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
// NOTE: do not call AddCommand("out-host") after invoking or MergeMyResults,
|
||||
// otherwise Invoke will not return any objects
|
||||
|
||||
@@ -2,7 +2,7 @@ using Xunit;
|
||||
using System;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class SecuritySupportTests
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Management.Automation.Internal.Host;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using Microsoft.PowerShell;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public class SessionStateTests
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@ using System;
|
||||
using System.Management.Automation;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PSTests
|
||||
namespace PSTests.Parallel
|
||||
{
|
||||
public static class UtilsTests
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Functional tests to verify basic conditions for IO to the PowerShellProperties.json files
|
||||
# Functional tests to verify basic conditions for IO to the powershell.config.json files
|
||||
# The properties files are supported on non-Windows OSes, but the tests are specific to
|
||||
# Windows so that file IO can be verified using supported cmdlets.
|
||||
#
|
||||
@@ -14,18 +14,18 @@ try {
|
||||
$IsNotSkipped = ($IsWindows -and !$IsInbox) # Only execute for PowerShell Core on Windows
|
||||
$PSDefaultParameterValues["it:skip"] = !$IsNotSkipped
|
||||
|
||||
Describe "User-Specific PowerShellProperties.json Modifications" -Tags "CI" {
|
||||
Describe "User-Specific powershell.config.json Modifications" -Tags "CI" {
|
||||
|
||||
BeforeAll {
|
||||
if ($IsNotSkipped) {
|
||||
# Discover the user-specific PowerShellProperties.json file
|
||||
# Discover the user-specific powershell.config.json file
|
||||
$userSettingsDir = [System.IO.Path]::Combine($env:USERPROFILE, "Documents", $productName)
|
||||
$userPropertiesFile = Join-Path $userSettingsDir "PowerShellProperties.json"
|
||||
$userPropertiesFile = Join-Path $userSettingsDir "powershell.config.json"
|
||||
|
||||
# Save the file for restoration after the tests are complete
|
||||
$backupPropertiesFile = ""
|
||||
if (Test-Path $userPropertiesFile) {
|
||||
$backupPropertiesFile = Join-Path $userSettingsDir "ORIGINAL_PowerShellProperties.json"
|
||||
$backupPropertiesFile = Join-Path $userSettingsDir "ORIGINAL_powershell.config.json"
|
||||
Copy-Item -Path $userPropertiesFile -Destination $backupPropertiesFile -Force -ErrorAction Continue
|
||||
}
|
||||
elseif (-not (Test-Path $userSettingsDir)) {
|
||||
@@ -49,12 +49,12 @@ try {
|
||||
if ($IsNotSkipped) {
|
||||
if (-not $backupPropertiesFile)
|
||||
{
|
||||
# Remove PowerShellProperties.json if it did not exist before the tests
|
||||
# Remove powershell.config.json if it did not exist before the tests
|
||||
Remove-Item -Path $userPropertiesFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
else
|
||||
{
|
||||
# Restore the original PowerShellProperties.json file if it existed before the test pass.
|
||||
# Restore the original powershell.config.json file if it existed before the test pass.
|
||||
Move-Item -Path $backupPropertiesFile -Destination $userPropertiesFile -Force -ErrorAction Continue
|
||||
}
|
||||
|
||||
|
||||
+11
-4
@@ -325,7 +325,8 @@ function Invoke-AppVeyorTest
|
||||
Write-Host -Foreground Green 'Run CoreCLR tests'
|
||||
$testResultsNonAdminFile = "$pwd\TestsResultsNonAdmin.xml"
|
||||
$testResultsAdminFile = "$pwd\TestsResultsAdmin.xml"
|
||||
$testResultsXUnitFile = "$pwd\TestResultsXUnit.xml"
|
||||
$SequentialXUnitTestResultsFile = "$pwd\SequentialXUnitTestResults.xml"
|
||||
$ParallelXUnitTestResultsFile = "$pwd\ParallelXUnitTestResults.xml"
|
||||
if(!(Test-Path "$env:CoreOutput\pwsh.exe"))
|
||||
{
|
||||
throw "CoreCLR pwsh.exe was not built"
|
||||
@@ -359,9 +360,10 @@ function Invoke-AppVeyorTest
|
||||
Write-Host -Foreground Green 'Upload CoreCLR Admin test results'
|
||||
Update-AppVeyorTestResults -resultsFile $testResultsAdminFile
|
||||
|
||||
Start-PSxUnit -TestResultsFile $testResultsXUnitFile
|
||||
Start-PSxUnit -SequentialTestResultsFile $SequentialXUnitTestResultsFile -ParallelTestResultsFile $ParallelXUnitTestResultsFile
|
||||
Write-Host -ForegroundColor Green 'Uploading PSxUnit test results'
|
||||
Update-AppVeyorTestResults -resultsFile $testResultsXUnitFile
|
||||
Update-AppVeyorTestResults -resultsFile $SequentialXUnitTestResultsFile
|
||||
Update-AppVeyorTestResults -resultsFile $ParallelXUnitTestResultsFile
|
||||
|
||||
#
|
||||
# Fail the build, if tests failed
|
||||
@@ -372,7 +374,12 @@ function Invoke-AppVeyorTest
|
||||
Test-PSPesterResults -TestResultsFile $_
|
||||
}
|
||||
|
||||
$testPassResult = Test-XUnitTestResults -TestResultsFile $testResultsXUnitFile
|
||||
@(
|
||||
$SequentialXUnitTestResultsFile,
|
||||
$ParallelXUnitTestResultsFile
|
||||
) | ForEach-Object {
|
||||
Test-XUnitTestResults -TestResultsFile $_
|
||||
}
|
||||
|
||||
Set-BuildVariable -Name TestPassed -Value True
|
||||
}
|
||||
|
||||
+5
-3
@@ -240,10 +240,12 @@ elseif($Stage -eq 'Build')
|
||||
}
|
||||
|
||||
try {
|
||||
$testResultsXUnitFile = "$pwd/TestResultsXUnit.xml"
|
||||
Start-PSxUnit -TestResultsFile $testResultsXUnitFile
|
||||
$SequentialXUnitTestResultsFile = "$pwd/SequentialXUnitTestResults.xml"
|
||||
$ParallelXUnitTestResultsFile = "$pwd/ParallelXUnitTestResults.xml"
|
||||
|
||||
Start-PSxUnit -SequentialTestResultsFile $SequentialXUnitTestResultsFile -ParallelTestResultsFile $ParallelXUnitTestResultsFile
|
||||
# If there are failures, Test-XUnitTestResults throws
|
||||
$testPassResult = Test-XUnitTestResults -TestResultsFile $testResultsXUnitFile
|
||||
$SequentialXUnitTestResultsFile, $ParallelXUnitTestResultsFile | ForEach-Object { Test-XUnitTestResults -TestResultsFile $_ }
|
||||
}
|
||||
catch {
|
||||
$result = "FAIL"
|
||||
|
||||
Reference in new issue
Block a user