【问题标题】:How can you use GetType().GetProperties() on a PowerShell Custom PSObject?如何在 PowerShell 自定义 PSObject 上使用 GetType().GetProperties()?
【发布时间】:2013-09-01 19:35:13
【问题描述】:

我正在尝试让 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,则不起作用。如果我将 $code 替换为 PSCustom 对象,例如

$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 模式布局并制作一个特殊情况,但我宁愿不必仅为一种类型的对象自定义它。 PowerShell 中有没有办法获取一个 psobject 并将其隐藏/转换为我可以与 GetType().GetProperties() 一起使用的东西?

【问题讨论】:

  • 什么版本的powershell,安迪?
  • Windows 8 上的 PowerShell v3

标签: powershell reflection log4net psobject


【解决方案1】:

据我了解,根据结果:

Get-Member -InputObject $obj -Force

获取psObject属性的方法有:

$obj.psobject.properties
$obj.psobject.get_properties()

你不能编写动态创建类的 C# 代码吗?

【讨论】:

    【解决方案2】:

    我最终在 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}
    
    }
    

    似乎可以解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      相关资源
      最近更新 更多