June 5th, 2018
heart7 reactions

Working with JSON data in PowerShell

Kory Thacher
Premier Field Engineer

Welcome back everyone! This week we will take another look at some common data types we might encounter in the real world: JSON data.

JSON data is used pretty frequently on the web if you’re hitting APIs. This not only includes external data (twitter, weather, marvel database), but often includes internal data to your company. It’s nice to be able to leverage data from anywhere, and it can be frustrating for people to try to parse JSON data.

Luckily, we have this all built in for you using ConvertFrom-JSON

I’ll get a response from an API online used for testing:

$response = Invoke-WebRequest -Uri '<a href="https://jsonplaceholder.typicode.com/users">https://jsonplaceholder.typicode.com/users</a>' -UseBasicParsing

The response data looks like this:

StatusCode : 200
StatusDescription : OK
Content : [
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "[email protected]",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwen...
RawContent : HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Origin, Accept-Encoding
Access-Control-Allow-Credentials: true
Pragma: no-cache
X-Content-Type-Options: nosniff
CF-Cache-...
Forms :
Headers : {[Transfer-Encoding, chunked], [Connection, keep-alive], [Vary, Origin, Accept-Encoding],
[Access-Control-Allow-Credentials, true]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml :
RawContentLength : 5645

And if we check out the “content” property we can see the actual JSON:

[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "[email protected]",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
},
{
"id": 2,
"name": "Ervin Howell",
"username": "Antonette",
"email": "[email protected]",
"address": {
"street": "Victor Plains",
"suite": "Suite 879",
"city": "Wisokyburgh",
"zipcode": "90566-7771",
"geo": {
"lat": "-43.9509",
"lng": "-34.4618"
}
},
"phone": "010-692-6593 x09125",
"website": "anastasia.net",
"company": {
"name": "Deckow-Crist",
"catchPhrase": "Proactive didactic contingency",
"bs": "synergize scalable supply-chains"
}
},
{
"id": 3,
"name": "Clementine Bauch",
"username": "Samantha",
"email": "[email protected]",
"address": {
"street": "Douglas Extension",
"suite": "Suite 847",
"city": "McKenziehaven",
"zipcode": "59590-4157",
"geo": {
"lat": "-68.6102",
"lng": "-47.0653"
}
},
"phone": "1-463-123-4447",
"website": "ramiro.info",
"company": {
"name": "Romaguera-Jacobson",
"catchPhrase": "Face to face bifurcated interface",
"bs": "e-enable strategic applications"
}
},
{
"id": 4,
"name": "Patricia Lebsack",
"username": "Karianne",
"email": "[email protected]",
"address": {
"street": "Hoeger Mall",
"suite": "Apt. 692",
"city": "South Elvis",
"zipcode": "53919-4257",
"geo": {
"lat": "29.4572",
"lng": "-164.2990"
}
},
"phone": "493-170-9623 x156",
"website": "kale.biz",
"company": {
"name": "Robel-Corkery",
"catchPhrase": "Multi-tiered zero tolerance productivity",
"bs": "transition cutting-edge web services"
}
},
{
"id": 5,
"name": "Chelsey Dietrich",
"username": "Kamren",
"email": "[email protected]",
"address": {
"street": "Skiles Walks",
"suite": "Suite 351",
"city": "Roscoeview",
"zipcode": "33263",
"geo": {
"lat": "-31.8129",
"lng": "62.5342"
}
},
"phone": "(254)954-1289",
"website": "demarco.info",
"company": {
"name": "Keebler LLC",
"catchPhrase": "User-centric fault-tolerant solution",
"bs": "revolutionize end-to-end systems"
}
},
{
"id": 6,
"name": "Mrs. Dennis Schulist",
"username": "Leopoldo_Corkery",
"email": "[email protected]",
"address": {
"street": "Norberto Crossing",
"suite": "Apt. 950",
"city": "South Christy",
"zipcode": "23505-1337",
"geo": {
"lat": "-71.4197",
"lng": "71.7478"
}
},
"phone": "1-477-935-8478 x6430",
"website": "ola.org",
"company": {
"name": "Considine-Lockman",
"catchPhrase": "Synchronised bottom-line interface",
"bs": "e-enable innovative applications"
}
},
{
"id": 7,
"name": "Kurtis Weissnat",
"username": "Elwyn.Skiles",
"email": "[email protected]",
"address": {
"street": "Rex Trail",
"suite": "Suite 280",
"city": "Howemouth",
"zipcode": "58804-1099",
"geo": {
"lat": "24.8918",
"lng": "21.8984"
}
},
"phone": "210.067.6132",
"website": "elvis.io",
"company": {
"name": "Johns Group",
"catchPhrase": "Configurable multimedia task-force",
"bs": "generate enterprise e-tailers"
}
},
{
"id": 8,
"name": "Nicholas Runolfsdottir V",
"username": "Maxime_Nienow",
"email": "[email protected]",
"address": {
"street": "Ellsworth Summit",
"suite": "Suite 729",
"city": "Aliyaview",
"zipcode": "45169",
"geo": {
"lat": "-14.3990",
"lng": "-120.7677"
}
},
"phone": "586.493.6943 x140",
"website": "jacynthe.com",
"company": {
"name": "Abernathy Group",
"catchPhrase": "Implemented secondary concept",
"bs": "e-enable extensible e-tailers"
}
},
{
"id": 9,
"name": "Glenna Reichert",
"username": "Delphine",
"email": "[email protected]",
"address": {
"street": "Dayna Park",
"suite": "Suite 449",
"city": "Bartholomebury",
"zipcode": "76495-3109",
"geo": {
"lat": "24.6463",
"lng": "-168.8889"
}
},
"phone": "(775)976-6794 x41206",
"website": "conrad.com",
"company": {
"name": "Yost and Sons",
"catchPhrase": "Switchable contextually-based project",
"bs": "aggregate real-time technologies"
}
},
{
"id": 10,
"name": "Clementina DuBuque",
"username": "Moriah.Stanton",
"email": "[email protected]",
"address": {
"street": "Kattie Turnpike",
"suite": "Suite 198",
"city": "Lebsackbury",
"zipcode": "31428-2261",
"geo": {
"lat": "-38.2386",
"lng": "57.2232"
}
},
"phone": "024-648-3804",
"website": "ambrose.net",
"company": {
"name": "Hoeger LLC",
"catchPhrase": "Centralized empowering task-force",
"bs": "target end-to-end models"
}
}
]

This contains 10 fake users. If we want this data to be more usable we can parse the response directly using ConvertFrom-JSON:

$users = $response | ConvertFrom-Json

$users | FT

id name username email address
-- ---- -------- ----- -------
1 Leanne Graham Bret [email protected] @{street=Kulas Light; suite=Apt. 556; city=Gwenbo...
2 Ervin Howell Antonette [email protected] @{street=Victor Plains; suite=Suite 879; city=Wis...
3 Clementine Bauch Samantha [email protected] @{street=Douglas Extension; suite=Suite 847; city...
4 Patricia Lebsack Karianne [email protected] @{street=Hoeger Mall; suite=Apt. 692; city=South ...
5 Chelsey Dietrich Kamren [email protected] @{street=Skiles Walks; suite=Suite 351; city=Rosc...
6 Mrs. Dennis Schulist Leopoldo_Corkery [email protected] @{street=Norberto Crossing; suite=Apt. 950; city=...
7 Kurtis Weissnat Elwyn.Skiles [email protected] @{street=Rex Trail; suite=Suite 280; city=Howemou...
8 Nicholas Runolfsdottir V Maxime_Nienow [email protected] @{street=Ellsworth Summit; suite=Suite 729; city=...
9 Glenna Reichert Delphine [email protected] @{street=Dayna Park; suite=Suite 449; city=Bartho...
10 Clementina DuBuque Moriah.Stanton [email protected] @{street=Kattie Turnpike; suite=Suite 198; city=L...

Now we could do whatever we want with these users

foreach ($user in $users)

{

write-host "$($user.name) has the email: $($user.email)"

}
Leanne Graham has the email: [email protected]

Ervin Howell has the email: [email protected]

Clementine Bauch has the email: [email protected]

Patricia Lebsack has the email: [email protected]

Chelsey Dietrich has the email: [email protected]

Mrs. Dennis Schulist has the email: [email protected]

Kurtis Weissnat has the email: [email protected]

Nicholas Runolfsdottir V has the email: [email protected]

Glenna Reichert has the email: [email protected]

Clementina DuBuque has the email: [email protected]

So there you have it, working with JSON data can be easy once you turn it into PowerShell objects. Hopefully this helps you work with APIs and process data on your PowerShell adventures.

If you like the content don’t forget to rate, comment and share!

Author

Kory Thacher
Premier Field Engineer

I've been a PFE since 2012, working with various technologies. I live in the modern applications domain, doing work in UWP apps, .NET, Unity, DevOps, and of course PowerShell. I've been teaching PowerShell related workshops very frequently for years, and I really enjoy getting the opportunity to explain a topic or learn something new from my colleagues. I enjoy scripting because of how fast and interactive it can be, and I love getting interesting problems to work on with customers. ...

More about author

1 comment

Discussion is closed. Login to edit/delete existing comments.

Sort by :
  • Paul Watson

    The first request did not work for me as it contains XML code. This worked.

    $response = Invoke-WebRequest -Uri 'https://jsonplaceholder.typicode.com/users' -UseBasicParsing

    Please show how to do something with the ‘address’ member.