Подтвердить что ты не робот

Powershell. Создать файл класса для хранения пользовательских объектов?

Я использую команду пользовательских объектов 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?

4b9b3361

Ответ 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;

Ответ 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.

Ответ 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 (Обязательный = $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()

Результаты:

Hello!

Привет, мир!