A little bit of $this. A little bit of $_

by willsteele at 2012-08-15 10:39:43

Trying to be a little funny with the subject. One question that has eluded me with advanced scripting is the proper implementation of the $this object. I have a light C# background, so, I am somewhat familiar with its use in that language. But, I have a slightly different construct in mind for the PowerShell use of $this and I wanted to see if it was accurate. When I use $this I see it as a singular implementation of the pipeline variable $_. In other words, it refers to the object currently being referenced by the method, property, etc. Is this an accurate way to think of it? Unfortunately, there aren’t too many explanations of it and I would like to take greater advantage of the Add-Member cmdlet and its MembersTypes. It seems understanding $this is important to that task.
by poshoholic at 2012-08-15 12:07:32
Great question Will.

$this is a variable representation of the object itself. When you use $this inside of a ScriptProperty or ScriptMethod that you have added with Add-Member, it allows you to refer to the object itself and reference other properties or methods on that object.

Here’s a very simple example showing how $this is useful in ScriptProperties:

# First create a simple object with two properties, FirstName and LastName
$myObject = New-Object -TypeName System.Management.Automation.PSObject -Property @{
FirstName = ‘Kirk’
LastName = ‘Munro’
}
# Now define a custom object type (because that’s important to do)
$myObject.PSTypeNames.Insert(0,‘My.Custom.Type.Name’)
# Add a ScriptProperty that is calculated only when that property is displayed (this
# is a very important point, it’s a totally dynamic value we’re dealing with here,
# determined at the time that the object is rendered/displayed; meaning, the value
# itself does not exist in memory as part of the object)
Add-Member -InputObject $myObject -MemberType ScriptProperty -Name FullName -Value {"$($this.FirstName) $($this.LastName)"}
# Now show the object
$myObject
# And note that since we didn’t use the setter (-SecondValue on Add-Member for
# ScriptProperty members), it’s a read-only property, so this returns an error.
$myObject.FullName = 'Kirk “Poshoholic” Munro’


Does that answer your question?
by willsteele at 2012-08-15 19:18:38
It does, but, brings up one simple clarifying question: can I use this anywhere in a script? Or, is it relegated to specific block types?
by poshoholic at 2012-08-15 22:20:49
The $this variable is only an automatic variable inside of script blocks that define script property getters or setters or script blocks that define script method behaviour.
by DexterPOSH at 2012-08-16 04:51:59
Great Question Will, and neatly explained by Kirk.

But I have a doubt why we need to define a custom object type? What purpose it achieves ?

# Now define a custom object type (because that’s important to do)
$myObject.PSTypeNames.Insert(0,‘My.Custom.Type.Name’)


Regards
Dexter
by willsteele at 2012-08-16 07:36:12
Got it now. Thanks
by poshoholic at 2012-08-16 08:26:34
Hi Dexter,

You should always define a custom type name for your custom objects as a best practice. Type names mean something in PowerShell, even if they are ETS type names. They’re used in the type and format ps1xml files to define additional extensions on those types, default display property sets, format specifications, etc. They’re used in commands in the OutputType attribute to define the type of objects that a command might return (this is important in v3 because Intellisense uses input and output types on commands to give you the most appropriate options first when pipelining). They’re used in strong typing. They’re used in 3rd party tools like the PowerGUI admin console, where actions that are available for a given object are based on the type of that object. They’re used in Get-Member output to identify the type of the object you’re working with as well as the members that are available on that object. In short, they’re very important in PowerShell, useful for all sorts of things to give PowerShell even more value. If you’re not setting the type of your custom objects now, I’d bet you’re going to end up circling back at a later date to add it, either because you need it or because someone using your objects requests it. And it’s a very simple, single line of script to add.
by DexterPOSH at 2012-08-16 08:34:35
Thanks a lot Kirk!
This has been enlightening.
I will start following this best practice.