Dynamic Fields in Objects – what?
Short post today, but I wanted to talk about dynamic properties in objects. I haven’t had too much need for this kind of thing, but the fact that PowerShell can do it so easily is pretty cool. Imagine having an object where you plug a value into one field and dynamically another field in the object changes based on that first value. Kind of sounds like a function, but it’s all done right in the object itself.
A little background. Colleague of mine was trying to use CMD.exe DIR command to make a fast Get-ChildItem, one that doesn’t get every single object property for a file, which in theory would retrieve that information much faster then Get-ChildItem. For now he’s abandoned the project because the speed wasn’t there but it brought up some interesting points, and one of them was directory name. When using DIR you often only get the BaseName property, not the full path but as a scripter I almost always want the full path. Certainly ways of getting that information but we would really want to display both. What if we could just have the object do it and not worry about?
What if you were dealing with a lot of disk size values and wanted the flexibility of seeing MB and GB conversions? Sure you could send it off to a function but lets consider another way.
Add-Member
It all begins with Add-Member. Let’s keep it simple and go with the BaseName calculation I mentioned before. First let’s define some things:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$dir = "C:\Users\mpugh\AppData\Local\ActiveState\KomodoEdit\8.5\codeintel\db" | |
$DynamicObject = [PSCustomObject]@{FullName = $Dir} |
No real drama, get some data and create an object with that data as a property (FullName). Now I want to add my dynamic property:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$DynamicObject | Add-Member –MemberType ScriptProperty –Name BaseName –Value { | |
$this.FullName.Split("\")[-1] | |
} |
This is where it gets cool. We take the object we created and pipe it into Add-Member which will add a property, in this case a ScriptProperty which will evaluate it’s value based on the scriptblock in the Value field. This is a pretty simple script function where I take the current object ($this) take the FullName property and split that on the back slash. Then take the last element in the returned array for display (which will be the last folder in the path–in this case).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$DynamicObject | |
FullName BaseName | |
——– ——- | |
C:\Users\mpugh\AppData\Local\ActiveState\KomodoEdit\8.5\codeintel\db db |
Cool. But we could have just assigned the BaseName value when we created the object right? Check this out:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PS C:\Users\mpugh> $DynamicObject.FullName = "C:\Users\mpugh\AppData\Local" | |
PS C:\Users\mpugh> $DynamicObject | |
FullName BaseName | |
——– ——– | |
C:\Users\mpugh\AppData\Local Local |
Notice all we did was change the FullName property, but the BaseName property dynamically changed. You’ve essentially created a class that dynamically changes itself based on the values you assign. You could still mimic all of this behavior by using Functions but it’s pretty interesting none the less. With PowerShell 5.0, Microsoft is promising us the ability to create classes without having to drop into C# which would really open up these kinds of techniques.
Imagine something like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Get-ChildItem $Path –Recurse | Select –Class MyDynamicFileObject –Property BaseName,FullName,SizeGB,SizeMB |
Where you’ve defined a class that automatically takes the Length property and converts it to MB and GB for you.
Follow-up post that coming soon that explains this tweet:
Holy crap. Add-Member may be my new performance go to!
#Crazy#Love#PowerShell#ForeShadowing
Love finding new technique’s that increase performance…. do you?
No comments yet.
Leave a Reply