Reputation: 43
I am trying to explore and find an approach that will provide me with an outputs that looks into the network statistics per each connection. I know that powershell provides the overall statistics of the network like
(using WSMan)
pipeline.AddCommand("Get-NetTCPConnection");
pipeline.AddCommand("Select-Object").AddArgument("LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess");
pipeline.AddCommand("Get-NetAdapterStatistics");
pipeline.AddCommand("Select-Object").AddArgument("InterfaceAlias, OutgoingBytes, IncomingBytes");
LocalAddress LocalPort RemoteAddress RemotePort State OwningProcess
-----------------------------------------------------------------------------------------------------
192.168.1.10 49242 93.184.216.34 80 ESTABLISHED 1234
192.168.1.10 49243 93.184.216.34 443 ESTABLISHED 1235
InterfaceAlias OutgoingBytes IncomingBytes
-------------------------------------------------
Ethernet 1000000 2000000
Wi-Fi 500000 1500000
Is there a class that I can use that will provide this information?
What I am expecting the output would be similar to the one below
--------------------------------------------------------
Local Address: 192.168.1.10
Local Port: 443
Remote Address: 203.0.113.5
Remote Port: 12345
State: Established
Bytes Sent: 1048576
Bytes Received: 2048000
Packets Sent: 512
Packets Received: 768
Owning Process ID: 1234
--------------------------------------------------------
My approach on Getting the IPv4Address and other parameters:
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
class Program
{
static void Main()
{
string remoteMachine = "RemoteMachine";
string username = "user";
string password = "password";
// WSMan connection info
PSCredential credentials = new PSCredential(username, new System.Security.SecureString());
foreach (char c in password) credentials.Password.AppendChar(c);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
new Uri($"http://{remoteMachine}:5985/wsman"),
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell",
credentials
);
// Create a runspace
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
// Create the pipeline
using (PowerShell pipeline = PowerShell.Create())
{
// Execute remotely
pipeline.Runspace = runspace;
// Add the Get-NetIPConfiguration command to the pipeline
pipeline.AddCommand("Get-NetIPConfiguration");
pipeline.AddCommand("Select-Object").AddParameter("Property", new string[] { "InterfaceAlias", "IPv4Address", "InterfaceIndex", "InterfaceDescription", "NetProfile", "IPv4DefaultGateway", "DNSServer" });
try
{
// Results
Collection<PSObject> results = pipeline.Invoke();
if (results.Count > 0)
{
foreach (PSObject result in results)
{
Console.WriteLine("InterfaceAlias : " + result.Members["InterfaceAlias"]?.Value);
Console.WriteLine("InterfaceIndex : " + result.Members["InterfaceIndex"]?.Value);
Console.WriteLine("InterfaceDescription: " + result.Members["InterfaceDescription"]?.Value);
Console.WriteLine("NetProfile Name : " + result.Members["NetProfile"]?.Value);
Console.WriteLine("IPv4Address : " + result.Members["IPv4Address"]?.Value);
Console.WriteLine("IPv4 DefaultGateway: " + result.Members["IPv4DefaultGateway"]?.Value);
Console.WriteLine("DNSServer : " + result.Members["DNSServer"]?.Value);
Console.WriteLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error executing the pipeline: " + ex.Message);
}
}
// Close the runspace
runspace.Close();
}
}
my outcome are the following:
InterfaceAlias : Ethernet1
InterfaceIndex :
InterfaceDescription:
NetProfile Name :
IPv4Address : MSFT_NetIPAddress (Name = ";P?9;!K5???9F66F66;99;", CreationClassName = "", SystemCreationClassName = "", SystemName = "")
IPv4 DefaultGateway:
DNSServer :
I tried to follow like this structure:
Upvotes: 1
Views: 59
Reputation: 43
Thanks to Charlieface, I was able to create the following:
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
class Program
{
static void Main()
{
string remoteMachine = "RemoteMachine";
string username = "user";
string password = "password";
// WSMan connection info
PSCredential credentials = new PSCredential(username, new System.Security.SecureString());
foreach (char c in password) credentials.Password.AppendChar(c);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
new Uri($"http://{remoteMachine}:5985/wsman"),
"http://schemas.microsoft.com/powershell/Microsoft.PowerShell",
credentials
);
// Create a runspace with the WSMan connection
Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
// Create the pipeline to execute the PowerShell command
using (PowerShell pipeline = PowerShell.Create())
{
// Command to execute remotely
pipeline.Runspace = runspace;
// Add the Get-NetIPConfiguration command to the pipeline
pipeline.AddCommand("Get-NetIPConfiguration");
pipeline.AddCommand("Select-Object").AddParameter("Property", new string[] { "InterfaceAlias", "IPv4Address", "InterfaceIndex", "InterfaceDescription", "NetProfile", "IPv4DefaultGateway", "DNSServer" });
try
{
Collection<PSObject> results = pipeline.Invoke();
// Process results
foreach (PSObject result in results)
{
string interfaceAlias = result.Members["InterfaceAlias"]?.Value.ToString();
string ipv4Address = string.Empty;
string ipv4PrefixLength = string.Empty;
string ipv4Gateway = string.Empty;
string dnsServers = string.Empty;
var ipv4AddressObject = result.Members["IPv4Address"]?.Value as PSObject;
if (ipv4AddressObject != null)
{
var baseObject = ipv4AddressObject.BaseObject as dynamic;
ipv4Address = baseObject[0]?.IPAddress;
ipv4PrefixLength = baseObject[0]?.PrefixLength.ToString();
}
// Accessing Default Gateway
var ipv4GatewayObject = result.Members["IPv4DefaultGateway"]?.Value as PSObject;
if (ipv4GatewayObject != null)
{
var baseGatewayObject = ipv4GatewayObject.BaseObject as dynamic;
ipv4Gateway = baseGatewayObject[0]?.NextHop;
}
// Accessing DNS Servers
StringBuilder DNSServers = new StringBuilder();
var dnsServersObject = result.Members["DNSServer"]?.Value as PSObject;
if (dnsServersObject != null)
{
var baseDNSServersObject = dnsServersObject.BaseObject as dynamic;
if(baseDNSServersObject.Count > 1)
{
foreach(var DnsServerObject in baseDNSServersObject)
{
var baseDNSServers = DnsServerObject?.ServerAddresses;
if (baseDNSServers is object[] DnsServers)
{
int? cnt = 1;
foreach (var DnsServer in DnsServers)
{
string? DNS = null;
if (cnt < DnsServers.Length)
{
DNS = DnsServer.ToString();
DNS = DNS + ";";
}
else
{
DNS = DnsServer.ToString();
}
DNSServers.Append(DNS);
cnt++;
}
}
}
}
else
{
var baseDNSServers = baseDNSServersObject[0]?.ServerAddresses;
if (baseDNSServers is object[] DnsServers)
{
foreach (var DnsServer in DnsServers)
{
string? DNS = DnsServer.ToString();
DNSServers.Append(DNS);
}
}
}
}
// Convert CIDR to Subnet Mask
string subnetMask = CidrToMask(Convert.ToInt32(ipv4PrefixLength));
// Output results
Console.WriteLine($"InterfaceAlias : {interfaceAlias}");
Console.WriteLine($"IPv4 Address : {ipv4Address}");
Console.WriteLine($"Subnet Mask : {subnetMask}");
Console.WriteLine($"Default Gateway : {ipv4Gateway}");
Console.WriteLine($"DNSServer : {DNSServers.ToString()}");
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine("Error executing the pipeline: " + ex);
}
}
// Clean up and close the runspace
runspace.Close();
}
public static string CidrToMask(int cidr)
{
var mask = (cidr == 0) ? 0 : uint.MaxValue << (32 - cidr);
var bytes = BitConverter.GetBytes(mask).Reverse().ToArray();
return new IPAddress(bytes).ToString();
}
Upvotes: 0
Reputation: 72194
Rather than using Select-Object
, you can cast it to dynamic
and access the properties late-bound.
// Add only the Get-NetIPConfiguration command to the pipeline
pipeline.AddCommand("Get-NetIPConfiguration");
try
{
// Results
var results = pipeline.Invoke<dynamic>();
foreach (var result in results)
{
Console.WriteLine($"InterfaceAlias : {result.InterfaceAlias}");
Console.WriteLine($"InterfaceIndex : {result.InterfaceIndex}");
Console.WriteLine($"InterfaceDescription: {result.InterfaceDescription}");
Console.WriteLine($"NetProfile Name : {result.NetProfile}");
Console.WriteLine($"IPv4Address : {result.IPv4Address}");
Console.WriteLine($"IPv4 DefaultGateway: {result.IPv4DefaultGateway}");
Console.WriteLine($"DNSServer : {result.DNSServer}");
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine("Error executing the pipeline: " + ex.Message);
}
Or you can import the NetTCP library and statically cast to the correct type.
Upvotes: 1