-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Make PowerShell able to enable logging of script block execution on Unix platforms #5791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
39af334
3dd86f5
263ec24
6ab1ad7
41c66db
117e83a
a6c62bf
167bbad
b4b864f
3b5badc
3b94173
6ee608f
01ecf4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1643,59 +1643,6 @@ private int GetCmdletRemovalIndex(List<CmdletInfo> cacheEntry, string PSSnapin) | |
|
|
||
| internal ExecutionContext Context { get; } | ||
|
|
||
| /// <summary> | ||
| /// Reads the path for the appropriate shellID from the registry. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe leave this? How Windows user or Domain Admins can system-wide switch from Windows PowerShell to PowerShell Core?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand your question. This method is removed because it's not used anywhere.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thoughts was about side-by-side scenario but it seems not help. |
||
| /// </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"); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| 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 @@ internal static ModuleLoggingGroupPolicyStatus GetModuleLoggingInformation(out I | |
| { | ||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need multiple return paths? Why not if (... == false) else if (... == true) and set status in both cases.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't change the original code, will update it to set |
||
| { | ||
| 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; | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change, the Windows PowerShell GPO settings don't apply to PSCore6, correct? This seems correct to me, but is a
breaking change. We should label this PR as such. cc @joeyaielloThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, GPO settings in Registry won't apply to PowerShell Core. I have added the
breaking changelabel. Thanks for catching that.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem correct to me. @Indhukrishna DSC has had feedback that seems to indicate that they expect GPO to apply.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will start to work on enabling GPO as well on windows. The preference order of the settings should be config file --> GPO, meaning if a policy setting is defined in the config file, then use it; if it's not defined in the config file, query registry. This way, you can have control whether you want the GPO settings to take effect.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Common rule is that Computer GPO is high priority, then User GPO, then computer wide config, then user config. It is critical rule and security related.
Update.
Software\Policies\Microsoft\Windows\PowerShell- herePoliciesassume that it is high priority and should overlap other configs - users can not change its.Software\Microsoft\Windows\PowerShell- it is a normal config corresponding to a text config file. This setting can be set manually by user or by using Group Policy Preferences (GPP). I think it should be low priority over a text config file (looks as changing defaults or set recommended defaults that the user can change by a config file).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the policy related settings, we are having a debate on which one should take preference. I will talk to @TravisEz13 later today about it.
For non-policy related settings, we shouldn't use registry settings anymore but only refer to the config file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conclusion is: on windows, we query group policies from registry first, and if the requested policy is not defined in GP, then we query from the configuration file.
New commit has been pushed to enable this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree - GPO is great Enterprise feature and Domain Admins should have full and flexible control on PowerShell. We could discuss this in a Issue (as I mention below too).
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean "non-policy related settings", like the settings in "SOFTWARE\Microsoft\PowerShell" today. They are not group policies.