Constructors are important subjects in object-oriented programming. A constructor is a special method of initializing the creation of an object. The constructor is used to add (or not) an extra layer of control during the instantiation of an object.

For example, you can check if parameters respect a certain type and format, or even do some external infrastructure tests that your object might depend on. For instance, you can check if a user with the same name already exists in the Active Directory.

The default constructor

The object can only be created if the validation process is successful. If you don't explicitly define a constructor, PowerShell will use the default "parameter-less" constructor.

Constructors allow you to validate the input parameters prior to the creation of the object. Only if the validation succeeds, will the object be created. Since the constructor is actually just a method, the validation can be anything that fits your needs. Most commonly, a constructor will contain some parameter validation, to guarantee that the user input is safe to use. If you do not create a custom constructor, PowerShell will use the default parameter-less constructor.

In the example provided in my previous post, the code we had at the beginning of the class looked like this:

Class Employee {
    [string]$FirstName
    [string]$LastName
    [string]$UserName
    [string]$EmployeeType
}

However, technically speaking, PowerShell used the following code behind the scenes:

Class Employee {
    [string]$FirstName
    [string]$LastName
    [string]$UserName
    [string]$EmployeeType

    Employee (){
    }
}

PowerShell added a default constructor which has the same name as that of the class.

Creating your own constructor

To be valid, a constructor must always have the same name as the class. As with methods, a constructor can have typed arguments. It is important to note that, as opposed to methods, you do not need to specify a return type because incidentally, the return type is the class you are instantiating.

You can work with your own constructor(s) as soon if you want to add an extra layer of controls for the arguments that are passed during the instantiation of the object, or if you want to add an extra layer of logic (I’ll showcase this in an example a bit later on).

Note that when you add your own constructor, the default constructor actually disappears. If you want to have a parameter-less constructor, you will have to manually include it in your class.

In my previous example, I used the method Create() to create a user account in the Active Directory based on the information stored in our object. You need to ensure that every property has been set, otherwise the creation of the user object will fail.

The three parameters that you need to be able to create a user object in the Active Directory are the following: FirstName, LastName, and UserType. The user type can either be "Internal" or "External". Depending on the type of user, I will copy the user object into specific OU.

Internal users will be created in OU=Internal,OU=Users,OU=HQ,DC=District,DC=Local

External users will be created in OU=External,OU=Users,OU=HQ,DC=District,DC=Local

Employee ([String]$FirstName,[String]$Lastname,[String]$EmployeeType){

    #Initializing variables
     $UserOU = ""

     #Assigning property values
      $this.EmployeeType = $EmployeeType
      $this.FirstName = $FirstName
      $this.LastName = $Lastname

     #Notice the call to our static method [GetNewUserName]
      $this.UserName = [Employee]::GetNewUserName($FirstName,$Lastname)

     #Notice the call to our static property [DomainName]
      $this.OU = "OU=$($EmployeeType)," + "OU=Users,OU=HQ," + [employee]::DomainName           
  }

In the end, gaining an understanding of constructors is pretty straightforward. The trick here is that we used what we had built at the beginning of this article, and integrated our static property DomainName and static method GetNewUserName.

Now that everything is set, we can create the object and display its property values:

$NewEmployee = [employee]::new("Stephane","Van Gulick","Internal")
$NewEmployee
Creating an object

Creating an object

To create a user object, you can now use your create() method.

$NewEmployee.Create()

If you check the Internal OU, you will find the new user object.

User object created in Active Directory

User object created in Active Directory

From now on, you can create a new user object with just two lines of code:

$NewEmployee = [employee]::new("Stephane","Van Gulick","Internal")
$NewEmployee.Create()

It will respect the naming convention that you introduced, and it is set in the appropriate OU, in accordance to the type of user object you want to create.

This is the complete class of my example:

Subscribe to 4sysops newsletter!

Class Employee {

    [ValidatePattern("^[a-zA-Z]+$")]
    [string]$FirstName
    [ValidatePattern("^[a-z A-Z]+$")]
    [string]$LastName
    hidden [string]$UserName
    [ValidateSet('Internal','External')]
    [string]
    $EmployeeType
    [ValidatePattern("^OU=")]
    [string]$OU
    hidden static [string]$DomainName = "DC=District,DC=Local"

    #Constructors
    Employee (){
    } 
    Employee ([String]$FirstName,[String]$Lastname,[String]$EmployeeType){
            #Initializing variables
                $UserOU = ""
            #Setting properties
                $this.EmployeeType = $EmployeeType
                $this.FirstName = $FirstName
                $this.LastName = $Lastname
            #Notice the call to our static method
                $this.UserName = [Employee]::GetNewUserName($FirstName,$Lastname)
            #Notice the call to our static property
                $this.OU = "OU=$($EmployeeType)," + "OU=Users,OU=HQ," + [employee]::DomainName   
    }

    #Methods
    [string]static GetNewUserName([string]$FirstName,[string]$LastName){
            $start = $LastName.replace(" ","").Substring(0,5)
            $end = $FirstName.Substring(0,2)
            $UName = ($start + $end).ToLower()
            $AllNames = Get-ADUser -Filter "SamaccountName -like '$UName*'"
            [int]$LastUsed = $AllNames | % {$_.SamAccountName.trim($Uname)} | select -Last 1
            $Next = $LastUsed+1
            $nextNumber = $Next.tostring().padleft(2,'0')
            $SamAccountName = $UName + $nextNumber
        return $SamAccountName
    } 

    [employee]Create(){
        New-ADUser  -SamAccountName $this.UserName `
                    -GivenName $this.FirstName `
                    -Surname $this.LastName `
                    -Name $this.UserName `
                    -UserPrincipalName $this.UserName `
                    -DisplayName ($this.FirstName + " " + $this.LastName) `
                    -Description ($this.FirstName + " " + $this.LastName) `
                    -Path $this.OU
        return $this
    } 
} 
$NewEmployee = [employee]::new("Stephane","Van Gulick","Internal") 
$NewEmployee | Get-Member

If you are interested in learning more about the advanced concepts of PowerShell classes, you can read my articles about inheritance and polymorphism.

avatar
Articles in seriesPowerShell classes
3 Comments
  1. David V. Corbin 3 years ago

    Link is broken… Looks like site no longer exists… If you want to read more about constructors, I recommend this article.

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account