Skip to content

Conversation

@SteveL-MSFT
Copy link
Member

This is the current thinking on being inbox in Windows

@awakecoding
Copy link

Is the goal of the PowerShell 7 to bootstrap an installation, or literally serve as a shim executable that is smaller than the complete installation, and will automatically bootstrap the installation on the first call, forwarding all the calls to an on-demand PowerShell installation?

I'm not entirely sure than an on-the-fly installation from a pwsh shim is a good idea, but I could be wrong. I would be very happy with a simple, in-box way to just get the latest and greatest PowerShell. I would stay away from solutions that just launch a child pwsh.exe to interact with it using standard input/output, this can only be flaky at best. Do not forget that we'd also need to correctly report back the child process exit code, etc.

However, if you want to pursue the pwsh shim idea, one thing I've already put some thought into would be to create a self-contained Rust executable and make it a PowerShell native host process. Here's the latest code Rust I have to do this: pwsh-host-rs. Since a Rust executable is easy to keep self-contained, and since the PowerShell native host does not rely on PowerShell or .NET, it can easily be improved to detect PowerShell and install it if necessary.

Even better: rather than deal with a subprocess, it can literally load PowerShell from the disk and become a full pwsh.exe replacement. This was actually the first prototype I did, where the only thing I did was launch the same entry point as the real pwsh.exe from my PowerShell native host process, but it would entirely run within the current process. All we'd need to do is pass it the same command-line parameters and it would be entirely transparent.

@LeonarddeR
Copy link

Have you considered the way WSL works in Windows 10/11? It is able to download distributions from the Windows Store, so it somehow behaves like a bootstrapper, right? Also, how are the WSL kernels tight to the lifecycle of Windows releases?

I'm not sure whether I follow the Admin vs. Non-Admins scenario yet. Are you suggesting that PowerShell 7 will be installed under the current user when pwsh is started non-elevated? I really think this is a scenario to avoid. Again, it makes sense tosee how bash behaves in this case.

@SteveL-MSFT
Copy link
Member Author

@awakecoding I believe the RFC covers pwsh shim vs pwshup. I don't think they are mutually exclusive, so pwshup could be something we invest into in the future and would be cross-platform while this is Windows specific.

@LeonarddeR this concept was taken from WSL. However, the Windows Store is not available on Server which is a motivation to go a slightly different route. WSL kernels (the Linux distro) is updated outside of Windows and wouldn't be affected by Windows lifecycle while WSL itself would be. Similarly, the pwsh shim would be under Windows lifecycle support, but not the installed PS7. As for admin vs non-admin, we need to support the case where the user is not admin and not require an admin to install.

@LeonarddeR
Copy link

@LeonarddeR this concept was taken from WSL. However, the Windows Store is not available on Server which is a motivation to go a slightly different route.

Ah, so my assumption that WSL is able to install distros from the store on server is incorrect.

As for admin vs non-admin, we need to support the case where the user is not admin and not require an admin to install.

I see.

I have two other thoughts:

Updates

While I understand that the PWSH shim can be used to check for updates and keven keep it up to date, wouldn't it be better to just handle this by Windows Update, unless the currently installed version of PowerShell is out of date? To put it another way, why is relying on Windows Update unsufficient, apart from ensuring that we're on a supported version of .NET?

PowerShell vs .NET

Another concern is decoupling PowerShell from .NET. As far as I understand, every PowerShell release (e.g. 7.2) is tight to a particular release of .NET (6 in this case).
Wouldn't it be interesting to have the .NET team on board for an installation strategy .NET would benefit from? E.g.

  1. Have a dotnet shim together with a pwsh shim
  2. The psh shim internally uses the dotnet shim to install a dotnet runtime and then installs PowerShell, preferably as a runtime dependant package.
  3. As the pwsh shim calls the dotnet shim to ensure there's a runtime, both .NET and PowerShell can be kept up to date.

The boostrapper should explicitly create a detached child `pwsh` process and then exit.
As a detached child process, it will continue execution even after the parent has exited.

Expectation is that the bootstrapper will always be first in the `$env:PATH` and executed first, so it can also serve

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this add even more time to executing pwsh, you now have to wait for 2 processes to initialise and while it's minute it's still a problem today with just pwsh.exe itself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will add some time, but should be minimal impact as the shim is in native code, but there is a cost to starting a 2nd process, but I think overall it'll be minimal compared to the current limitations of pwsh startup with .NET

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @awakecoding's comment has a good point. He suggests that, if we decide to go with the shim approach, then the bootstrapper pwsh can actually host CoreCLR runtime, and calls into pwsh.dll via its entry point. In this way, we don't need to spin up 2 processes and handle STD io redirections.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daxian-dbw it's actually even better than that: you can literally use the hostfxr APIs to call into the pwsh.exe command-line entry point... within the current process. You literally load pwsh.exe and launch it within the PowerShell native host process without a subprocess! When using this specific mode of launching with a PowerShell native host, you can only do it as a one-shot thing where you basically just call it once and let it return, but that's precisely what we want here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @awakecoding, I just saw the run_pwsh_lib and run_pwsh_app in your project. What's the benefit of loading and launching pwsh.exe comparing to loading Microsoft.PowerShell.ConsoleHost.dll and calling into the entry point function Start(string[] args, int argc)? The former will load extra libraries (pwsh.exe and pwsh.dll).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @awakecoding, I just saw the run_pwsh_lib and run_pwsh_app in your project. What's the benefit of loading and launching pwsh.exe comparing to loading Microsoft.PowerShell.ConsoleHost.dll and calling into the entry point function Start(string[] args, int argc)? The former will load extra libraries (pwsh.exe and pwsh.dll).

There is currently no way to load less than what pwsh.exe needs, and even if there was a way to do it (lazy loading of DLLs, etc) then the proper way would still be with a .NET native host process, so we're back to my technique again.

Also, how would you load ConsoleHost.dll from a process that isn't .NET, and without creating a subprocess? Chances are you would need to use the hostfxr APIs again to do this cleanly, and then you'd be limited to the command-line interface.

The PowerShell native host approach is the only one that avoids creating a subprocess and solves the problem very efficiently. Think of it as just replacing pwsh.exe out of the full PowerShell installation, except it doesn't rely on .NET at all, making it the perfect shim.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, how would you load ConsoleHost.dll from a process that isn't .NET, and without creating a subprocess? Chances are you would need to use the hostfxr APIs again to do this cleanly, and then you'd be limited to the command-line interface.

The pwrshplugin used by PowerShell for WSMan remoting loads System.Management.Automation.dll directly from native process to create a function pointer, see code here.

We also have an ancient native powershell host written in C++, and it used to load ConsoleHost.dll directly from native process, though it hasn't been used for a long time. See the code here.

We also have the DSC native agent that loads CoreCLR and calls into managed code form native code. So, I think it's doable, only that we need to figure out how to get the Trusted Assembly List (TPA) populated by using hostfx.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a similar approach that shouldn't change much, the sample you linked to appears to be using COM Interop to load PowerShell. While I believe it is still possible to use COM Interop on Windows with PowerShell 7, I do recall trying it on Linux only to realize the COM exports were missing on non-Windows.

The current project is only for Windows, but it wouldn't hurt to use the recommended hosting APIs, and that would mean the hostfxr APIs. Maybe the only thing we can conclude at this point is to use the hostfxr APIs to make a .NET host, and then move on to how we'd load and call PowerShell using it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Regardless of the implementation details, I believe we should make the bootstrapper a .NET host, if we want the bootstrapper a shim that always runs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having the pwsh bootstrapper be a .NET host is interesting. If it's simply hosting the consolehost and passes all arguments to it to evaluate, then I would agree that is a fine solution.


This will allow `pwsh -c customer_script.ps1` to work seamlessly as though PS7 was available inbox.

The bootstrapper would need to start the real `pwsh.exe` and bind stdin/stdout so that inputs and outputs come from `pwsh.exe` seamlessly.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would also need to ensure this works in an interactive situation where just doing pwsh will spawn the process that inherits the console handles itself rather than a redirected stdio.

It also means if you do something like pwsh -c "my command" from WinPS it will not wait until until it is finished because the parent (bootstrap) process has ended.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good points, will make these explicit

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another issue is how do you get the exit code to bubble itself back up to the caller. You essentially need to either have the bootstrap process continue to run until pwsh is finished and have that set it's own exit code to that of pwsh's.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggestion of launching a subprocess pwsh.exe from the shim pwsh.exe has a lot of potential issues, but if we make the pwsh.exe shim a PowerShell native host process, we can actually make it behave exactly like the original without even spawning a subprocess. It would literally be the same as pwsh.exe but without PowerShell, and the ability to load the .NET runtime + launch PowerShell entirely from disk. I've done this before, just not with the full "let's find and download PowerShell on the fly" part.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea this does sound like a better solution, I'm not too well versed in hosting the CLR side but a colleague mentioned it should be possible for the pwsh shim to do the bootstrapping and then just host the CLR in the same process once that step is done. You save the hit of spawning yet another process and don't need to worry about IO redirection and other things like handle inheritance and the like.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the shim has to stay resident and manage the pwsh lifecycle. I have many scripts that depend on calling pwsh.exe synchronously.


### Auto-updating

Upon startup of the bootstrapper (following rules of [admin vs non-admin](#admin-vs-non-admins)) will detect if the installed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this really be part of Windows/Microsoft Update? I dislike the idea of pwsh trying to do even more work at startup and potentially change the ground that I'm working on by automatically updating. I feel like the bootstrap script if this goes ahead should just install the initial version and updates are managed through WU.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original reason not to just use WU was because it wasn't supported on Nanoserver, but since we've decided Nano is out of scope, we should revisit this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of today, I think WU will work only if the installation is done through MSI and has the "use windows update" checked. How would it work for non-admin scenarios? I believe there will be many users using the non-admin installation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jborean93 Agreed. I'm not comfortable with the idea that my set of build nodes will update to a newer version of PowerShell merely by running pwsh as part of a build. I prefer to be "in control" of when that happens.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use winget as fallback.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

winget is not available on Windows Server and Windows Server support is required

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT Since you say that Nano Server is out of scope, does that mean that PowerShell could be delivered via MSI after all (rather than Squirrel mentioned above)? IIRC, all SKUs of Windows other than Nano Server support Windows Installer.


### Configuration

Some registry configuration (settable via Group Policy) would be needed to disable auto-updating.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another reason for doing updates through WU, it's something already understood by admins and offers the ability for orgs to cache the update files on their own servers for distribution rather than having to find another way to get that data from the net.

However, when 7.x is out of support, then it should auto-update to 7.x+1.
This is consistent with how our Microsoft Update support works to keep users patched and on a supported release.

The auto-update applies regardless if PS7 is started interactively or via automation (explicitly using the `-noninteractive`, `-file`, or `-command` switch).
Copy link
Member

@daxian-dbw daxian-dbw Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating from 7.x to 7.x+1 can potentially break existing automation workload. Here are 2 real-word issue reported after the users moved to 7.2 from 7.1:

  1. The reader's MaxDepth of 64 has been exceeded PowerShell#16457 -- PowerCLI module was broken in 7.2 because of a breaking change in Newtonsoft.Json that was made to prevent a DoS vulnerability.
  2. Multiple Ambiguous Error under Windows 11 but not Windows 10 PowerShell#16506 -- method resolution failed for a working script because new overloads were added to System.Text.Json.JsonSerializer.Deserialize(...) that causes a conflict in method resolution.

Even if PowerShell itself can be backward regression free (best case scenario), the assemblies shipped with PowerShell can break user's existing workload, and there is nothing PowerShell can do to prevent that from happening. So, I think we should never automatically update from 7.x to 7.x+1. That should always be an explicit decision made by the user.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a matter of opt-in or opt-out. Secure by default means you have to opt-out of automatic updates. I would expect folks who rely on automation to be experts vs folks who simply want to use a shell

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect folks who rely on automation to be experts vs folks who simply want to use a shell

I'm not necessarily arguing for or against automatic updates, but FWIW in my experience the opposite is true. At least on the Windows side, there's a much larger amount of less experienced folks who can cobble a script together than folks who are even a little comfortable in a shell.

- If installed, pass-through all arguments to the new detached `pwsh` child process
- This means that if PS7 is already in the `PATH`, then that version (whether installed via MSI, MSIX, or other means)
needs to be updated outside of the bootstrapper
- Otherwise, [install](#installer) PS7 and then pass-through all arguments to the new detached `pwsh` child process

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this would essentially circumvent software installation policies established by the enterprise and - in a worst case scenario - might become yet another hole enterprise will now need to be closing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would one control aspects of such installation? E.g. things like path, whether it is single/multi user install, logging and verbosity

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another issue that comes to mind: what about software that first checks for the presence of pwsh.exe, and then calls "pwsh.exe --version" to detect the installed PowerShell version? Not only the shim would fool most software into thinking it's already installed, but the "pwsh.exe --version" version call would trigger the actual installation.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this is the same problem the Python for Windows folks created. They have a python.exe alias that build scripts detected as "Python is installed". Terrible dev experience.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, PS7 should just be considered a Windows feature-on-demand (even though it doesn't use that mechanism specifically because a literal Feature-on-Demand requires the 10 year support lifecycle) and would install via Windows Update channel (this is in the RFC). So for all intents and purposes, pwsh.exe is in-box regardless if it needs to bootstrap itself initially. pwsh -version would work as though it was installed.

needs to be updated outside of the bootstrapper
- Otherwise, [install](#installer) PS7 and then pass-through all arguments to the new detached `pwsh` child process

The boostrapper should explicitly create a detached child `pwsh` process and then exit.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appears to me it would break a range of scenarios where users formed PS command lines and used explicit process start and wait (ShellExecute, _wpopen, Process.Start, etc.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these problems are solvable although it might require the installed pwsh to be first in the path so that the bootstrapper is no longer called unless called explicitly after PS7 is installed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might require the installed pwsh to be first in the path so that the bootstrapper is no longer called unless called explicitly after PS7 is installed

Yes please!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to add some specifics here.

Windows PowerShell is often used as a wrapper around poorly-written application installers. Software distribution systems, such as Configuration Manager or Microsoft Endpoint Manager (Intune), call powershell.exe and pass it the wrapper script. Termination of the powershell.exe process signals the caller (ConfigMgr, Intune, etc.) that the installation is complete, which triggers evaluation of application detection rules. If powershell.exe were to spawn another copy of itself and exit, the caller would run detection rules while the real installation was still in progress, and it would report failure to the user (e.g., in Software Center or Company Portal). If PowerShell (pwsh.exe) spawns another process and exits, then it cannot serve as a replacement for Windows PowerShell in this scenario.

That may not be a terribly compelling argument, since such uses would rarely require features beyond what Windows PowerShell provides; administrators could just keep using Windows PowerShell for that purpose. The same pattern is commonly used for other functionality, though, where the improved features of PowerShell may be highly useful and desirable. PowerShell is used as a gap-filler for functionality that is missing from such endpoint management products: If FunctionalityX is not provided by the system, an administrator can write a custom solution in PowerShell to implement the needed functionality and deploy it to devices as an "application" that can be installed and uninstalled. Again, if pwsh.exe were to launch a separate process and then exit, this scenario would be broken and render PowerShell unusable for this purpose.

- a separate Windows feature that can be uninstalled (so that using `pwsh` would not automatically work, or is being installed by other means)
- different icon for the bootstrapper to indicate it is a bootstrapper

### .ps1 registration

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ps1 registration/integration makes sense as feature of PowerShell installer; not something for bootstrapper to be solving.


`pwsh.exe` will be registered to execute .ps1 scripts, by default.
However, it will have code to detect if started from the `explorer.exe` and instead
give an error message that scripts need to be run from the console and not from Explorer.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"and not from Explorer" - few questions:

why blocking a launch from shell?

and in doing so, why special treatment to explorer?
if I am using another shell - e.g. Total Commander, what should be different about it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two other aspects come into my mind:

I am using self elevating PowerShell scripts.
How would this affect the secondary instance that's elevated.

For Windows Explorer please consider an implementation that's compatible to have PowerShell 7 when using the address line entering PowerShell
This currently launcher a PowerShell in the directory currently Windows Explorer opened. (same as cmd does)

Copy link

@riverar riverar Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if my script has no TUI/GUI and running via Explorer blindly is an expected/valid scenario? This constraint seems orthogonal to the bootstrapper story.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mention about explorer.exe is to prevent folks from downloading a .ps1 and accidentally executing it by double clicking it in Explorer. In this case, to support default execution by other processes (so they can just expect a foo.ps1 to work as foo.cmd does today), we would need to associate .ps1 with pwsh but special case the explorer.exe use case. Software today have to wrap .ps1 within a .cmd which makes them not write .ps1 and write batch files instead

@awakecoding
Copy link

Regarding the pwsh shim, the best approach would be to use a PowerShell native host process instead of launching a pwsh subprocess. This is something I have done in the past, if you look close enough in my screenshot you'll see I'm using the pwsh command-line entirely in-process from a C program.

A cleaned up version of my PowerShell native host prototype was rewritten in Rust under the pwsh-host-rs project, which is what would be ideal to build a pwsh shim. It uses a helper function that was introduced in PowerShell 7.2 to avoid using files on disk other than vanilla PowerShell.

However, when 7.x is out of support, then it should auto-update to 7.x+1.
This is consistent with how our Microsoft Update support works to keep users patched and on a supported release.

The auto-update applies regardless if PS7 is started interactively or via automation (explicitly using the `-noninteractive`, `-file`, or `-command` switch).
Copy link

@afedyashov afedyashov Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This auto-update is so scary.

I maintain few dozen of psm1 modules - several hundred of exported functions total, and I would not jump to a different version of PowerShell that had not been scrutinized by thorough testing before.

Imagine - one day, because of some apparently small change somewhere in ConvertTo-Json function behavior - all CI pipelines fall apart, just because somebody maintaining the server didn't read the fine print.

I feel this area of the proposal needs a bit more scrutiny.


Current design is based on auto-update (unless configuration is set not to) even if the usage is via automation.
For example, remotely or using task scheduler to execute a script.
A design decision could be made to not auto-update if we know the usage is not interactive,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having my automation engine upgrade outside of my patch cycle is kind of scary. I love the work the team has done to add PS7 to WU/MU. I believe that established process is the better method for upgrading versions.

@Karl-WE
Copy link

Karl-WE commented Dec 2, 2021

Have you considered the way WSL works in Windows 10/11? It is able to download distributions from the Windows Store, so it somehow behaves like a bootstrapper, right? Also, how are the WSL kernels tight to the lifecycle of Windows releases?

Good questions about WSL.
Some components included in Windows seem hard to be serviced. Naively I would not understand why it's not possible to patch them via CU. Example Windows Optional Feature of OpenSSH.

As you mentioned the store there unfortunately no store or business store or its future sub on Windows Server nor on Windows 10 LTSC.

Not to forget about the Windows Server Core Installation Option.
On top of that Windows Server Core unfortunately cannot be joined to AAD due to missing dsregcmd.

If we had these modern options (doubt it will happen for some conceptual reasons) it could make things easier for PowerShell, winget, Windows Terminal and many other applications to be provisoned.

Resulting Rust binary code is very similar in size and performance as C/C++.
Rust built code is supported in Windows.

Rust uses the MS C runtime at execution, but we should statically link so that there aren't external dependencies that may be missing on the system.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Statically linking the CRT will prevent servicing should the need arise (e.g. security). Instead, I would look into the hybrid CRT solution. https://github.com/microsoft/WindowsAppSDK/blob/main/docs/Coding-Guidelines/HybridCRT.md

This presents two problems:

- This works fine for interactive use, but for automation, they now have to bootstrap PS7 before they can use PS7 to bootstrap other configuration
- Windows Store is not supported on Windows Server which is required
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could alternatively investigate using AppInstaller. Or at least evaluate it and include the "why not" in this section.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that MSIX specific? MSIX is not supported on Windows Server

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT MSIX is supported on Windows Server. You might be thinking of the AppInstaller app (which is separate from the .appinstaller manifest).

`pwsh.exe` will be registered to execute .ps1 scripts, by default.
However, it will have code to detect if started from the `explorer.exe` and instead
give an error message that scripts need to be run from the console and not from Explorer.
This means that from cmd.exe, you can execute .ps1 scripts without explicitly calling `pwsh.exe` and that applications
Copy link

@rashil2000 rashil2000 Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the .ps1 extension be added to the PATHEXT environment variable? I feel if the goal is to give PS scripts a first-class treatment on Windows similar to .bat and .cmd scripts, it'd make sense to give the ability to invoke them without having to specify the extension every time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that is the intent so that foo.ps1 could just be executed as foo

- a separate Windows feature that can be uninstalled (so that using `pwsh` would not automatically work, or is being installed by other means)
- different icon for the bootstrapper to indicate it is a bootstrapper

### .ps1 registration

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be out-of-scope, but please consider the Hosted App Model.
PowerShell/PowerShell#15758

@iSazonov
Copy link
Contributor

iSazonov commented Dec 4, 2021

While bootstrapper looks technically interesting it is actually useless - I see no benefit for corporations or individuals.

Bootstrapper and the described process is contrary to experience. What did we have in the past? MSFT has released hundreds of updates continuously at unpredictable times. And where did we gradually come to? MSFT now releases single cumulative updates once a month or less for select products. Enterprises and individuals can plan update process.
It is reasonable to ask whether the bootstrapper will be as reliable and secure as WU/MU? Obviously no, WU/MU is a large, complex, reliable and secure system, bootstrapper cannot compete with it. Enterprises use WU/MU over Internet directly or through WSUS or SCCM. They do not need just another channel of updates - for them this is an additional cost.

The question is WHAT exactly will be updated through WU. And if the goal is to have PS7+ on all Windows systems, then a reasonable question arises - for what? What are the benefits? Cross-platform?
Then as Enterprise administrator I expect:

  1. PS7+ can be automatically installed, updated and configured on all Windows systems by traditional means - implemented partially
  2. All Microsoft modules are ported to PS7+ - implemented partially
  3. PS7+ can be automatically installed, updated and configured on all Unix systems by traditional means - implemented partially
  4. Remoting works crossplatform - not implemented at all
  5. PS7+ is more small and more fast - no, it is large and more slow
  6. PS7+ has features which "kill" Windows PowerShell - no

Looking at this, any IT department will reject the move to PS7. The absence of remoting is especially disagreeable. Without it PS7+ is a toy for Enterprises.
If we talk about cross-platform as a benefit of PS7 +, then it is not enough to have PS7 + on all Windows systems - we need to have PS7 + on all Unix systems, and transparent remoting should work OOB on all platforms.

Let's get back to "The question is WHAT exactly will be updated through WU/MU."
Now we see that we need to add Unixes and their update channels here.
And the main thing remains - WHAT.

What does experience tell us?
Windows PowerShell is distributed as WMF for years and this WMF has not always been in-box. See https://docs.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/overview?view=powershell-7.2

From this experience MSFT should release cross-platform WMF 7.
This package may have a Windows-independent update cycle.
WMF 7 possible content:

  1. Mandatory component - .Net 7+
  • optional .Net components - ASP.NET Core, Entity Framework, Windows Forms, .NET MAUI, WCF, WPF, ...
  1. PS 7+
  2. Common modules
  3. Common DSC classes
  4. ...

It is important to have .Net as separate component in the WMF so that other applications can benefit. It does not prevent distribution of self-contained applications but allow other developers create and distribute small applications using shared .Net.

And WMF 7 should have Unix version too.

@sharpninja
Copy link

And WMF 7 should have Unix version too.

I would think this would make life at Azure's operations much better.

@essentialexch
Copy link

  1. All Microsoft modules are ported to PS7+ - implemented partially

I know the PS Team doesn't care - but I curse PS 7 every time I try to use it and gwmi isn't there by default.

I'm curious as to what percentage of enterprises have migrated their corpus of 15+ years of PS 1-5 to PS 7.x? I expect it's quite small.

@Karl-WE
Copy link

Karl-WE commented Dec 8, 2021

from my perspective I do see good features in PS7. Have a look at network commands or *-service commands etc.

I do not see the need to have a package such as WMF 7, while it would be consistent with the experience we had. PS 7 can be easily deployed via MSI and updated WU etc.
I often Windows Servers where WMF 5.1 is not installed, limiting remote manageability.

You mentioned there is no remoting, there is remoting but it is disabled by default, but could be enabled, isn't this the case?

@iSazonov
Copy link
Contributor

iSazonov commented Dec 8, 2021

You mentioned there is no remoting, there is remoting but it is disabled by default, but could be enabled, isn't this the case?

@Karl-WE If you ask me I wrote crossplatform remoting.

@daxian-dbw
Copy link
Member

Remoting works crossplatform - not implemented at all

SSH remoting is a cross-platform remoting.

@Karl-WE
Copy link

Karl-WE commented Dec 8, 2021

You mentioned there is no remoting, there is remoting but it is disabled by default, but could be enabled, isn't this the case?

@Karl-WE If you ask me I wrote crossplatform remoting.

Given what I've seen how Systems get compromised with remote PowerShell from kali Linux to Windows using PS 5.1 I am not sure if cross platform remoting is feasible.

I can remember a request from icinga admins how they could connect via remote PowerShell, so it seems there are other usecases than this 😉

@SteveL-MSFT
Copy link
Member Author

After some internal discussion, we're likely going to pursue a install-powershell type cmdlet instead of this bootstrapper primarily because it will be significantly less work for the team and almost the same result. RFC for that will come later.

@Karl-WE
Copy link

Karl-WE commented Jan 15, 2022

Thanks @SteveL-MSFT for the follow-up, would be glad to link the new RFC here so participants can review (if public).

@sharpninja
Copy link

After some internal discussion, we're likely going to pursue a install-powershell type cmdlet instead of this bootstrapper primarily because it will be significantly less work for the team and almost the same result. RFC for that will come later.

Please give an argument to install as a dotnet tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.