我想让this log4net customization使用PowerShell PSObjects。基本上,此模式布局将遍历对象并将其属性转储到CSV列中。以下是执行反射的代码:
PropertyInfo[] properties = loggingEvent.MessageObject.GetType().GetProperties();
foreach (PropertyInfo prop in properties)
{
object value = prop.GetValue(loggingEvent.MessageObject, null);
loggingEvent.Properties[prop.Name] = value;
}
在C#中使用普通类时,这可以正常工作。如果我在PowerShell中使用内联C#创建一个类,它也可以工作。
$code = @”
using System;
namespace CsvTest {
public class MyEvent
{
public string UserId { get; set; }
public string Details { get; set; }
public int EventCode { get; set; }
}
}
“@
Add-Type $code
$test = New-Object CsvTest.MyEvent
$test.UserId = "Andy"
$test.Details ="SomeStuff"
$test.EventCode = 10
$MyCommonLogger.Error($test)
$MyCommonLogger.Info($test)
$MyCommonLogger.Warn($test)
如果我创建自定义PSObject,那么什么是行不通的。如果我用PSCustom对象替换$ code,例如
$obj = New-Object psobject -Property @{
"UserId" = "Andy";
"EventCode" = 100;
"Details" = "DetailInfoGoeshere"
}
然后它将返回Null。我已经确认这确实会返回null。
$obj = New-Object psobject -Property @{
"UserId" = "Andy";
"EventCode" = 100;
"Details" = "DetailInfoGoeshere"
}
$obj.GetType().GetProperties()
我认为如果入站对象是PSObject,我可以破解CSVLogging Pattern布局并创建一个特例,但我不想仅为一种类型的对象自定义它。在PowerShell中是否有一种方法可以使用psobject并将其转换/转换为可以与GetType()一起使用的东西.GetProperties()?
答案 0 :(得分:5)
据我了解,根据以下结果:
Get-Member -InputObject $obj -Force
获取psObject属性的方法是:
$obj.psobject.properties
$obj.psobject.get_properties()
你不能编写动态创建类的C#代码吗?
答案 1 :(得分:0)
我最终在PowerShell中编写代码来生成我需要的类。我添加了“Test-IsAssemblyLoaded”函数,以便它不会尝试在相同的PS运行中加载相同的程序集两次。有点脏,但有效。
Function Test-IsAssemblyLoaded {
param ($assembly)
$result = $false
try {
$expression = "[$assembly]| out-null"
invoke-expression $expression;
$result = $true
}
catch {$result = $false}
return $result
}
Function Add-DotNetClass {
param(
[Parameter()]
$NameSpace = "PowerShell",
[Parameter()]
$Properties,
[Parameter()]
$ClassName
)
$code = @"
using System;
namespace $Namespace
{
public class $className
{
$(foreach ($p in $Properties)
{
"public $p {get;set;} `n"
} )
}
}
"@
if (Test-IsAssemblyLoaded "$Namespace.$ClassName") {Write-Warning "Assembly already loaded"}
else {Add-Type $code}
}
似乎可以解决问题。