Author Posts

October 10, 2016 at 2:39 pm

Hi,

I am learning scripting, i came across a script which Creates OU's in Active Directory
Using an Inputfile and produces an Csv log output.

I have this function log-me in Example 1, i have re-written it Example 2 in the style i learned [i am following MVA/DonJones/JasonHelmic video tuts].

My question is, why do many people who write scripts for automation use Example 1 method, creating an object, adding members,
where as it could be done in hashtable format as in example 2.

Is it an old v1 or v2 style of writing or does it have any advantages over an hashtable?
because i noticed that we cannot have 2 NoteProperties with same name, same with hashtable, we cannot have two keys with same name.

What are the advantages/pro's con's of these two styles.

#Example 1
Function Log-Me{

param(
	[String]$OUPathTrans,
	[Boolean]$validate,
	[String]$OUStatus,
	[String]$ParOUPath
)

    $object = New-Object -TypeName psobject

    $object | Add-Member -Name Complete_OU_DN -MemberType NoteProperty -Value $OUPathTrans
    $object | Add-Member -Name Parent_OU_DN -MemberType NoteProperty -Value $ParOUPath
    $object | Add-Member -Name AlreadyExists -MemberType NoteProperty -Value $validate
    $object | Add-Member -Name OUCreated -MemberType NoteProperty -Value $OUStatus
    $object | Add-Member -Name Parent_OU_DN1 -MemberType NoteProperty -Value $ParOUPath


    return $object
}


#Example2
Function Log-Me{

param(
	[String]$OUPathTrans,
	[Boolean]$validate,
	[String]$OUStatus,
	[String]$ParOUPath
)


    $object = [PSCustomObject][ordered]@{'Complete_OU_DN' = $OUPathTrans;
                                'Parent_OU_DN' = $ParOUPath;
                                'AlreadyExists' = $validate;
                                'OUCreated' = $OUStatus;
                            
    }

    $object
}
  • This topic was modified 1 year, 10 months ago by  Sikander Mirza. Reason: spell

October 10, 2016 at 3:15 pm

One more thing i noticed, an empty array is declared at the beginning of the script eg: $collobjects = @()
and the log-me function the values is assigned to this array eg: $collobjects += log-me –

and finally the array is exported to an csv, so if we use hashtable in the log-me function will it still work.
Please don't go on the code specific, i need the concept.

October 10, 2016 at 3:36 pm

There are many ways to accomplish the same things in scripting. The pscustomobject class was introduced in V3, so if you want your code to function in v2, you need to use older methods to generate objects. You can still use hash tables to generate a PSObject to be supported in V2+, however, performing ordering is more complicated:

$props = @{
    'Complete_OU_DN' = $OUPathTrans;
    'Parent_OU_DN' = $ParOUPath;
    'AlreadyExists' = $validate;
    'OUCreated' = $OUStatus;
}

New-Object -TypeName PSObject -Property $props

One of most overlooked methods for generating object is Select-Object.

$os = Get-WMIObject -Class Win32_OperatingSystem
$cs = Get-WMIObject -Class Win32_ComputerSystem


# We'll use Select-Object to generate a new PSObject and we
# can even rename the Manufacturer from Win32_ComputerSystem so
# that there is not duplicated property names
$myNewObject = $os |
Select Manufacturer, 
       SerialNumber, 
       SystemDirectory,
       @{Name="ComputerManufacturer";Expression={$cs.Manufacturer}}

Personally, I don't like Add-Member to create objects. It's not very clean and when you start looping you have to use -Force to overwrite property names. Add-Member can be used to add the same value to each row, for instance you want to add ComputerName to the previous object:

$myNewObject | Add-Member -MemberType NoteProperty -Name ComputerName -Value $env:COMPUTERNAME

Add-Member can do some other advanced items like setting default viewable properties: https://learn-powershell.net/2013/08/03/quick-hits-set-the-default-property-display-in-powershell-on-custom-objects/

October 10, 2016 at 3:54 pm

Your second question about defining an empty array. A PSObject is an array of hash tables. You will see examples like this:

$object = @()

for ($i=1;$i -le 5;$i++) {
   $object += New-Object -TypeName PSObject -Property @{ComputerName = ("Computer{0}" -f $i)}
}

$object

Before you run it, remark out the first line. When you do, you should receive an error "does not contain a method named 'op_Addition'". Un-remark it and run it again. The first time it was run, without defining an array, you're trying to append (add) to a static object, so there is nothing to add to. Here is a the best method I have found to append to an object:

$object = for ($i=1;$i -le 5;$i++) {
   New-Object -TypeName PSObject -Property @{ComputerName = ("Computer{0}" -f $i)}
}

$object

October 10, 2016 at 4:34 pm

Add-Member was the only way to populate an object in the early versions of PowerShell. You still see a lot of scripts using Add-Member because they were either written a long time back, the author isn't aware of any other approach or they haven't kept up to date with changes in PowerShell

Using a hash table is a lot less work and is the recommended approach.

October 12, 2016 at 11:52 am

Thanks, its clear now.