dotnet / interactive

.NET Interactive combines the power of .NET with many other languages to create notebooks, REPLs, and embedded coding experiences. Share code, explore data, write, and learn across your apps in ways you couldn't before.
MIT License
2.85k stars 381 forks source link

Powershell module not importing or cant find #1720

Open craftzneko opened 2 years ago

craftzneko commented 2 years ago

Describe the bug

Importing a module doesnt seem to work

Please complete the following:

Which version of .NET Interactive are you using? There are a few ways to find this out:

1.0.255901

Screenshots

image

craftzneko commented 2 years ago

Anybody have any idea if this should even be possible?

jonsequitur commented 2 years ago

@daxian-dbw Any ideas here?

daxian-dbw commented 2 years ago

@pr1malc0de Can you follow the instruction in the error message and see what you get when running Import-Module RemoteDesktop?

craftzneko commented 2 years ago

@daxian-dbw hi! I ran the import command it seemed ok (see screenshot)

craftzneko commented 2 years ago

@daxian-dbw anything else i can try?

Szeraax commented 2 years ago

I think the problem is that the RemoteDesktop module isn't built for Pwsh and I don't think that there is anything that .Net interactive can do to fix that.

If you look at the number of modules in each of my $PSModulePath folders, you'll see that I have 106 modules listed in the SAME PATH on WindowsPowershell 5.1, but only 64 modules on Pwsh 7.2. See image: image

If you open up a pwsh shell and run Import-Module RemoteDesktop -SkipEditionCheck, you'll see that Pwsh CANNOT open this module without doing a New-PSSession over to a WindowPowershell session and then import the commands into the current session.

I don't know if .net Interactive would want to add in the complexity of trying to support remote sessions to WindowsPowershell, however, if @jonsequitur knows whether they have an upcoming feature for supporting remote sessions over powershell remoting (don't know if SSH remoting could even be possible too), then this would be trivial (or automatically backported) as a part of that feature.

The fact that the module does import at all suggests that there MAY be hope yet.

There are various other modules that don't load in Pwsh when doing -SkipEditionCheck like Appx, PSWorkflow, and Servermanager. I wouldn't hold my breath.

daxian-dbw commented 2 years ago

@pr1malc0de Which RemoteDesktop module were you using? The one on PowerShell gallery is broken and it doesn't look like what you were using.

Szeraax commented 2 years ago

@daxian-dbw I feel confident that he's talking about the one included by default with windows:

image

craftzneko commented 2 years ago

@Szeraax @daxian-dbw thats correct it's the one that is included in Rsat tools I believe. I had thought that using the switch -UseWindowsPowerShell (even though my screenshot was before I tried) would just work, didn't realise that there would need to be compatibility with the .net interactive

daxian-dbw commented 2 years ago

@pr1malc0de @Szeraax Thank you both for the clarification! It turns out import-Module RemoteDesktop -UseWindowsPowerShell just silently failed because PowerShell remoting depends on BinaryFormatter even though it's obsolete, and due to the settings in .NET interactive, using BinaryFormatter for serialization/deserialization throws NotSupportedException. Below is an example with importing PersistentMemory with -UseWindowsPowerShell:

image

@jonsequitur BinaryFormatter.Serialize/Deserialize is a dependency of PowerShell SDK. Somehow the using of it is disallowed at run time. Would it be possible to enforce the obsoletion at compilation time, while allow it at runtime?

jonsequitur commented 2 years ago

Using BinaryFormatter directly should already emit a warning a compile time. For security reasons, we don't plan to allow its usage at runtime.

More details here: https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/binaryformatter-serialization-obsolete

daxian-dbw commented 2 years ago

I know that, but BinaryFormatter is used in PowerShell remoting and for back compatibility reason (remoting to Windows PowerShell 5.1), we had to keep it and suppress the warning in PowerShell. I just post a message to my team to re-evaluate this dependency.

If re-enabling BinaryFormatter functionality won't be possible in .NET interactive, then let's consider this issue by-design. Also, PowerShell remoting won't work in .NET interactive either due to the same reason.

daxian-dbw commented 2 years ago

Here is the response from our remoting/security SME:

Yes, we are aware of the issues using BinaryFormatter, and determined that there is no security hole since we control the data we serialize/deserialze. The information is used by Exchange and so we've kept it for remoting backwards compatibility. We can change the code to not use the serializer, but doing so may break compatibility with older WinRM endpoints, such as Exchange. Ok I just looked closely at the code. We have already removed the TimeZone deserialization, which is where there could be a security concern. So what we have left represents no security concern. If we decide to remove TimeZone altogether, we will likely break compatibility with Exchange endpoints. We would also be in violation of the PSRP.

To summarize, in PowerShell remoting, we already removed the deserialization code that uses BinaryFormatter, but we still do serialization of a specific type TimeZone due to back-compatibility reason. Since the deserialization code was already removed, there is no security issue at all anymore.

@jonsequitur Given that there is no security concern with the use of BinaryFormatter in PowerShell remoting, would you consider enable the use of it at run time for .NET Interactive? You can continue to disallow the direct use of it in the .NET Interactive project source code.

craftzneko commented 2 years ago

@jonsequitur any update on this do you think it will be possible now? Cheers

BrianTJackett commented 1 year ago

Run into (similar) issue when try to load the Microsoft.Graph.Authentication module in the OnLoadAsync method of custom extension. Able to load this module directly into a PowerShell Polyglot Notebook code block as a workaround, but would prefer to be able to load it dynamically / automatically in the background if possible.

daxian-dbw commented 1 year ago

An update: The use of BinaryFormatter was removed in PowerShell version 7.3. So, once .NET Interactive upgrades to use PS v7.3 SDKs, the Import-Module -UseWindowsPowerShell switch will work.

But I suggest waiting for v7.3.2 to come out, because there are some regression issues found in v7.3.0, and not all will fixed in v7.3.1.

BrianTJackett commented 1 year ago

I see PowerShell v7.3.0 just released within last month. Do you know timeline for 7.3.2 to release? Will use workaround of manually loading dependent PowerShell modules for the time being, but plan to revisit this in the future.

daxian-dbw commented 1 year ago

7.3.1 will be released in December. 7.3.2 will likely be in January at the earliest.

BrianTJackett commented 1 year ago

It looks like the next version of PowerShell SDK for Microsoft Graph (internal preview build at the moment) is able to load in .Net Interactive. Waiting on upcoming public preview release of that and PowerShell v7.3.2 before moving forward. Appreciate your insights so far @daxian-dbw.