大家好,我是 C# 和 .NET 编程新手。 我正在尝试使用 powershell 脚本并制作一个执行类似功能的代理。代理正确编译和安装,并将 powershell 命令的输出记录到日志文件中。 问题是我没有访问这些值,而是日志打印出对象? 我如何访问这些值?提前致谢,并对我的初步尝试保持温和。
我对我一直在使用的文档的参考: https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.powershell?view=powershellsdk-7.4.0
日志文件输出: 执行时间:10/2/2024 3:49:45 PM 启动带宽陷阱...System.Collections.ObjectModel.Collection`1[System.Management.Automation.PSObject]
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Management.Automation;
namespace SBC_Agent
{
public partial class Service1 : ServiceBase
{
Timer timer = new Timer(); // name space(using System.Timers;)
private Timer _audittimer;
private string auditFilePath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\Audit";
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WriteToFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Interval = 5000; //number in milliseconds
timer.Enabled = true;
_audittimer = new Timer();
_audittimer.Interval = 60000;
_audittimer.Elapsed += new ElapsedEventHandler(OnElapsedAuditTime);
_audittimer.Enabled = true;
Directory.CreateDirectory(Path.GetDirectoryName(auditFilePath));
}
private void OnElapsedAuditTime(object source, ElapsedEventArgs e)
{
RunPowerShellCommands();
}
private void BandwidthTrap()
{
try
{
using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())
{
//psInstance.AddScript("Get-WmiObject -Class win32_ip4routetable | where {$_.destination -eq \"0.0.0.0\"} | select -ExpandProperty InterfaceIndex | select -First 1");
psInstance.AddScript("Get-WmiObject -Class win32_ip4routetable");
var int_index = psInstance.Invoke();
//var ifIndex = "InterfaceIndex=" + int_index;
using (StreamWriter writer = new StreamWriter(auditFilePath, true))
{
writer.WriteLine("Execution Time: " + DateTime.Now.ToString() + " Launched Bandwidth Trap..." + int_ndex);
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry("Powershell Service Error: " + ex.Message, EventLogEntryType.Error);
using (StreamWriter writer = new StreamWriter(auditFilePath, true))
{
writer.WriteLine("Error: " + ex.Message);
writer.WriteLine("StackTrace: " + ex.StackTrace);
}
}
}
private void RunPowerShellCommands()
{
try
{
BandwidthTrap();
/*
using (System.Management.Automation.PowerShell psInstance = System.Management.Automation.PowerShell.Create())
{
psInstance.AddScript("Get-Process");
var results = psInstance.Invoke();
using (StreamWriter writer = new StreamWriter(auditFilePath, true))
{
writer.WriteLine("Execution Time: " + DateTime.Now.ToString());
foreach (var result in results)
{
writer.WriteLine(result.ToString());
}
writer.WriteLine();
}
}
*/
}
catch (Exception ex)
{
EventLog.WriteEntry("Powershell Service Error: " + ex.Message, EventLogEntryType.Error);
using (StreamWriter writer = new StreamWriter(auditFilePath, true))
{
writer.WriteLine("Error: " + ex.Message);
writer.WriteLine("StackTrace: " + ex.StackTrace);
}
}
}
protected override void OnStop()
{
WriteToFile("Service is stopped at " + DateTime.Now);
}
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
WriteToFile("Service is recall at " + DateTime.Now);
}
public void WriteToFile(string Message)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
//Create a file to write to
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
原剧本:
$HOSTNAME=hostname
$RXKEY="bandwidth_rx_trap"
$TXKEY="bandwidth_tx_trap"
$ifIndex = Get-WmiObject -Class win32_ip4routetable | where {$_.destination -eq "0.0.0.0"} | select -ExpandProperty InterfaceIndex | select -First 1
$ifIndex = "InterfaceIndex=" + $ifIndex
$nic_name = Get-WmiObject -Class win32_networkadapterconfiguration -Filter $ifIndex | select -ExpandProperty Description
$nic = [System.Net.NetworkInformation.Networkinterface]::GetAllNetworkInterfaces() | where {($_.description -eq $nic_name) -and ($_.operationalstatus -eq "up")}
for ($i=1; $i -le 5; $i++){
$bytesSent = 0
$bytesReceived = 0
$stats = $nic.GetIPv4Statistics()
$bytesSent = $stats.BytesSent
$bytesReceived = $stats.BytesReceived
$bytesSentSum = $bytesSentSum + $bytesSent
$bytesReceivedSum = $bytesReceivedSum + $bytesReceived
Start-Sleep 1
}
$TXAVG=[math]::round($bytesSentSum/5/1024,0)
$RXAVG=[math]::round($bytesReceivedSum/5/1024,0)
如果您想从
InterfaceIndex
中提取第一个 win32_ip4routetable
,您应该使用 Invoke<T>()
重载,然后该方法会输出 Collection<T>
,以便您可以 FirstOrDefault()
它。总结一下:
using (PowerShell psInstance = PowerShell.Create())
{
int int_index = psInstance
.AddScript(@"
Get-CimInstance -Class win32_ip4routetable |
Where-Object { $_.Destination -eq '0.0.0.0' } |
Select-Object -ExpandProperty InterfaceIndex -First 1")
.Invoke<int>()
.FirstOrDefault();
using (StreamWriter writer = new StreamWriter(auditFilePath, true))
{
writer.WriteLine(
$"Execution Time: {DateTime.Now} Launched Bandwidth Trap...{int_index}");
}
}