Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Are You My Type?

Posted on October 26, 2017

I am always stressing that PowerShell is all about the objects. If you keep this in mind, PowerShell is pretty easy to use. Get a bunch of things, and select the details that you want to see or work with. Out of the box PowerShell gives you some very rich objects to work with from simple files to Active Directory users. What I like even more is that you can create your own properties "on-the-fly" to meet your needs. It is almost like magic. You can create new properties practically out of thin air. But sometimes even this process can get a bit tedious or overwhelming. Let me offer some solutions.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Let's begin a PowerShell expression you might run to discover what system drivers are currently running.

Get-CimInstance -class win32_systemdriver -filter "state='running'" |
Select-Object Name,Description,ServiceType,StartMode,@{Name="Path";Expression={$_.pathname}},
@{Name="Company";Expression = {(get-item $_.pathname).versioninfo.CompanyName}},
@{Name="Product";Expression = {(get-item $_.pathname).versioninfo.ProductName}},
@{Name="Version";Expression = {(get-item $_.pathname).versioninfo.productversion}},
@{Name="Updated";Expression = {(get-item $_.pathname).lastwritetime}},
@{Name="Computername";Expression={$_.SystemName}}

image

Effective, although, this is a lot of typing. With Select-Object I created a few alias properties using hashtables. For example, instead of using 'SystemName,' I wanted to display 'Computername'. I also wanted to include information that wasn't a part of the Win32_SystemDriver object. The object did include a property for the file path, so I create a few custom properties that retrieved version information from the file.

@{Name="Company";Expression = {(get-item $_.pathname).versioninfo.CompanyName}},
@{Name="Product";Expression = {(get-item $_.pathname).versioninfo.ProductName}},
@{Name="Version";Expression = {(get-item $_.pathname).versioninfo.productversion}}

The challenge is that if I want to re-run the command perhaps with a different filter or a different subset of properties, I have to re-type a lot of code. I'm betting you don't like to type.  Let's look at some options.

First, you could save your custom property definitions as variables.

$path = @{Name="Path";Expression={$_.pathname}}
$company = @{Name="Company";Expression = {(get-item $_.pathname).versioninfo.CompanyName}}

I can use these variables in my Select-Object statement.

Get-CimInstance -class win32_systemdriver -filter "state='running'" | 
Select-Object Name,Description,StartMode,$path,$company  | Group Company

image

As long as I have these variables defined I can use them as often as I want.

But perhaps the best approach is to create you own type extension. Before you run away thinking I'm asking you to create an arcane looking xml file, this is actually quite easy. First, you need typename of the object you want to extend. You see this every time you use Get-Member.

image

I'm going to save this value with a line of code.

$type = get-ciminstance win32_systemdriver | select-object -first 1 | Get-member | Select-object -ExpandProperty TypeName

More than likely this variable will be an array of names so I'll use $type[0]

image

Next, I'm going to use the Update-TypeData cmdlet. Yes, you can use a ps1xml file but you don't have to.  I can just easily create my alias properties.

Update-TypeData -TypeName $type[0] -MemberType AliasProperty -MemberName Path -Value pathname -force
Update-TypeData -TypeName $type[0] -MemberType AliasProperty -MemberName Computername -Value SystemName -force

The Value is the name of the actual property. I'm using –Force to overwrite any existing property definitions. I can also create ScriptProperties which will run a small bit of code to get a value.

Update-TypeData -TypeName $type[0] -MemberType ScriptProperty -MemberName Company -Value {(get-item $this.pathname).versioninfo.CompanyName} -force
Update-TypeData -TypeName $type[0] -MemberType ScriptProperty -MemberName "Product" -Value {(get-item $this.pathname).versioninfo.ProductName} -force
Update-TypeData -TypeName $type[0] -MemberType ScriptProperty -MemberName "Version" -Value {(get-item $this.pathname).versioninfo.productversion} -force
Update-TypeData -TypeName $type[0] -MemberType ScriptProperty -MemberName "Updated" -Value {(get-item $this.pathname).lastwritetime} -force

The Value is the scriptblock portion of the Expression key I defined early. The only other change you must remember to make is to use $this instead $_.

Now, these properties are defined for any Win32_SystemDriver object.

Get-CimInstance Win32_SystemDriver -filter "state='running'"  | 
Select-Object Name,Description,ServiceType,StartMode,Path,Company,Product,Version,Updated,Computername |
Out-Gridview -title "Running Drivers"

image

See how much easier and cleaner that is? I can use these properties as much as I want.

Get-CimInstance Win32_SystemDriver -filter "servicetype='kernel driver'"  |
Where Company -notmatch "microsoft" | Sort StartMode,Name |
Format-Table -GroupBy StartMode -Property State,Name,Company

However, remember that these are *your* properties and not part of WMI which is why I can't use them in the Get-CimInstance filter.

image

A few final caveats on this technique. These extensions will only last for as long as my PowerShell session is running. If I always want to have them, I would put this code in my PowerShell profile script. You should also be careful when writing scripts or modules that use these extensions. If someone is running your code and they haven't added the type extensions the code won't work. In a module, you can add the Update-TypeData lines into your .psm1 file. Or you can take the extra steps to create an actual .ps1xml file with the extensions and include that with your module.

Give my code samples a spin and let me know what you think.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

2 thoughts on “Are You My Type?”

  1. Pingback: Adding Efficiency with PowerShell Type Extensions
  2. Gyz says:
    November 5, 2017 at 1:37 pm

    Indeed very cool stuff, more powerful and simpler than Select-Object with an expression. thank you!

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d