Reputation:
I'm basically trying to create a console application which executes a given script on a remote machines within a given IP range and stores the results.
This is my code so far but something is going wrong when I try to create a runspace with the WSManConnectionInfo object as arg.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Security;
namespace GetSysInfo
{
class Program
{
private static string outPath;
static void Main(string[] args)
{
//get script path
Console.WriteLine("Enter full path to script.");
string path = Convert.ToString(Console.ReadLine());
//get IP range
Console.WriteLine("Input start IPv4.");
IPAddress sIP = IPAddress.Parse(Console.ReadLine().ToString());
Console.WriteLine("Input end IPv4.");
IPAddress eIP = IPAddress.Parse(Console.ReadLine().ToString());
//get list of IPs in range
RangeFinder rf = new RangeFinder();
List<string> IPrange = rf.GetIPRangeList(sIP, eIP);
//run script
foreach (var IP in IPrange)
{
try
{
RunScriptRemote(LoadScript(path), IP);
}
catch (Exception e)
{
Console.WriteLine("An error occured" + Environment.NewLine + e.Message);
}
}
}
//script executer
private static void RunScriptRemote(string script, string address)
{
Console.WriteLine("Enter username.");
String username = Console.ReadLine();
Console.WriteLine("Enter password.");
ConsoleKeyInfo key;
SecureString pass = new SecureString();
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
{
pass.AppendChar(key.KeyChar);
Console.Write("*");
}
else
{
if (key.Key == ConsoleKey.Backspace && pass.Length > 0)
{
pass.RemoveAt(pass.Length);
Console.Write("\b \b");
}
else if (key.Key == ConsoleKey.Enter && pass.Length > 0)
{
Console.Write(Environment.NewLine);
pass.MakeReadOnly();
}
}
}
while (key.Key != ConsoleKey.Enter);
PSCredential credential = new PSCredential(username, pass);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(new Uri("http://" + address + ":5985/wsman"), "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", credential);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Negotiate;
connectionInfo.EnableNetworkAccess = true;
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);//point of crash
runspace.Open();
//set path to save results
Console.WriteLine("Enter full path to save results. Must be a directory.\nThis can be a local path or a network path.");
Console.WriteLine("In case of a network path the results will be merged automatically");
outPath = Convert.ToString(Console.ReadLine());
runspace.SessionStateProxy.SetVariable("filepath", outPath);
using (PowerShell ps = PowerShell.Create())
{
ps.Runspace = runspace;
ps.AddScript(script);
ps.Invoke();
}
//Pipeline pipeline = runspace.CreatePipeline();
//pipeline.Commands.AddScript(script);
//pipeline.Invoke();
runspace.Close();
}
//script loader
private static string LoadScript(string filename)
{
try
{
using (StreamReader sr = new StreamReader(filename))
{
StringBuilder fileContents = new StringBuilder();
string curLine;
while ((curLine = sr.ReadLine()) != null)
{
fileContents.Append(curLine + Environment.NewLine);
}
return fileContents.ToString();
}
}
catch (Exception e)
{
return e.Message;
}
}
}
public class RangeFinder
{
public IEnumerable<string> GetIPRange(IPAddress startIP,
IPAddress endIP)
{
uint sIP = ipToUint(startIP.GetAddressBytes());
uint eIP = ipToUint(endIP.GetAddressBytes());
while (sIP <= eIP)
{
yield return new IPAddress(reverseBytesArray(sIP)).ToString();
sIP++;
}
}
public List<string> GetIPRangeList(IPAddress startIP,
IPAddress endIP)
{
uint sIP = ipToUint(startIP.GetAddressBytes());
uint eIP = ipToUint(endIP.GetAddressBytes());
List<string> IPlist = new List<string>();
while (sIP <= eIP)
{
IPlist.Add(new IPAddress(reverseBytesArray(sIP)).ToString());
sIP++;
}
return IPlist;
}
//reverse byte order in array
protected uint reverseBytesArray(uint ip)
{
byte[] bytes = BitConverter.GetBytes(ip);
bytes = bytes.Reverse().ToArray();
return (uint)BitConverter.ToInt32(bytes, 0);
}
//Convert bytes array to 32 bit long value
protected uint ipToUint(byte[] ipBytes)
{
ByteConverter bConvert = new ByteConverter();
uint ipUint = 0;
int shift = 24;
foreach (byte b in ipBytes)
{
if (ipUint == 0)
{
ipUint = (uint)bConvert.ConvertTo(b, typeof(uint)) << shift;
shift -= 8;
continue;
}
if (shift >= 8)
ipUint += (uint)bConvert.ConvertTo(b, typeof(uint)) << shift;
else
ipUint += (uint)bConvert.ConvertTo(b, typeof(uint));
shift -= 8;
}
return ipUint;
}
}
}
I get the following error when trying to run: Common Language Runtime detected an invalid program.
I tried creating a new solution as Google suggested but it's obviously going wrong when creating the runspace.
I'm out of idea's and sources for help, so I'm reaching out to the Stackoverflow community.
Thanks in advance, X3ntr
EDIT: I tried cleaning my solution, manually deleting any pbd's, changed the target CPU, turned off code optimalization, allowed unsafe code, rebuilding, creating a new solution,... as suggested in this post.
Upvotes: 2
Views: 900
Reputation:
I followed the advice from this answer: I added a reference to C:\windows\assembly\GAC_MSIL\System.Management.Automation and then ran this command in an elevated powershell: Copy ([PSObject].Assembly.Location) C:\
Upvotes: 1