Nested objects are very useful as they can give you a way to store complex data. The featured image of this blog is of a nested temple. Each room is nested on top of the other. What’s cool about this image is each room has items inside of it. For example, there a water bottle. Think of nested arrays like this. The full thing is a temple. That is the first object. Then we have small buildings inside that. Those are our secondary objects. Those secondary objects also have properties. So imagine the roof being the second object’s properties. Inside each building there are rooms. Those are our third objects. What’s in those rooms are the properties of those rooms. Then you can have a chest that could be a fourth object and it could have its own properties. As you can tell, this can get confusing quickly. Parsing through that data can be a challenge. Below we will go through the process of adding display names to the account SKU for the licenses for each user. We do this for later reporting. There are a few things you will need before we start.

  1. MSonline module
  2. SKU file that can be found here
  3. A Microsoft account with users
  4. An at least read-only account.

The Setup

You will need to be doing all of the following commands on PowerShell Version 5 because MSOnline does not work on PowerShell 7 yet.

Install-Module MSOnline -force
Import-module MSOnline

Now you need to connect to the Microsoft Online account. You can do this by using the connect-msolservice. Make sure you have the credentials required.

$Users = Get-MsolUser -all

Now download the list here. You will need to import the file into PowerShell. You can do this with the Import-CSV command. Inside this list, you can add what you want and so on and so forth.

Add the Add to Licenses

Now we have the array built, it’s time to start learning something cool. The goal is to add the display name of the Account SKU inside the licenses area of each user. This way when you see the licenses you know what you are looking at later. More importantly, this will teach you how to place information directly into an array instead of rebuilding the array.

For vs Foreach

I love foreach, it helps so much. foreach ($user in $users) is nice. This is great for rebuilding an array because you can push the information into another array easily like this. Great for a full rebuild. However, in our world we want to put the data directly into the array itself. The Foreach creates a temporary object based on the object that is inside the array. So it creates a “User” based on the “Users.” Thus, doing $user | add-member doesn’t stay. I tried this a few hundred times. So, the for loop is going to be our friend. The reason for this is you can say where in the original loop you want to go to. Lets start the loop shall we.

The Script

for (($I = 0); $I -lt $Users.count; $I++ ) {
    if ($Null -ne $Users[$I].Licenses) {
        for (($A = 0); $A -lt $Users[$I].Licenses.count; $A++) {
            $Los = $Users[$I].Licenses[$A].AccountSkuID
            $Lose = $SKU | where-object { $_.SKU -like $Los }
            if ($Null -ne $Lose) {
                $Users[$I].Licenses[$A] | Add-Member -MemberType NoteProperty -Name "LiceDisplayName" -Value $Lose.Name
            }
            else {
                $Users[$I].Licenses[$A] | Add-Member -MemberType NoteProperty -Name "LiceDisplayName" -Value "N/A"
            }
        }
    }
}

The first part is the for loop. We start the loop at 0. ($I = 0) we start at 0 because arrays start at 0. Then we will continue this loop while $I is less than the total user count. Each loop will increase the $I by 1 using the $I++. This is a basic for loop setup. This will give us the index of the users. The next step is the test to see if the user has licenses.

if ($Null -ne $Users[$I].Licenses) {}

A few things with this if statement. First the $Null is on the left. The reason for that is because we evaluate nothing first. Then if the next thing even has something in it, it triggers right off the bat. If it doesn’t, then we else out. Thus, having $Null on the left is faster. Next notice the $Users[$I]. This is basically we want the Object at index of $I. Each time the loop process, that $I increases. Thus, we go through the loop. Finally we are looking at the .Licenses. If It doesn’t have a licenses, we don’t want to evaluate anything. We will leave this alone. Now if it does, then we get to have our fun. Normally users have more than one license inside their profile. Thus, we have more than one loop.

for (($A = 0); $A -lt $Users[$I].Licenses.count; $A++) {}

Now notice, I replaced $I with $A, but I changed up the condition. If $A is less than the current index of $users licenses count. Then we increase $A by 1 with the $A++. Now we are within the user array within a user and evaluating licenses. We are going deep.

$Los = $Users[$I].Licenses[$A].AccountSkuID
$Lose = $SKU | where-object { $_.SKU -like $Los }

So here we are grabbing that AccountSkuID with our $Los variable. Then we compare from our Imported $SKUs we downloaded and imported earlier. We place that inside the $Lose value. So now we have the Displayname and the SKU name.

To prevent any errors, we check $Lose to see if it’s null. I it is, then we want to place the information into it differently. This way later when we look at the data we don’t get some odd errors.

if ($Null -ne $Lose) {}

Finally the meat and potatoes of why we are here. We want to add that Display name for that sku. So let’s do that. We want the current $I user. We want the current $A licenses. Once we have both of those, we want to use add-member to add a note property. We want to name it something different than just DisplayName because that is everywhere. So, I like to use smaller names. I used $Lice. You can use Displayname, or not. I’m just odd.

$Users[$I].Licenses[$A] | Add-Member -MemberType NoteProperty -Name "LiceDisplayName" -Value $Lose.Name

As we loop through this process, it will add the Display name to each license inside the array. This way you can report on it later. In the else part of our test, we place the note property name the same but the value would be “N/A” or something along those lines. As long as it’s not null, we are safe. Below is a visual that might help understand how this loop works. The User object (Black) is the I. The LIcenses are multi-color. A. All of it lives within the User Array which is Purple.

If you have any questions, please feel free to reach out.