Powershell: Use Windows Powershell in Pwsh7

Created on 10 May 2020  路  10Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your name", "Name", "Lastname")

or

Get-WmiObject win32_physicalmemory

Expected behavior

working as in windows powershell, basically anything related to com or windows api cant be used in pwsh7

# Get-WmiObject win32_physicalmemory
>>


__GENUS              : 2
__CLASS              : Win32_PhysicalMemory
__SUPERCLASS         : CIM_PhysicalMemory
... others
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your name", "Name", "Lastname")

image

Actual behavior

# Get-WmiObject win32_physicalmemory
>>
Get-WmiObject: The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

~
# [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

~
# $name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your name", "Name", "Lastname")
InvalidOperation: Method invocation failed because [Microsoft.VisualBasic.Interaction] does not contain a method named 'InputBox'.

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question

Most helpful comment

@onriv thanks for updating the issue!

We're conflating a few separate issues here, but ultimately I think you could resolve them all without too much difficulty.

The *-WmiObject cmdlets were deprecated in PowerShell version 3. Please use the Get-CimInstance cmdlet as a replacement; for most tasks they are a drop-in replacement, parameters are all very similar or identical in a lot of cases. Some things previously directly referenced as methods on the objects may need to be handled with Invoke-CimMethod instead, however.

You will most likely not be able to reliably import a Windows PowerShell core module in pwsh, or if you can I would expect reduced functionality as it is over a remoting connection. I wouldn't count on it, and it's better to use the CIM cmdlets in pwsh instead.

As for the Visual Basic issue, not really sure where to begin on that, but I'd check the documentation for those libraries to see what's changed in the .NET Core versions of those. In a lot of cases, the GUI functionalities of many libraries were removed. That's neither here nor there, it's far beyond what PowerShell has any control over.

All 10 comments

Please read and fill out the proper issue template for your question. There is't enough information here to really make any kind of meaningful determination as to what the problem actually is.

I will, however, note that neither of your listed commands work in Windows PowerShell either. Not sure where you got those from.

@vexx32 I'm sorry and the question should have been clarified and followed the template now.

And though I used

 Import-Module Microsoft.PowerShell.Management -UseWindowsPowerShell
WARNING: Module Microsoft.PowerShell.Management is loaded in Windows PowerShell using WinPSCompatSession remoting session; please note that all input and output of commands from this module will be deserialized objects. If you want to load this module into PowerShell Core please use 'Import-Module -SkipEditionCheck' syntax.


~
# Get-WmiObject win32_physicalmemory
>>
Get-WmiObject: The term 'Get-WmiObject' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

it's still not working

@onriv thanks for updating the issue!

We're conflating a few separate issues here, but ultimately I think you could resolve them all without too much difficulty.

The *-WmiObject cmdlets were deprecated in PowerShell version 3. Please use the Get-CimInstance cmdlet as a replacement; for most tasks they are a drop-in replacement, parameters are all very similar or identical in a lot of cases. Some things previously directly referenced as methods on the objects may need to be handled with Invoke-CimMethod instead, however.

You will most likely not be able to reliably import a Windows PowerShell core module in pwsh, or if you can I would expect reduced functionality as it is over a remoting connection. I wouldn't count on it, and it's better to use the CIM cmdlets in pwsh instead.

As for the Visual Basic issue, not really sure where to begin on that, but I'd check the documentation for those libraries to see what's changed in the .NET Core versions of those. In a lot of cases, the GUI functionalities of many libraries were removed. That's neither here nor there, it's far beyond what PowerShell has any control over.

@onriv For more info on Get-WmiObject, see Breaking Changes for PowerShell 6 - WMI v1 cmdlets.

@SeeminglyScience thanks, the document would solve my probelm for the wmi api

@vexx32 And I can't use .Net framework in pwsh7? I tried to add the dll of .Net but it didn't work neither:

~
# Add-Type -Path C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll


~
# $name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your name", "Name", "Lastname")
InvalidOperation: Method invocation failed because [Microsoft.VisualBasic.Interaction] does not contain a method named 'InputBox'.

mostly this part is for using com-object (like excel/outlook/vb). Sometimes switching from pwsh7 console to powershell and then switching back is not very convenient, especially if having to share some variables.

You can use the .NET API, it's just subject to it's own breaking changes outside of PowerShell's control. That library no longer contains the InputBox API and it's not controlled by the PowerShell team. See the discussion in #11513 about MsgBox in the same library.

Also note that it doesn't affect COM interop.

@SeeminglyScience @vexx32 thanks a lot ! Since the information have been enough for me, I closed the issue.

@SeeminglyScience @vexx32 Hello~ I still got a problem:

I got the dll version that windows powershell is using:

# [Microsoft.VisualBasic.Interaction].Assembly

GAC    Version        Location
---    -------        --------
True   v4.0.30319     C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll

And try to add the dll to pwsh7:

~
# [Microsoft.VisualBasic.Interaction].Assembly

GAC    Version        Location
---    -------        --------
False  v4.0.30319     D:\Users\sha*****\Apps\PowerShell-7.0.0-win-x64\Microsoft.VisualBasic.Core.dll



~
# Add-Type -Path C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll


~
# $name = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your name", "Name", "Lastname")
InvalidOperation: Method invocation failed because [Microsoft.VisualBasic.Interaction] does not contain a method named 'InputBox'.


~
# [Microsoft.VisualBasic.Interaction].Assembly

GAC    Version        Location
---    -------        --------
False  v4.0.30319     D:\Users\sha*****\Apps\PowerShell-7.0.0-win-x64\Microsoft.VisualBasic.Core.dll

but anyway it still use the version that pwsh7 port with?

@onriv in your last example, you've already loaded D:\Users\sha*****\Apps\PowerShell-7.0.0-win-x64\Microsoft.VisualBasic.Core.dll when you import the GAC's C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll. It's loaded because you've already used the Microsoft.VisualBasic.Interaction assembly in your first command. That means you can't load the second assembly; you get the first one, whose Interaction has no InputBox method.

If you start a fresh PowerShell session, this will work:

powershell Add-Type -Path C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll '

In this case though, I would recommend using a WinForms solution, since that's supported by the DLLs that come with PowerShell (so no Add-Type from the GAC needed).

@onriv there is a hack to get it working in pwsh7 core
load it as a dynamic assembly and invoke static method InputBox

$v = [System.Reflection.Assembly]::LoadFile('C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.VisualBasic.dll')

instead of directly referencing InputBox

[Microsoft.VisualBasic.Interaction]::InputBox("Title", "File data", "")

$hh = $v.GetExportedTypes() |? { $_.Name -eq 'Interaction'}
$to = $hh.GetMethod('InputBox')
$to.Invoke($null, @("Title", "File data", "", -1, -1))

Was this page helpful?
0 / 5 - 0 ratings