Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell v5 class method - problems

Playing with the new class function in PowerShell v5, and I'm trying to get my head around if we can put methods into classes.

I've tried the below and played about with it for a bit, but haven't been having luck.

class Server {

    [string]$computerName = "192.168.0.200"
    [bool]$ping = (Test-Connection -ComputerName $computerName).count

}

$1 = [server]::new()
$1.computerName = "blah"

I've tried with manually entering a computer name via setting the property, but then I assumed you'd need it at object creation

$1 = [server]::new($computerName = "192.168.0.200")

Exceptions I'm getting are

[ERROR] Exception calling ".ctor" with "0" argument(s): "Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the 
[ERROR] command again."
[ERROR] At D:\Google Drive\Projects\VSPowerShell\DiscoveryFramework\DiscoveryFramework\DiscoveryFramework\class.ps1:12 char:1
[ERROR] + $1 = [server]::new()
[ERROR] + ~~~~~~~~~~~~~~~~~~~~
[ERROR]     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
[ERROR]     + FullyQualifiedErrorId : ParameterBindingValidationException
[ERROR]  
[DBG]: PS C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE> 
[DBG]: PS C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE> $1
Server
[DBG]: PS C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE> $1.gettype()
Server

Full exception link from $error is on http://pastebin.com/WtxfYzb5


Got a bit further used $this.prop, but you cant initiate the constructor with your own parameters.

PS path:\> class Server {

    [string]$computerName = "192.168.0.200"
    [bool]$ping = (Test-Connection -ComputerName $this.computerName).count

}

PS path:\> 
PS path:\> $var = [server]::new()

PS path:\> $var

computerName  ping
------------  ----
192.168.0.200 True
like image 557
Luke Griffith Avatar asked May 28 '15 21:05

Luke Griffith


1 Answers

What you're needing is a constructor (or multiple constructors), if you don't specify one within your class the only constructor you get is the default one with no arguments.

As summing you're wanting to initialize your Server with an ip address different from the default (and allowing the default for $ping to fire.)

I've included the regions I normally include in my classes to distinguish between properties, constructors and methods.

class Server {
    #region class properties
    [string]$computerName = "192.168.0.200"
    [bool]$ping = (Test-Connection -ComputerName $this.computerName).count
    #endregion

    #region class constructors
    Server() {}

    Server([string]$computerName) {
        $this.computerName = $computerName
    }
    #endregion

    #region class methods
    #endregion
}

Now you can create an object without passing a parameter to it:

[1] PS G:\> $1 = [Server]::new()
[2] PS G:\> $1

computerName  ping
------------  ----
192.168.0.200 True



[3] PS G:\> $1.computerName = 'blah'
[4] PS G:\> $1

computerName  ping
------------  ----
blah          True

You can now also supply a ip address (or server name) when creating the object (note, don't supply the property name.)

[5] PS G:\> $2 = [Server]::new("192.168.0.100")
[6] PS G:\> $2

computerName  ping
------------  ----
192.168.0.100 True

Of note, notice there are two constructors inside the class. When testing this the default constructor that takes no arguments was no longer valid once I specified one of my own, so I've included a zero argument constructor for when you want to use all default values.

For more info about these classes, their constructors and methods, I would recommend checking out the videos Trevor Sullivan has released in the last few days.

like image 116
Windos Avatar answered Nov 15 '22 04:11

Windos