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

Friday Fun Convert Object to Hash Table

Posted on October 21, 2011September 13, 2013

I've been working on a few PowerShell projects recently and one requirement I had was to turn an object into a hash table. I thought this was something that was already handled in PowerShell but I couldn't find a cmdlet or an easy .NET technique. So I wrote my own function, ConvertTo-Hashtable.

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!

The function is designed to accept pipelined input and turns each object into an associative array, i.e., a hash table, and write the hash table to the pipeline.

Function ConvertTo-HashTable {

[cmdletbinding()]

Param(
[Parameter(Position=0,Mandatory=$True,HelpMessage="Please specify an object",
ValueFromPipeline=$True)]
[object]$InputObject,
[switch]$NoEmpty
)

Process {
Write-Verbose "Converting an object of type $($_.GetType().Name)"
#get propery names
$names=$InputObject | get-member -MemberType properties | select-object -expandproperty name
#define an empty hash table
$hash=@{}
#go through the list of names and add each property and value to the hash table
$names | foreach-object {
Write-Verbose "Adding property $_"
$hash.Add($_,$inputobject.$_)
} #foreach
if ($noEmpty) {
Write-Verbose "Parsing out empty values"
#define a new hash
$defined=@{}
#get items from $hash that have values and add to $defined
$hash.keys | foreach-object {
if ($hash.item($_)) {
$defined.add($_,$hash.item($_))
}
}
Write-Verbose "Writing the result to the pipeline"
Write-Output $defined
}
else {
Write-Verbose "Writing the result to the pipeline"
Write-Output $hash
} #If $noempty
}#close process
}#end function

As an object is processed by the function it uses Get-Member to retrieve all of the object's properties.

$names=$InputObject | get-member -MemberType properties | select-object -expandproperty name

The function then walks the object and adds each property name and value to a hash table.

#go through the list of names and add each property and value to the hash table
$names | foreach-object {
Write-Verbose "Adding property $_"
$hash.Add($_,$inputobject.$_)
} #foreach

This hash table object, $hash, eventually is written to the pipeline. This process happens to each piped in object. However, I also added a function parameter, -NoEmpty, to filter out properties with no values. When specified, the function creates a second hash table and then checks each key in $hash. If the corresponding item has a value, the key and value are added to the secondary hash.

if ($noEmpty) {
Write-Verbose "Parsing out empty values"
#define a new hash
$defined=@{}
#get items from $hash that have values and add to $defined
$hash.keys | foreach-object {
if ($hash.item($_)) {
$defined.add($_,$hash.item($_))
}
}
Write-Verbose "Writing the result to the pipeline"
Write-Output $defined

The secondary hash is then written to the pipeline. I had to take this approach because PowerShell doesn't like it when you try to modify and enumerate a hash table at the same time. Here's how you might use it:

PS S:\> $h=get-service spooler | convertto-hashtable
PS S:\> $h

Name Value
---- -----
ServiceName spooler
CanPauseAndContinue False
DisplayName Print Spooler
CanShutdown False
Site
Name spooler
MachineName .
ServiceType Win32OwnProcess, InteractiveProcess
Status Running
ServiceHandle SafeServiceHandle
Container
DependentServices {}
RequiredServices {HTTP, RPCSS}
ServicesDependedOn {HTTP, RPCSS}
CanStop True

Or to filter out the empty values:

PS S:\> get-service spooler | convertto-hashtable -NoEmpty

Name Value
---- -----
ServiceName spooler
DisplayName Print Spooler
RequiredServices {HTTP, RPCSS}
Name spooler
MachineName .
Status Running
ServiceHandle SafeServiceHandle
ServiceType Win32OwnProcess, InteractiveProcess
ServicesDependedOn {HTTP, RPCSS}
CanStop True

Granted, your use case for something like this is probably pretty limited. But there are some good technique examples here on working with hash tables.

The one nagging problem, at least until PowerShell v3, is that it is very difficult to write a sorted hash table. I'd love to write the hash table to the pipeline with sorted keys, but that may have to wait.

In the meantime, feel free to download and experiment with ConvertTo-Hashtable.


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

3 thoughts on “Friday Fun Convert Object to Hash Table”

  1. JV says:
    October 21, 2011 at 11:32 am

    That is a good generalization of what I did here to unwind the wrapped properties of an adsi search result object.

    http://gallery.technet.microsoft.com/scriptcenter/Extract-arbitrary-list-of-6f59d3b4

  2. Rob Campbell says:
    October 22, 2011 at 8:57 am

    “I’d love to write the hash table to the pipeline with sorted keys, but that may have to wait.”

    Process {
    Write-Verbose "Converting an object of type $($_.GetType().Name)"
    #get propery names
    $names=$InputObject | get-member -MemberType properties | select-object -expandproperty name
    #define an empty hash table
    $hash= new-object system.collections.specialized.ordereddictionary
    #go through the list of names and add each property and value to the hash table
    $names | sort | foreach-object {
    Write-Verbose "Adding property $_"
    $hash.Add($_,$inputobject.$_)
    } #foreach
    if ($noEmpty) {
    Write-Verbose "Parsing out empty values"
    #define a new hash
    $defined=new-object system.collections.specialized.ordereddictionary
    #get items from $hash that have values and add to $defined
    $hash.keys | foreach-object {
    if ($hash.item($_)) {
    $defined.add($_,$hash.item($_))
    }
    }
    Write-Verbose "Writing the result to the pipeline"
    Write-Output $defined
    }
    else {
    Write-Verbose "Writing the result to the pipeline"
    Write-Output $hash
    } #If $noempty
    }#close process
    }#end function

    1. Jeffery Hicks says:
      October 22, 2011 at 1:10 pm

      I knew it could be done. Unfortunately it takes more knowledge than a typical IT Pro is likely to have. Thanks for your work.

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