Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell. Create a class file to hold Custom Objects?

I use Powershell's custom-object command to hold data points. Custom-object creates just one object and assigns a variable to it. Can Powershell go one step further and create new classes from which objects can be made?

In the examples below, I store three pieces of data: a server name, a timestamp, and the minutes since an event occurred on the server.

When I was learning Powershell, I put all this into a two-dimensional array:

$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 doesn't play well with arrays, so I started using a custom object:

$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

That's exports correctly, and dealing with object properties is easier than dealing with columns in a two-dimensional array.

But if I want to create several custom objects that aren't in an array, I have to write the custom-object code over and over again.

$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

What if Powershell could design custom classes in addition to custom objects? Like OO programming languages do? Something like:

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

Is that possible in Powershell?

like image 910
Bagheera Avatar asked Sep 09 '13 19:09

Bagheera


People also ask

Can you create class in PowerShell?

If you are going to create a class in Windows PowerShell, you must design it. Nothing is worse than to start writing a module, create a bunch of classes, and then all of a sudden, realize that you need to add (or worse yet, change) one or more properties.

What is PSCustomObject in PowerShell?

Long description. The [pscustomobject] type accelerator was added in PowerShell 4.0. Prior to adding this type accelerator, creating an object with member properties and values was more complicated. Originally, you had to use New-Object to create the object and Add-Member to add properties.

How do you add an object in PowerShell?

Use += to Add Objects to an Array of Objects in PowerShell Every time you use it, it duplicates and creates a new array. You can use the += to add objects to an array of objects in PowerShell.


2 Answers

You can define classes in 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;
like image 68
alroc Avatar answered Oct 26 '22 22:10

alroc


You could use a function as a faux constructor for your custom objects. You wouldn't ever have to duplicate your code, and you could use flags to set your properties right from the function call. Here's an example:

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
}

And some sample output:

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

You can do a whole ton of stuff with functions that is out of the scope of this question. Instead, check out about_functions_advanced.

like image 42
Anthony Neace Avatar answered Oct 26 '22 23:10

Anthony Neace