5

I have a list of ciphers that I need to identify and remove, and the easiest way for a non-developer to maintain this list is via a declaration similar to this:

$bannedCiphers = @{
    "RC4 128/128"=@{
        "IsPermitted" = $false
        "AffectedCiphers" = @{
                        "SSL_RSA_WITH_RC4_128_MD5",
                        "SSL_RSA_WITH_RC4_128_SHA",
                        "TLS_RSA_WITH_RC4_128_MD5",
                        "TLS_RSA_WITH_RC4_128_SHA"
        }
    } 
}

Although I'm having trouble creating the correct syntax for nested objects within Powershell.

What is the correct way to create an object with nested properties like the one above?

1
  • i would make a custom object with Name = [string], IsPermitted = [bool], and AffectedCiphers = [array]. that could be stored in an array or another collection type. perhaps a hashtable if you will have many such entries - all with a unique key - and need to look them up quickly. Commented Oct 31, 2018 at 18:06

3 Answers 3

3

This should do the trick...

$bannedCiphers = @{
    "RC4 128/128"= @{
        "IsPermitted" = $false
        "AffectedCiphers" = @(
            "SSL_RSA_WITH_RC4_128_MD5",
            "SSL_RSA_WITH_RC4_128_SHA",
            "TLS_RSA_WITH_RC4_128_MD5",
            "TLS_RSA_WITH_RC4_128_SHA"
        )
    } 
}

Furthermore, the $bannedCiphers hashtable could easily be converted to JSON (and back)

A la...

$bannedCiphers | ConvertTo-Json

...which outputs:

{  
   "RC4 128/128":{  
      "IsPermitted":false,
      "AffectedCiphers":[  
         "SSL_RSA_WITH_RC4_128_MD5",
         "SSL_RSA_WITH_RC4_128_SHA",
         "TLS_RSA_WITH_RC4_128_MD5",
         "TLS_RSA_WITH_RC4_128_SHA"
      ]
   }
}

If you had this data in JSON format to begin with, you could import that into PowerShell like:

$myJsonData = @"
    {  
       "RC4 128/128":{  
          "IsPermitted":false,
          "AffectedCiphers":[  
             "SSL_RSA_WITH_RC4_128_MD5",
             "SSL_RSA_WITH_RC4_128_SHA",
             "TLS_RSA_WITH_RC4_128_MD5",
             "TLS_RSA_WITH_RC4_128_SHA"
          ]
       }
    }
"@

$myNestedCiphers = $myJsonData | ConvertFrom-Json
Sign up to request clarification or add additional context in comments.

Comments

1

I thought I would re-post this answer and clarify my code a bit more using a custom object example.

Original solution without pscustomobject:

$bannedCiphers = @{
    "RC4 128/128"= @{
        "IsPermitted" = $false
        "AffectedCiphers" = @(
            "SSL_RSA_WITH_RC4_128_MD5",
            "SSL_RSA_WITH_RC4_128_SHA",
            "TLS_RSA_WITH_RC4_128_MD5",
            "TLS_RSA_WITH_RC4_128_SHA"
            )
        } 
    "Another RC4"= @{
        "IsPermitted" = $false
        "AffectedCiphers" = @(
            "Cipher1",
            "Cipher2",
            "Cipher3",
            "Cipher4"
            )
        } 
    }

The output of this solution will yield $bannedCiphers output:

Name                           Value
----                           -----
Another RC4                    {IsPermitted, AffectedCiphers}
RC4 128/128                    {IsPermitted, AffectedCiphers}

My solution creating custom objects:

$bannedCiphers2 = [pscustomobject]@{
    "RC4 128/128"= @{
        "IsPermitted" = $false
        "AffectedCiphers" = @(
            "SSL_RSA_WITH_RC4_128_MD5",
            "SSL_RSA_WITH_RC4_128_SHA",
            "TLS_RSA_WITH_RC4_128_MD5",
            "TLS_RSA_WITH_RC4_128_SHA"
            )
        } 
    "Another RC4"= @{
        "IsPermitted" = $false
        "AffectedCiphers" = @(
            "Cipher1",
            "Cipher2",
            "Cipher3",
            "Cipher4"
            )
        } 
    }

The output for my solution will yield $bannedCiphers2 output:

RC4 128/128                    Another RC4
-----------                    -----------
{IsPermitted, AffectedCiphers} {IsPermitted, AffectedCiphers}

original:

$bannedCiphers | Select-Object *

IsReadOnly     : False
IsFixedSize    : False
IsSynchronized : False
Keys           : {Another RC4, RC4 128/128}
Values         : {System.Collections.Hashtable, System.Collections.Hashtable}
SyncRoot       : System.Object
Count          : 2

vs:

$bannedCiphers2 | Select-Object *

RC4 128/128                    Another RC4
-----------                    -----------
{IsPermitted, AffectedCiphers} {IsPermitted, AffectedCiphers}

4 Comments

His question was more in regards to data type vs object type - why the need to make a PSCustomObject though? Where is the practicality? It's a loosely typed scripting language... you should take advantage of that or switch to C#
This is not apples to apples... you are discovering the difference between data type vs object type... you wouldnt do this in real life.. $bannedCiphers | Select-Object * you would just do $bannedCiphers - in practice, whether PsCustomObject or not, they both do the same exact thing as far as OP is concerned.. and to answer OP's question, I provided an answer based upon data type..
@MattOestreich Hi Matt, yes, I know. The reason I pipe the variables to select-object *, is to show the difference between the two. Both will do the job in the end of the day.
No worries! The output of: $bannedCiphers | Select-Object * and this: $bannedCiphers2 | Select-Object * outlines which properties those object types contain. A PSCustomObject is a "custom" type - a hashtable is not a custom type - its a "data type" that is defined in a class somewhere. You see the properties of that class when you do: $bannedCiphers | Select-Object * The "data type" hashtable holds a key/value pair - PSCustomObject is different - it is custom... therefore the properties of that type are also different - this does not change the data behind either type.
0

you can also create nested lists in a class.

class cChild{
[string] $id
[string] $field1
}

class cParent{
[string] $id
[string] $field1
[cChild[]] $child_list
}

one or more child classes can be nested in the parent as the variable $child_list. Classes set boundaries for acceptable data parsed from json.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.