Extending Objects in Windows PowerShell, Part 3

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:

Revisiting How to Make an Object in PowerShell

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.

Sponsored Content

Passwords Haven’t Disappeared Yet

123456. Qwerty. Iloveyou. No, these are not exercises for people who are brand new to typing. Shockingly, they are among the most common passwords that end users choose in 2021. Research has found that the average business user must manually type out, or copy/paste, the credentials to 154 websites per month. We repeatedly got one question that surprised us: “Why would I ever trust a third party with control of my network?

$obj = [pscustomobject]@{
  Name = $env:username
  Computer = $env:computername
  OS = (Get-CimInstance Win32_OperatingSystem).Caption
  PSVersion = $PSVersionTable.PSVersion

In either event, you get an object.

Our new object in Windows PowerShell. (Image Credit: Jeff Hicks)
Our new object in Windows PowerShell. (Image Credit: Jeff Hicks)

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.

Our new script properties and methods. (Image Credit: Jeff Hicks)
Our new script properties and methods. (Image Credit: Jeff Hicks)

I can use this object to get some useful management information from the local computer.

Using the uptime property to gather meaningful information. (Image Credit: Jeff Hicks)
Using the uptime property to gather meaningful information. (Image Credit: Jeff Hicks)

Creating a Custom Server Management Framework

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 {
$disk = Get-CimInstance -Classname win32_logicaldisk -filter "deviceid = '$drive'" -ComputerName $this.computername
$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.

Using our refresh method in Windows PowerShell. (Image Credit: Jeff Hicks)
Using our refresh method in Windows PowerShell. (Image Credit: Jeff Hicks)

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.

Related Topics:


Don't have a login but want to join the conversation? Sign up for a Petri Account

Comments (0)

Leave a Reply

13 Email Threat Types to Know About Right Now

As email threats evolve and multiply, keeping track of them all—and staying protected against the many different types—becomes a complex challenge. Today, that requires more than just the traditional email gateway solution that used to be good enough.

In this eBook you will learn:

  • What are the most common and challenging email attacks for organizations?
  • How to defend against sophisticated email threats, such as spoofing, social engineering, and fraud
  • How to protect employees at the inbox level with the right technologies and security-awareness training
  • How to use a multilayered protection strategy to reduce susceptibility to email attacks and better defend your business and employees

Sponsored by: