【问题标题】:Powershell. Create a class file to hold Custom Objects?电源外壳。创建一个类文件来保存自定义对象?
【发布时间】:2020-06-14 19:14:00
【问题描述】:

我使用 Powershell 的自定义对象命令来保存数据点。自定义对象只创建一个对象并为其分配一个变量。 Powershell 能否更进一步,创建新的类来制作对象?

在下面的示例中,我存储了三段数据:服务器名称、时间戳和服务器上发生事件后的分钟数。

我在学习Powershell的时候,把这些都放到了一个二维数组中:

$record = @("Server","Timestamp","Minutes")
for ($j = 0; $j -lt 10; $j++){
    $record += @("Server1","$(get-date)",$j)
    sleep 60
    }
$record | export-csv -path c:\record.csv -no type information

export-csv 不能很好地处理数组,所以我开始使用自定义对象:

$record = @()
for ($j = 0; $j -lt 10; $j++){
    $r = New-Object -TypeName PSObject
    $r | Add-Member -MemberType NoteProperty -Name Server -Value ""
    $r | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
    $r | Add-Member -MemberType NoteProperty -Name Minutes -Value ""
    $r.server = "Server1"
    $r.timestamp = "$(get-date)"
    $r.minutes = "$j"
    $record += $r
    sleep 60
    }
$record | export-csv -path c:\record.csv -no type information

这是正确的导出,处理对象属性比处理二维数组中的列更容易。

但如果我想创建几个不在数组中的自定义对象,我必须一遍又一遍地编写自定义对象代码。

$server1 = New-Object -TypeName PSObject
$server1 | Add-Member -MemberType NoteProperty -Name Server -Value ""
$server1 | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
$server2 = New-Object -TypeName PSObject
$server2 | Add-Member -MemberType NoteProperty -Name Server -Value ""
$server2 | Add-Member -MemberType NoteProperty -Name Timesteamp -Value ""
#ad nauseum

如果 Powershell 除了自定义 对象 之外还可以设计自定义 会怎样?像OO编程语言一样吗?比如:

class record {
    -MemberType NoteProperty -Name Server -Value ""
    -MemberType NoteProperty -Name Timestamp -Value ""
    -MemberType NoteProperty -Name Minutes -Value ""
    }
$server1 = new-object -TypeName record
$server2 = new-object -TypeName record
$server3 = new-object -TypeName record

这在 Powershell 中可行吗?

【问题讨论】:

  • 未来的读者:请注意,从 Powershell 5.0 开始,自定义类是使用 Class 关键字的内置功能,它支持属性、方法、多个构造函数等,所有这些都使用典型的 powershell 语法。无需学习 c# 或使用下面描述的各种非常聪明的解决方法和工具。
  • 这里是 about_Classes 页面:docs.microsoft.com/en-us/powershell/module/…

标签: powershell powershell-2.0


【解决方案1】:

您可以在 PowerShell 中定义类。

Add-Type -Language CSharp @"
public class Record{
    public System.DateTime TimeStamp;
    public string Server;
    public int Minutes;
}
"@;
$MyRecord = new-object Record;
$MyRecord.Server = "myserver";
$MyRecord.Timestamp = Get-Date;
$MyRecord.Minutes = 15;

【讨论】:

  • 谢谢。我从来没有听说过“Add-Type”命令...从快速阅读中,我输入“Add-Type -Langauge CSharp @”“@...并且双引号之间的所有内容都编译为 C#?在,我可以在引号之间粘贴一个完整的 C# 程序,它会作为我的 Powershell 脚本的一部分运行?
  • 您可以在 PowerShell 中嵌入 C#。见blogs.technet.com/b/stefan_gossner/archive/2010/05/07/…
  • 如何在CSharp中添加函数/方法
【解决方案2】:

可以使用函数作为自定义对象的虚假构造函数。您永远不必复制您的代码,并且您可以使用标志从函数调用中直接设置您的属性。这是一个例子:

Function New-Constructor
{
    param
    (
        [string]$Name,
        [DateTime]$TimeStamp = (Get-Date)
    )

    $server = New-Object -TypeName PSObject
    $server | Add-Member -MemberType NoteProperty -Name Server -Value $Name
    $server | Add-Member -MemberType NoteProperty -Name TimeStamp -Value $TimeStamp

    # Calling "server" below outputs it, acting as a "return" value
    $server
}

还有一些示例输出:

PS C:\> New-Constructor -Name "MyServer"

Server                                                      TimeStamp
------                                                      ---------
MyServer                                                    9/9/2013 3:27:47 PM


PS C:\> $myServer = New-Constructor -Name "MyServer"
PS C:\> $myServer

Server                                                      TimeStamp
------                                                      ---------
MyServer                                                    9/9/2013 3:27:57 PM


PS C:\> $newServer = New-Constructor -Name "NS" -TimeStamp (Get-Date).AddDays(-1)
PS C:\> $newServer

Server                                                      TimeStamp
------                                                      ---------
NS                                                          9/8/2013 3:33:00 PM

您可以使用超出此问题范围的功能做很多事情。相反,请查看about_functions_advanced

【讨论】:

  • 谢谢。使用函数是有意义的。 alroc 的 Add-Type 答案可能更简洁,但如果我不懂 C#,这会起作用。
  • 在任何一种情况下,我都假设我可以将这些自定义类(无论是 PS 函数还是 C# 类)分组到一个模块中,我的团队可以将其导入到他们编写的任何脚本中,对吗?
  • @MichaelCornn 是的,你明白了。
  • 如果我想在 Powershell 中模拟类的方法怎么办?我该怎么做?
  • @AnthonyNeace 做到了。请看帖子:stackoverflow.com/questions/35943179/…
【解决方案3】:

另一种选择。

属性

您可以将属性消息的“$null”值替换为具有初始值。 Prop 对象是键(属性)和值(初始值)的哈希表。

$messageClass = New-Object -TypeName PSObject -Prop @{ message = $null; }

方法

$messageClass | Add-Member -MemberType ScriptMethod -Name "ShowMessage" -Value {

    Try
    {
        Write-Host $this.message    
    }
    Catch
    {
        Throw $_.Exception
    }
}

构造函数

下面的代码描述了一个构造函数。多态性是使用[Parameter(Mandatory=$false)]来断言或不提供指定参数来实现的。

function MessageClass {
    param([Parameter(Mandatory=$true)]
          [String]$mandatoryMessage,
          [Parameter(Mandatory=$false)]
          [String]$optionalMessage)

    $messageObj = $messageClass.psobject.copy()

    if ($optionalMessage)
    {
        $messageObj.message = "$mandatoryMessage $optionalMessage!"
    }
    else
    {
        $messageObj.message = "$mandatoryMessage!"
    }

    $messageObj
}

然后可以像这样调用构造函数:

$var1 = 'Hello'
$var2 = 'World'
$example1 = MessageClass -mandatoryMessage $var1
$example2 = MessageClass -mandatoryMessage $var1 -optionalMessage $var2

显示文本:

$example1.ShowMessage()
$example2.ShowMessage()

结果是:

你好!

世界你好!

【讨论】:

    【解决方案4】:

    为了获得最佳性能,我会这样做:

    Add-Type -TypeDefinition '
    public class recordEntry {
        public string server;
        public System.DateTime timestamp;
        public int minutes;
    
        public recordEntry(string _server, System.DateTime _timestamp, int _minutes) {
            server = _server;
            timestamp = _timestamp;
            minutes = _minutes;
        }
    }'
    
    $record = [System.Collections.ArrayList]@()
    $record = foreach ($j in 0..10){
        [recordEntry]::new("Server1", [datetime]::Now, $j)
    }
    $record | export-csv -path c:\record.csv -NoTypeInformation
    

    【讨论】:

      猜你喜欢
      • 2020-07-27
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 2017-08-23
      • 2011-12-31
      相关资源
      最近更新 更多