Recently I received the question the /r/PowerShell community if it was possible to create an object that refers to its own properties when it is created. The user specified that they would prefer to create this as a one-liner.
Using the Add-Member cmdlet in combination with the -Passthru parameter this is quite simple to do, for example:
1 2 3 | $Object = New-Object PSObject -property @{ Property1 = 'Hello World' } | Add-Member ScriptProperty GetProperty1 {$This.Property1} -PassThru |
To make this slightly more interesting it is also possible to manipulate this object by using the manipulating the property. In the following example a property ‘Today’ is created and the script property uses this property to calculate the next week. For example:
1 2 3 | $Object = New-Object PSObject -Property @{ Today = (Get-Date).Date } | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru |
It is also possible to create a ScriptMethod that uses the previously defined property, in the next example I create a ScriptMethod that can add or substract a week from the Today property:
1 2 3 4 | $Object = New-Object PSObject -Property @{ Today = (Get-Date).Date } | Add-Member ScriptProperty NextWeek {($This.Today).AddDays(7)} -PassThru | Add-Member ScriptMethod AddWeeks {param([int]$Week) $This.Today.AddDays($Week*7)} -PassThru |
Love it! This solution begs for a class example as well eh? 😉
I should do some more blogging on classes you are right Irwin! Here you go, a sample of two different approaches of doing this with objects returned by classes:
class MyObject {
[pscustomobject]Get() {
return [pscustomobject]@{'Today' = Get-Date} |
Add-Member ScriptProperty 'NextWeek' {$This.Today.AddDays(7)} -PassThru
}
}
[MyObject]::New().Get()
class MyObject2 {
[pscustomobject]Get() {
return [pscustomobject]@{'Today' = Get-Date}
}
}
[MyObject2]::New().Get() | Add-Member ScriptProperty 'NextWeek' {$This.Today.AddDays(7)} -PassThru
Class ClassWeeks {
[String]$Today
[String]$NextWeek
ClassWeeks() {
$this.Today = (Get-Date).DateTime
$this.nextWeek = (Get-Date).AddDays(7).DateTime
}
[void]AddWeeks([int]$Weeks){
Write-Host -Object ( ‘{0}’ -f ( (Get-Date) + (New-TimeSpan -Days ($Weeks*7)))) -ForegroundColor Green
}
}
$day = [ClassWeeks]::new()
$day.AddWeeks(2)
Granted it isn’t dynamic, but maybe you could make so? :p
Regards,
Irwin
Hi Jaap,
That was quick!!! I didn’t see your reply… Gonna dissect this just as soon I get some time!
KG/Irwin
No problem, let me know what you think.