I'm developing under .NET Framework 4.8. Note that I'm strictly locked to use .NET 4.8.
I've installed the "Microsoft.PowerShell.5.1.ReferenceAssemblies" Nuget package in order to be able automate Powershell commands, since the Nuget packages for PS6 and PS7 reuquires .net core at least.
The problem is that I'm unable to run the Get-WindowsDriver cmdlet in this scenario. I get this exception message when invoking the Get-WindowsDriver command:
The term 'Get-WindowsDriver' is not recognized as the name of a cmdlet, function, script file, or operable program
I've tried to import the DISM module via a call to InitialSessionState.ImportPSModule
(using the full file path to the Dism.psd1 file) and also I tried to import he module invoking the Import-Module cmdlet. In both cases and from what I observed it seems to do absolutely nothing of nothing, because if I invoke the Get-Module cmdlet (to try verify that the DISM module was loaded correctly) it does not return any single result nor produces any error.
This is the code I'm trying:
Dim state As InitialSessionState = InitialSessionState.CreateDefault()
state.ExecutionPolicy = ExecutionPolicy.Unrestricted
state.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psd1"})
Dim runspace As Runspace = RunspaceFactory.CreateRunspace(state)
Runspace.DefaultRunspace = runspace
Runspace.DefaultRunspace.Open()
Dim ps As PowerShell = PowerShell.Create(RunspaceMode.CurrentRunspace)
ps.Runspace = runspace
ps.Commands.AddScript("Get-Module | Out-String")
For Each result As PSObject In ps.Invoke
Debug.WriteLine(result.ToString())
Next result
Can I call Get-WindowsDriver cmdlet under .net 4.8 with PS 5.1?, and how to do that?.
Please note that I don't have this problem if I use the same code under net 5.0/6.0 (using "Microsoft.Powershell.*" v7.1.7 nuget packages like in this code example that I compiled and executed with no problems).
Try the following, I've tested it on Win 10.
Get PowerShell version:
Open PowerShell and run:
Get-Host | Select-Object Version
Create a new project:
Windows Forms App (.NET Framework)
Download/install NuGet package:
Since you're using .NET Framework 4.8 and PowerShell v5.1, download/install NuGet package: Microsoft.PowerShell.5.1.ReferenceAssemblies
See Choosing the right PowerShell NuGet package for your .NET project for more information.
Add the following using directives:
Imports System.Management.Automation
Imports System.Management.Automation.Runspaces
Imports Microsoft.PowerShell
Then use one of the following:
Public Function PSGetModule() As String
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
'create the default initial session state.
Dim sessionState As InitialSessionState = InitialSessionState.CreateDefault()
sessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted
sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psd1"})
'sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism"})
Using ps As PowerShell = PowerShell.Create(sessionState)
Dim results As ObjectModel.Collection(Of PSObject) = ps.AddCommand("Get-Module").Invoke()
'Dim results As ObjectModel.Collection(Of PSObject) = ps.AddScript("Get-Module").Invoke()
For Each result As PSObject In results
sb.AppendLine(result.ToString())
Next
End Using
Return sb.ToString()
End Function
Public Function PSGetModule2() As String
Debug.WriteLine($"PSGetModule2")
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
'create the default initial session state.
Dim sessionState As InitialSessionState = InitialSessionState.CreateDefault()
sessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted
sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psd1"})
'sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism"})
Using rs As Runspace = RunspaceFactory.CreateRunspace(sessionState)
'open
rs.Open()
Using ps As PowerShell = PowerShell.Create()
ps.Runspace = rs
Dim results As ObjectModel.Collection(Of PSObject) = ps.AddCommand("Get-Module").Invoke()
For Each result As PSObject In results
sb.AppendLine(result.ToString())
Next
End Using
End Using
Return sb.ToString()
End Function
Public Async Function PSGetModuleAsync() As Task(Of String)
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
'create the default initial session state.
Dim sessionState As InitialSessionState = InitialSessionState.CreateDefault()
sessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted
sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psd1"})
'sessionState.ImportPSModule({"C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Dism"})
Using ps As PowerShell = PowerShell.Create(sessionState)
ps.AddCommand("Get-Module")
Dim results = Await Task.Factory.FromAsync(ps.BeginInvoke(), Function(asyncResult As IAsyncResult) ps.EndInvoke(asyncResult))
For Each result As PSObject In results
sb.AppendLine(result.ToString())
Next
End Using
Return sb.ToString()
End Function
Usage:
Dim result As String = PSGetModule()
Debug.WriteLine($"result (PSGetModule): {result}")
Usage (Async)
Dim result As String = Await PSGetModuleAsync()
Debug.WriteLine($"result: {result}")
I was able to execute Get-WindowsDriver
, using code from this post. Here's the method that I used for testing (you may wish to change it to a function):
Public Sub GetSystemDrivers(flags As GetDriverFlags)
'create the default initial session state.
Dim sessionState As InitialSessionState = InitialSessionState.CreateDefault()
sessionState.ExecutionPolicy = ExecutionPolicy.Unrestricted
'sessionState.ImportPSModule("Dism")
'create a runspace. using the default host
Using rs As Runspace = RunspaceFactory.CreateRunspace(sessionState)
'open
rs.Open()
Dim hasFlagInbox As Boolean = flags.HasFlag(GetDriverFlags.Inbox)
Dim hasFlagNotInbox As Boolean = flags.HasFlag(GetDriverFlags.NotInbox)
'set value
Runspace.DefaultRunspace = rs
Using ps As PowerShell = PowerShell.Create()
ps.Runspace = rs
Dim dismDriverObjects = ps.AddCommand("Get-WindowsDriver").AddParameter("Online").Invoke()
For Each dismDriverObject As PSObject In dismDriverObjects
'create new instance
Dim driverInfo As New DismDriverInfo(dismDriverObject)
If flags <> GetDriverFlags.Any Then
If (hasFlagInbox AndAlso Not driverInfo.Inbox) OrElse
(hasFlagNotInbox AndAlso driverInfo.Inbox) Then
Continue For
End If
End If
Debug.WriteLine($"Driver: {driverInfo.DriverFile}")
Debug.WriteLine($"Date: {driverInfo.BuildDate}")
Debug.WriteLine($"Version: {driverInfo.Version}")
Next
End Using
End Using
End Sub
Note: Since Get-WindowsDriver
requires administrative privileges, add an Application Manifest File
(Project => Add New Item... => Application Manifest File) to your project. Then change from <requestedExecutionLevel level="asInvoker" uiAccess="false" />
to <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
.
Resources: