1

If I run the below command inside of Powershell, it works as expected

invoke-command -computername [name] -scriptblock { ipconfig.exe > c:\ipconfig.txt }

But when I try to incorporate this into a c# function, I'm getting this error

{"Cannot bind parameter 'ScriptBlock'. Cannot convert the \"ipconfig.exe > c:\ipconfig.txt\" value of type \"System.String\" to type \"System.Management.Automation.ScriptBlock\"."}

even though I'm converting the scriptblock parameter value to a System.Management.Automation.ScriptBlock object? What am I doing incorrect?

    private void btnInstallTest_Click(object sender, EventArgs e)
    {
        List<string> commands = new List<string>();

        commands.Add("invoke-command");
        List<Tuple<String, String>> parameters = new List<Tuple<string, string>>();
        parameters.Add(new Tuple<string, string>("computername", @"server"));
        parameters.Add(new Tuple<string, string>("ScriptBlock", @"ipconfig.exe > c:\ipconfig.txt"));

        Collection<PSObject> psobject = runRemotePowerShellCommands(commands, parameters, "server", @"domain\user", convertToSecureString("password"));          
    }

    private Collection<PSObject> runRemotePowerShellCommands(List<string> commands, List<Tuple<String, String>> parameters, string remoteMachineName, string domainAndUsername, SecureString securePW)
    {
        Collection<PSObject> psobjs = new Collection<PSObject>();
        string result = "";
        string shellUri = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
        PSCredential psCredential = new PSCredential(domainAndUsername, securePW);
        WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, remoteMachineName, 5985, "/wsman", shellUri, psCredential);
        connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos; //.Basic;

        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            PowerShell powershell = PowerShell.Create();
            for (int i = 0; i < commands.Count; i++)
            {
                if (commands[i].Contains(";"))
                {

                    string[] commandsSplit = commands[i].Split(';');
                }
                else
                {
                    powershell.AddCommand(commands[i]);
                }

                System.Management.Automation.ScriptBlock sb = null;
                if (parameters != null)
                {
                    foreach (Tuple<string, string> param in parameters)
                    {
                        if (param.Item1.ToLower() == "scriptblock")
                        {
                            sb = ScriptBlock.Create(param.Item2);                                
                            powershell.AddParameter(param.Item1, sb);
                            //powershell.AddParameter(param.Item1, param.Item2);
                        }
                        else
                        {
                            powershell.AddParameter(param.Item1, param.Item2);
                        }
                    }
                }

                if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)
                {
                    // do nothing, the runspace is already open
                }
                else
                {
                    runspace.Open();                        
                    powershell.Runspace = runspace;
                }

                try
                {
                    psobjs = powershell.Invoke();

                    if (powershell.HadErrors == true)
                    {
                        result = "Failed - " + powershell.Streams.Error[0].ToString();
                        result = result.Replace("\"", "*");
                        psobjs.Add(result);
                    }
                }
                catch (Exception ex)
                {
                    result = "Failed: " + ex.Message;
                    psobjs.Add(result);
                }
            }

            powershell.Commands.Clear();                
        }

        return psobjs;
    }
1
  • Well alternatively for getting network configuration information you could use WMI queries. Commented Aug 22, 2018 at 17:53

1 Answer 1

7

I feel like you've super over-complicated this:

using (PowerShell ps = PowerShell.Create())
{
    ps.AddScript($@"Invoke-Command -ComputerName {name} -ScriptBlock {{ipconfig > C:\ipconfig.txt}}")
    ps.Invoke()
}

Alternatively you can chain .AddCommand().AddParameter()

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

2 Comments

This worked flawlessly, thank you. With my definitely overcomplicated function for this issue, I've used it before and it worked without issue. I'm not sure why I got that error?
Tuple<string, string> your string compare with scriptblock is failing so it was being passed as a string instead of creating the correct type. @Jay

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.