1

My goal is to accomplish running a PowerShell command within a vb.net application. I'm trying to run the command calc inside powershell.

These following systems are imported:

Imports System.IO
Imports System.Collections.ObjectModel
Imports System.Management.Automation
Imports System.Management.Automation.Runspaces
Imports System.Text

I created the function RunScript to run any powershell commands:

Public Function RunScript(ByVal script As String) As String
        Dim runspace As Runspace = RunspaceFactory.CreateRunspace()
        runspace.Open()
        Dim pipeline As Pipeline = Runspace.CreatePipeline()
        pipeline.Commands.AddScript(script)
        pipeline.Commands.Add("Out-String")
        Dim results As Collection(Of PSObject) = pipeline.Invoke()
        Runspace.Close()
        Dim stringbuilder As StringBuilder = New StringBuilder()
        For Each ps As PSObject In results
            stringbuilder.AppendLine(ps.ToString())
        Next
        Return stringbuilder.ToString()
End Function

The NuGet Package I am using is this: System.Management.Automation.dll (not to be confused with System.Management.Automation)

The way I use this function to run a PowerShell command (running calc in this instance:)

 txtOutput.Text = RunScript("calc")

(note: txtOutput is a textbox containing the output of the command when it is run inside powershell)

No errors are shown before building the solution but when building the solution, the following errors were logged in the console:

error BC30002: Type 'Runspace' is not defined.
error BC30451: 'RunspaceFactory' is not declared. It may be inaccessible due to its protection level.
error BC30002: Type 'Pipeline' is not defined.
error BC30002: Type 'PSObject' is not defined.
error BC30002: Type 'PSObject' is not defined.

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Wriar
  • 306
  • 1
  • 10
  • Don't use the `System.Management.Automation.dll` package directly - see [this answer](https://stackoverflow.com/a/58211901/45375). – mklement0 May 21 '20 at 01:42

1 Answers1

1

Here's my method for running PowerShell scripts in VB:

Imports System.Management.Automation.Runspaces
    ''' <summary>
    ''' Allows running PowerShell snippets/scripts/commands.
    ''' </summary>
    ''' <param name="scriptText">
    ''' The PowerShell command to send.
    ''' </param>
    ''' <returns>
    ''' The result of the command as a string.
    ''' </returns>
    ''' <remarks>
    ''' Requires: reference to System.Management.Automation.dll, and Imports System.Collections.ObjectModel
    ''' </remarks>
    Public Function RunPSScript(ByVal scriptText As String) As String

        ' Create a Powershell runspace
        Dim pShellRunSpace As Runspace = RunspaceFactory.CreateRunspace()

        ' Open it
        pShellRunSpace.Open()

        ' Create a pipeline and feed it the script text
        Dim pShellPipeline As Pipeline = pShellRunSpace.CreatePipeline()

        pShellPipeline.Commands.AddScript(scriptText)

        ' Add an extra command to transform the script output objects into nicely formatted strings.
        ' Remove this line to get the actual objects that the script returns.
        ' For example: the script "Get-Process" returns a collection of System.Diagnostics.Process instances.
        pShellPipeline.Commands.Add("Out-String")

        ' Execute the script
        Dim pShellResults As Collection(Of PSObject) = pShellPipeline.Invoke()

        ' Close the runspace 
        pShellRunSpace.Close()

        ' Convert the script result into a single string
        Dim sb As New StringBuilder()

        For Each obj As PSObject In pShellResults
            sb.AppendLine(obj.ToString())
        Next

        ' Return the results of the script that has now been converted to text
        Return sb.ToString()

    End Function

And I've found that often-times just waiting on PowerShell to finish doing it's thing (i.e. passing tnc google.com -port 8080) can take a while and hold up the UI, so I'll pass the call to something like a BackgroundWorker to handle.

Also, this thread may help: variable is not declared it may be inaccessible due to its protection level

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94