Last Update: Sep 04, 2024 | Published: Aug 13, 2015
In the last part of this series, I demonstrated how to extend results that you might get back from a cmdlet. As you hopefully know, you can create an object out of thin air in PowerShell by using the New-Object cmdlet.
Extending Objects in PowerShell Article Series:
To create an object in PowerShell, all you need to do is specify a hashtable of property values.
$obj = New-Object psobject -Property @{
Name = $env:username
Computer = $env:computername
OS = (Get-CimInstance Win32_OperatingSystem).Caption
PSVersion = $PSVersionTable.PSVersion
}
You can also use the [PSCustomObject] type accelerator.
$obj = [pscustomobject]@{
Name = $env:username
Computer = $env:computername
OS = (Get-CimInstance Win32_OperatingSystem).Caption
PSVersion = $PSVersionTable.PSVersion
}
In either event, you get an object.
This type of object can also be extended by using the same techniques I showed earlier.
$obj | Add-Member -MemberType ScriptProperty -Name Uptime -value {
(Get-Date) - (Get-CimInstance win32_operatingsystem).LastBootUpTime }
$m1= {get-service | where {$_.status -eq "stopped"}}
$m2= {Param([string]$log="System") Get-Eventlog -logname $log -newest 10}
$obj | Add-Member -MemberType ScriptMethod -Name GetRunning -Value $m1
$obj | Add-Member -MemberType ScriptMethod -Name GetLastLogs -Value $m2
I went ahead and added a script property and a few methods.
I can use this object to get some useful management information from the local computer.
With this in mind, it seemed to me that I could create a custom server management framework. Here’s how this might work.
First, I need a computer name.
$computername = "chi-test01"
Next, I’ll outline a few standard properties.
$os = Get-Ciminstance -ClassName Win32_operatingsystem -ComputerName $computername
$PSVersion = Invoke-Command {$PSVersionTable.PSVersion} -HideComputerName -computername $Computername
This is probably enough information to create an object.
$managed = [pscustomobject]@{
Computername = $computername.ToUpper()
PSVersion = $PSVersion
OperatingSystem = $os.Caption
ServicePack = $os.CSDVersion
LastBoot = $os.LastBootUpTime
}
Now to add some custom methods I can use as management tools.
$managed | Add-Member -MemberType ScriptProperty -Name ProcessCount -Value {(Get-Process -ComputerName $this.computername).count}
$managed | Add-Member -MemberType ScriptProperty -Name Uptime -Value { (Get-Date) - (Get-Ciminstance win32_operatingsystem -computername $this.computername).lastBootUptime } -force
$managed | Add-Member -MemberType AliasProperty -name OS -Value OperatingSystem
$managed | Add-Member -MemberType ScriptMethod -Name GetFreeSpace -Value {
Param([string]$Drive="c:")
$disk = Get-CimInstance -Classname win32_logicaldisk -filter "deviceid = '$drive'" -ComputerName $this.computername
$disk.Freespace}
$managed | Add-Member -MemberType ScriptMethod -Name Reboot -value { Restart-Computer -ComputerName $this.computername -force}
There’s one item that I haven’t show you, and that’s a property set. With a property set, you can reference a collection of properties by using a single name.
$managed | Add-Member -MemberType PropertySet -Name Boot -Value Computername,LastBoot,Uptime
I hope that you realize that there’s no limit to the type of information and methods you could include here. Although one step I think I should have is an option to refresh the object. Should something change, I need to be able to update any static properties.
$refresh = {
$this.PSVersion = Invoke-Command {$PSVersionTable.PSVersion} -HideComputerName -computername $this.Computername
$os = Get-Ciminstance -ClassName Win32_operatingsystem -ComputerName $this.computername
$this.OperatingSystem = $os.Caption
$this.LastBoot = $os.LastBootUpTime
$this.ServicePack = $os.CSDVersion
}
$managed | Add-Member -MemberType ScriptMethod -Name Refresh -value $refresh
I’ll test by rebooting the server.
$managed.Reboot()
What have we ended up with in terms of a management object?
By default I get all of the properties, including my alias. It might be more useful to define a default display. We can do this by defining a custom type for this object.
$myType = "my.ManagedComputer"
$managed.psobject.TypeNames.Insert(0, $myType)
These commands insert a new type name for my object.
Now that I have a unique type name, I can use Update-TypeData and define a default property set.
Update-TypeData -TypeName $myType -DefaultDisplayPropertySet Computername,OS,PSVersion,LastBoot,Uptime
Notice the change?
The other properties and methods are still available should I need them.
In the final article, we’ll take one final step and explore how to use this techniques to manage at scale.