4

I read a lot about passing vars from C# to powershell script but i am interesten in the other way around.

here I have this code to create a Type in my powershell script:

Add-Type @'

public class Node
{

    public string Type;
    public string VM_Name;
    public string VM_IP;
    public string Hostname;

}
'@

$vm1 = New-Object Node
$vm2 = New-Object Node
$vm3 = New-Object Node
$vm4 = New-Object Node

After this code I have C# code:

$sourceCode = @'


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void InitializeComponent()
    {
    }
}

'@

How I might be able to access $vm1,2,3,4 in the C# code above ?

2 Answers 2

6

You could either pass the variables into the type via a method in your C# class that would accept the variables as parameters e.g.:

$form = new-object Form1
$form.SetVariables($vm1, $vm2, $vm3, $vm4)

I recommend that approach.

Another option (heavier weight and not tested) is to try accessing the current runspace from the C# code e.g.:

var defRunspace = System.Management.Automation.Runspaces.Runspace.DefaultRunspace;
var pipeline = defRunspace.CreateNestedPipeline();
pipeline.Commands.AddScript("$vm1,$vm2,$vm3,$vm4");
var results = pipeline.Invoke();
var vm1 = results[0];
var vm2 = results[1];
...

I haven't tried this from C# code (only from within PowerShell) so I'm not 100% sure it will work.

Sign up to request clarification or add additional context in comments.

Comments

0

A way to pass variables to C# scripts running inside Powershell is to use an HttpListener (monitoring a localhost port) that harvests the Content-Type. The Content-Type field can take up to 16,000 characters, and I used it to prevent colleagues on your machine using a browser to create spurious input.

The listener shown here is in a stand-alone Powershell script:

Add-Type -TypeDefinition @'

using System;
using System.Threading.Tasks;
using System.Net;
using System.Windows.Forms;

namespace LocalHostListener
{
    public class Program
    {
        HttpListener listener = new HttpListener();

            public static void Main(string[] args)
            {
                    Program program = new Program();
                    program.Start(args[0]);
            }

            public void Start(string url_)
            {
                    listener.Prefixes.Add(url_);
                    listener.Start();
                    listener.BeginGetContext(new AsyncCallback(GetContextCallback), null);
                    Console.ReadLine();
                    listener.Stop();
            }

            public void GetContextCallback(IAsyncResult result)
            {
            HttpListenerContext context = listener.EndGetContext(result);
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;

            Task.Factory.StartNew(() => 
            {
                // KICK OFF YOUR UPDATE ACTIONS HERE (THE LENGTH FILTER EXCLUDES BROWSER CALLS)
                if(request.ContentType.Length>0) yourAction(request.ContentType);
            });

                // SEND A RESPONSE TO KEEP POWERSHELL Invoke-WebRequest,
                // BROWSERS AND VBS MSXML2.XMLHTTP.6.0 HAPPY
                // (C# HttpWebRequest DOESN'T CARE)
                    response.ContentLength64 = 1;
            response.OutputStream.WriteByte(Convert.ToByte('!'));

                    listener.BeginGetContext(new AsyncCallback(GetContextCallback), null);
            }

        public void yourAction(string update)
        {
            Console.WriteLine(update); 
            MessageBox.Show(new Form(), update,"Message from localhost feed",
             MessageBoxButtons.OK,MessageBoxIcon.None,
               MessageBoxDefaultButton.Button1,(MessageBoxOptions)0x40000);
        }
    }
}

'@ -Language CSharp -ReferencedAssemblies System.Windows.Forms

$Host.UI.RawUI.WindowTitle='Monitoring "Content-Type" on http://localhost:1959'
[LocalHostListener.Program]::Main('http://localhost:1959/')

You can then update the listener using the Powershell WebRequest:

Invoke-WebRequest -ContentType 'Your message here' -URI http://localhost:1959

Updates can also be sent to the listener using a C# sender that sets the Content-Type with your variables (again, shown here in a stand-alone Powershell script):

Add-Type -TypeDefinition @'

using System;
using System.Net;

namespace LocalHostSender
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try{
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:1959");
                    request.ContentType = args[0];
                    request.Timeout = 200;
                    request.GetResponse();          
            }catch{}
        }
    }
}

'@ -Language CSharp -ReferencedAssemblies System.Net

[LocalHostSender.Program]::Main("Your message here")

The response section of the listener script can be removed if only the C# sender is used.

Another advantage with this method is that VBS scripts can also update the Content-Type:

text_ = "Your message here"

Randomize
Set req = CreateObject("MSXML2.XMLHTTP.6.0")
req.open "GET", "http://localhost:1959/" & rnd, False
req.setRequestHeader "Content-Type", text_
req.send
'req.responseText

The random addition to the page request is required if you want to loop multiple requests, as MSXML2.XMLHTTP.6.0 doesn't send Content-Type information on identical page requests.

If you actually wanted browser/HTML access you could harvest the page requests in the listener using:

string simplePageRequest_ = request.Url;
//Parsing "favicon.ico" and "http://localhost:1959/"

string pageQuery_ = request.QueryString["q"];

updating via the browser page requests, or again using the Powershell WebRequest:

Invoke-WebRequest 'http://localhost:1959/Your message here'
Invoke-WebRequest 'http://localhost:1959/?q=Your message here'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.