Skip to content
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

PowerShell SDK should support easier invocation of PowerShell that is hidden from the debugger and that ignores $PSDefaultParameterValues and *Preference variables #10334

Closed
KirkMunro opened this issue Aug 9, 2019 · 11 comments
Labels
Issue-Enhancement the issue is more of a feature request than a bug Resolution-No Activity Issue has had no activity for 6 months or more WG-Interactive-Debugging debugging PowerShell script

Comments

@KirkMunro
Copy link
Contributor

KirkMunro commented Aug 9, 2019

Summary of the new feature/enhancement

When people build non-module tools that use the PowerShell SDK, they ultimately need to invoke some PowerShell commands. For tools are meant to function as a black box, the PowerShell commands that the tool invokes...

  1. ...should be hidden from the PowerShell debugger (so that breakpoints do not trigger on tool internals);
  2. ...should not pick up on user parameter preferences defined in $PSDefaultParameterValues;
  3. ...should not pick up on user invocation preferences defined in $*Preference variables;

This needs to be very, very easy so that tools can work as they were designed, without changes in behavior because of user preferences, and without the PowerShell debugger tripping on non-user code that is meant to be internal.

For a related discussion that highlights what tool makers need to think about in detail, see this comment in issue #2121 of PowerShell\vscode-powershell. That discussion also shows the scaffolding that is required to do something that should be very simple and supported in the SDK via a few flags.

Proposed technical implementation details (optional)

Any public interface that allows users to build PowerShell commands piecemeal (i.e. AddCommand, AddParameter, AddScript, AddArgument, etc.) and then invoke them needs to support invocation options that:

  • hide the command(s) from the debugger;
  • ignore $PSDefaultParameterValues;
  • automatically apply default values for any common parameters that are not explicitly used.

That's not very specific, so obviously more investigation would be necessary to identify where to create these options so that they can be used via public interfaces, and where the options would need to be plumbed through the PowerShell runtime so that toolmakers get the results they expect.

Update copied from discussion below:

To achieve this goal, S.M.A.PSInvocationSettings will be extended with a DebuggerHidden property, which would ensure the commands were hidden from the debugger, and a IgnorePreferenceVariables property, which would ignore $PSDefaultParameterValues and $*Preference variables. Programmers using the SDK can pass their PSInvocationSettings instance into S.M.A.PowerShell.Invoke, and with the new settings properly plumbed through the runtime, they won't have to worry about user preferences impacting internal APIs.

@KirkMunro KirkMunro added the Issue-Enhancement the issue is more of a feature request than a bug label Aug 9, 2019
@KirkMunro KirkMunro changed the title PowerShell SDK should support easier invocation of PowerShell that is hidden from the debugger and that ignores $PSDefaultParameterValues and preference variables PowerShell SDK should support easier invocation of PowerShell that is hidden from the debugger and that ignores $PSDefaultParameterValues and *Preference variables Aug 9, 2019
@iSazonov iSazonov added the WG-Interactive-Debugging debugging PowerShell script label Aug 9, 2019
@BrucePay
Copy link
Collaborator

@KirkMunro Why not just use a separate runspace.

@KirkMunro
Copy link
Contributor Author

@BrucePay That's a great question, and I'm going to think about that for a bit.

Now you've got me wondering if this is as simple as something that just isn't obvious because it's not a documented best practice to use for things like this, but maybe it should be.

As someone who has worked on PowerShell tools for many years, where this problem has shown up here and there, I wonder why I never thought of doing that. I'm not the only one, though, because this showed up in PowerGUI, it was an issue in PowerWF/PowerSE, and now it shows up in VSCode-PowerShell, and nobody involved other than you, just now, suggested using a separate runspace, so it's not an obvious design approach that just jumps out at you. At least, not until you hear it from @BrucePay.

@KirkMunro
Copy link
Contributor Author

KirkMunro commented Aug 12, 2019

@BrucePay After thinking on this some more, doubting that it's really that simple, and seeing @SeeminglyScience confirm that it's not that simple, I'm back to my original thought: it's not that simple, and the SDK should support working with PowerShell in a runspace without taking user preferences into account.

Tools that don't care about state could use their own runspace, but tools that are built on top of PowerShell, offering an IDE, or debugging, etc. need state information from the user's runspace to ensure that they are working with the same information that is available to the user, and they wouldn't have access to that information if they used a separate runspace.

@BrucePay
Copy link
Collaborator

@KirkMunro

need state information from the user's runspace

Conveniently available through the SessionStateProxy APIs on the runspace :-)

need state information from the user's runspace

ISE seemed to do OK. It managed, manipulated state and debugged multiple runspaces both local and remote.

Anyway, this might help (assuming it's still there). As you know, a runspace is all about state, specifically session state. There is one global session state object per runspace and then one each for each module loaded. The module session state objects are linked to the global session state object so they all share the global namespace. The global session state object is linked to null. However, we designed things so that it's possible for a non-global session state object to be created that isn't linked to anything. We figured that there might be scenarios where you wanted an isolated session state even though we didn't know of any such scenarios. So you might be able to create an isolated "tools" environment using this mechanism (assuming it still exists and is public - I haven't looked.) But note - this is an empty session state - no commands, no variables, nothing. You'd have to manually populate it to have any commands available to you.

@KirkMunro
Copy link
Contributor Author

KirkMunro commented Aug 18, 2019

Is that the right way to go for this though?

Creating/managing a session state for this seems more complicated than what I was thinking.

I was leaning more towards adding properties to S.M.A.PSInvocationSettings, such as DebuggerHidden, which would ensure the commands were hidden from the debugger, and IgnorePreferenceVariables, which would ignore $PSDefaultParameterValues and $*Preference variables. Then programmers using the SDK could pass their PSInvocationSettings instance into S.M.A.PowerShell.Invoke, and as long as the new settings were properly plumbed through the runtime, they wouldn't have to worry about user preferences impacting internal APIs.

@KirkMunro
Copy link
Contributor Author

ISE seemed to do OK. It managed, manipulated state and debugged multiple runspaces both local and remote.

ISE isn't that advanced as far as IDEs go, and it is still susceptible to internal behavior that can be unintentionally manipulated by use of $PSDefaultParameterValues, breakpoints, and $*Preference variables. PowerShell itself suffers the same problem. It just doesn't show up that often, but regardless of the frequency, SDK users should be able to use the runtime in a way that internals are kept internal.

@SeeminglyScience
Copy link
Collaborator

ISE seemed to do OK. It managed, manipulated state and debugged multiple runspaces both local and remote.

ISE isn't that advanced as far as IDEs go

Yeah the ISE could get away with a bit more because it doesn't try to do a whole lot. It also had the benefit of InternalsVisibleTo. I can't look at the code to check obviously, but in the few places that it does go the extra mile, I'm guessing it leans on internals heavily.

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

2 similar comments
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 16, 2023
Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug Resolution-No Activity Issue has had no activity for 6 months or more WG-Interactive-Debugging debugging PowerShell script
Projects
None yet
Development

No branches or pull requests

4 participants