2

How would I access the following values using the regex function in Powershell, and assign each one to an individual variable?:

id (i.e. get the value: TOKEN_ID) - under token

id (i.e. get the value: TENANT_ID) - under token, tenant

adminURL (i.e. get the value: http://10.100.0.222:35357/v2.0) - the first value under serviceCatalog,endpoints

As I am using Powershell v2, I can't use the ConvertFrom-Json cmdlet. So far I've tried converting the document to an xml file using the a third-party PS script, but it doesn't always get it right. I'd like to use regex, but I am not very comfortable with it.

$json =
    "{
        "access": {
            "metadata": {
                "is_admin": 0,
                "roles": [
                    "9fe2ff9ee4384b1894a90878d3e92bab"
                ]
            },
            "serviceCatalog": [
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8774/v2/TENANT_ID",
                            "id": "0eb78b6d3f644438aea327d9c57b7b5a",
                            "internalURL": "http://10.100.0.222:8774/v2/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8774/v2/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "nova",
                    "type": "compute"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:9696/",
                            "id": "3f4b6015a2f9481481ca03dace8acf32",
                            "internalURL": "http://10.100.0.222:9696/",
                            "publicURL": "http://8.21.28.222:9696/",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "neutron",
                    "type": "network"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8776/v2/TENANT_ID",
                            "id": "16f6416588f64946bdcdf4a431a8f252",
                            "internalURL": "http://10.100.0.222:8776/v2/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8776/v2/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "cinder_v2",
                    "type": "volumev2"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8779/v1.0/TENANT_ID",
                            "id": "be48765ae31e425cb06036b1ebab694a",
                            "internalURL": "http://10.100.0.222:8779/v1.0/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8779/v1.0/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "trove",
                    "type": "database"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:9292",
                            "id": "1adfcb5414304f3596fb81edb2dfb514",
                            "internalURL": "http://10.100.0.222:9292",
                            "publicURL": "http://8.21.28.222:9292",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "glance",
                    "type": "image"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8777",
                            "id": "350f3b91d73f4b3ab8a061c94ac31fbb",
                            "internalURL": "http://10.100.0.222:8777",
                            "publicURL": "http://8.21.28.222:8777",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "ceilometer",
                    "type": "metering"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8000/v1/",
                            "id": "2198b0d32a604e75a5cc1e13276a813d",
                            "internalURL": "http://10.100.0.222:8000/v1/",
                            "publicURL": "http://8.21.28.222:8000/v1/",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "heat-cfn",
                    "type": "cloudformation"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8776/v1/TENANT_ID",
                            "id": "7c193c4683d849ca8e8db493722a4d8c",
                            "internalURL": "http://10.100.0.222:8776/v1/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8776/v1/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "cinder",
                    "type": "volume"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8773/services/Admin",
                            "id": "11fac8254be74d7d906110f0069e5748",
                            "internalURL": "http://10.100.0.222:8773/services/Cloud",
                            "publicURL": "http://8.21.28.222:8773/services/Cloud",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "nova_ec2",
                    "type": "ec2"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:8004/v1/TENANT_ID",
                            "id": "38fa4f9afce34d4ca0f5e0f90fd758dd",
                            "internalURL": "http://10.100.0.222:8004/v1/TENANT_ID",
                            "publicURL": "http://8.21.28.222:8004/v1/TENANT_ID",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "heat",
                    "type": "orchestration"
                },
                {
                    "endpoints": [
                        {
                            "adminURL": "http://10.100.0.222:35357/v2.0",
                            "id": "256cdf78ecb04051bf0f57ec11070222",
                            "internalURL": "http://10.100.0.222:5000/v2.0",
                            "publicURL": "http://8.21.28.222:5000/v2.0",
                            "region": "RegionOne"
                        }
                    ],
                    "endpoints_links": [],
                    "name": "keystone",
                    "type": "identity"
                }
            ],
            "token": {
                "audit_ids": [
                    "gsjrNoqFSQeuLUo0QeJprQ"
                ],
                "expires": "2014-12-15T15:09:29Z",
                "id": "TOKEN_ID",
                "issued_at": "2014-12-15T14:09:29.794527",
                "tenant": {
                    "description": "Auto created account",
                    "enabled": true,
                    "id": "TENANT_ID",
                    "name": "USERNAME"
                }
            },
            "user": {
                "id": "USER_ID",
                "name": "USERNAME",
                "roles": [
                    {
                        "name": "_member_"
                    }
                ],
                "roles_links": [],
                "username": "USERNAME"
            }
        }
    }"

1 Answer 1

3

If you are using .NET 3.5 or higher on your machines with PowerShell 2.0, you can use a JSON serializer (from the linked answer):

[System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
$json = "{a:1,b:2,c:{nested:true}}"
$ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$obj = $ser.DeserializeObject($json)

This would be preferable to using regex.

For admin URL for example, you'd refer to:

$obj.access.serviceCatalog[0].endpoints[0].adminURL

Using RegEx Anyway

if ($json -match '(?s)"serviceCatalog".+?"endpoints".+?"adminURL"[^"]+"(?<adminUrl>[^"]+)".+?"token".+?"id"[^"]+"(?<tokenID>[^"]+)".+?"tenant".+?"id"[^"]+"(?<tenantID>[^"]+)') {
    $Matches['adminURL']
    $Matches['tokenID']
    $Matches['tenantID']
}

RegEx Breakdown:

  • (?s) tells the regex engine that . matches anything, including newlines (by default it wouldn't).
  • Of course all of the "whatever" parts just match literally.
  • .+? matches 1 or more of any character (including newlines since we're using s), and the ? makes it non-greedy.
  • [^"]+ this matches 1 or more characters that are not a double quote.
  • () is a capturing group. By using (?<name>) we can refer back to the group later by name rather than number, just a nicety.

So the basic idea is to look for the literals, then get to a point where we can capture the values needed. After a -regex operator match in PowerShell, the $Matches variable is populated with the matches, groups, etc.

Note that this relies on the values being in the order they are in the posted JSON. If they were in a different order it would fail.

To work around that you could split this into 3 different regex matches.

Sign up to request clarification or add additional context in comments.

2 Comments

I had a go at this earlier. But got stuck. How would I access the values I need from within the object?
@methuselah I added an example of accessing the object members with the parser.

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.