user12007109
user12007109

Reputation:

How do I convert an object to a Hashtable in Powershell?

I have a variable which is declared as (for example)

$dict_object = @{Firstname="A";Lastname="B"}

I want to run another command , any command for example, Get-CIMInstance -class win32_BIOS and I wanted to compare the output with the $dict_object variable using compare-object. The problem is that the $dict_object is a hashtable whereas the command output is not a hashtable. This is just example but is there any way to convert Powershell command output into a hashtable and compare it with a Hashtable variable/object. I tried using Convertfrom-stringData but it is not assigning key value pairs as expected.

For example, this is the command with convertfrom-stringdata

PS C:\Windows\System32> Get-CimInstance -class win32_bios | ConvertFrom-StringData
Name                           Value
----                           -----
Win32_BIOS: 1.6.0 (Name        "1.6.0", SoftwareElementID = "1.6.0", SoftwareElementState = 3, TargetOperatingSystem =…

versus normal output

PS C:\Windows\System32> Get-CimInstance -class win32_bios

SMBIOSBIOSVersion : 1.6.0
Manufacturer      : Dell Inc.
Name              : 1.6.0
SerialNumber      : BDM8P93
Version           : DELL   - 20170001 

I am expecting the above to has first column as key and second column as value but it seems ConvertFrom-StringData is not working that way.

I need this to compare existing variable with output from Get-WebconfigurationProperty (IIS Module) and if the value is not right, then else block will execute Add-webconfigurationProperty where I have tested that the Add-webconfigurationProperty takes HashTable as input

Upvotes: 1

Views: 1449

Answers (2)

mklement0
mklement0

Reputation: 437513

  • Get-CimInstance outputs (non-string) objects, not strings, so its output cannot meaningfully serve as input to ConvertFrom-StringData, which expects strings in a specific format.

  • While you cannot (directly) convert objects to hashtables, you can directly convert preexisting[1] hashtables to ([pscustomobject]) objects; e.g.:

    $dict_object = 
    $object_from_dict = [pscustomobject] $dict_object
    
  • And, of course, you may directly a [pscustomobject] instance directly, as a literal[1]:

    $object = [pscustomobject] @{Firstname="A";Lastname="B"}
    

As AdminOfThings notes, once you have (non-hashtable) objects to compare, you can compare multiple properties across two [collections of] objects using the Compare-Object cmdlet, passing the set of properties to compare the objects by to the -Property parameter:

# Reference object (the one with comparison values).
$refObj = [pscustomobject] @{ Manufacturer = 'Dell Inc'; Name = '1.6.0' }

# Difference object (the one to compare against, from command output)
$diffObj = Get-CimInstance -Class win32_BIOS

# Compare the two objects, by the properties defined on the reference object.
Compare-Object $refObj $diffObj -Property $obj.psobject.Properties.Name

By default, Compare-Object outputs only those input objects that differ, wrapped in a [pscustomobject] instance with a .SideIndicator property indicating which input side the object is unique to; see this answer for more information.


[1] Creating [pscustomobject] literals even uses hashtable syntax (e.g., [pscustomobject] @{Firstname="A";Lastname="B"}), but that is actually syntactic sugar that constructs the object directly, not via an intermediate hashtable. Also note that such a literal preserves the definition order of the keys / property names, unlike true hashtables.

Upvotes: 1

Alex_P
Alex_P

Reputation: 2952

I would run the Get-CimInstance once and populate a hashtable according to the values you need. For example:

$cimInstance = Get-CIMInstance -class win32_BIOS
$cimHashTable = @{
  Name = $cimInstance.Name
  Version = $cimInstance.Version}
}
if ($cimHashTable.Name -eq 'CorrectValue')
{
  continue
}
else
{
  Fix-Value
}

However, in this case I actually wouldn't make the effort and create a new HashTable but just use the $cimInstance variable and check for the values directly.

Upvotes: 0

Related Questions