Variables, and More About Note Properties

I have been thinking a lot about variables and note properties recently. You know that, if you read A Better Way to Solve the Same Problem. It sets the stage for what we are going to see today. The question that started that post was, whether or not I could add note properties to a single variable, such as PowerShell does with the $PROFILE variable. I could. I ended up creating a variable that held one URL when you returned the variable but also held four other URLs, one in each additional note property.

I want to take this further, and the best part is that all the things I was worried about trying to do myself, PowerShell just does for me without any thinking about it. Follow along and you will see.

Let’s set up the variable I was using last time to help this recap. Then we will create another variable and work with it to explore some new things I learned. Building this variable is being done a little differently than it was previously. It incorporates some concepts from another recent post, There is a Difference: Arrays Versus Hash Tables. First, we will assign our initial value to the variable.

$PSSites = 'https://docs.microsoft.com/en-us/powershell/scripting/overview'

Next, we will create a hash table that includes four key-value pairs. Each pair includes a website name and an associated URL, because as we learned in that post, a hash table is an associative array.

$Sites = @{
    GitHub  = 'https://github.com/PowerShell/PowerShell'
    Docs    = 'https://docs.microsoft.com/en-us/powershell/'
    Gallery = 'https://www.powershellgallery.com/'
    Reddit  = 'https://www.reddit.com/r/PowerShell/'
}

Following that, we will use the foreach statement to loop through the key-value pairs in the hash table, running Add-Member against each of them, and thusly adding each as a note property on our $PSSites variable.

foreach ($Site in $Sites.GetEnumerator()) {
    $PSSites = $PSSites | Add-Member -NotePropertyName $Site.Key -NotePropertyValue $Site.Value -PassThru
}

We can use Get-Member to ensure the previous command added the additional URLs as note properties.

$PSSites | Get-Member -MemberType NoteProperty

   TypeName: System.String

Name    MemberType   Definition
----    ----------   ----------
Docs    NoteProperty string Docs=https://docs.microsoft.com/en-us/powershell/
Gallery NoteProperty string Gallery=https://www.powershellgallery.com/
GitHub  NoteProperty string GitHub=https://github.com/PowerShell/PowerShell
Reddit  NoteProperty string Reddit=https://www.reddit.com/r/PowerShell/

At this point, we have our own variable like the $PROFILE variable that contains multiple string values. We can access the note properties of $PSSites using dot notation.

$PSSites.GitHub
$PSSites.docs
$PSSites.Gallery
$PSSites.Reddit

https://github.com/PowerShell/PowerShell
https://docs.microsoft.com/en-us/powershell/
https://www.powershellgallery.com/
https://www.reddit.com/r/PowerShell/

Now, let’s create another variable and add some members to it, as well. These will be a little different and you will see that momentarily. We will start by assigning a string value to the variable, as we did above.

$TestingVariable = 'A string value'
$TestingVariable
A string value

Before we add the rest, I suppose I should remind everyone about my end goal written at the bottom of the first post linked above: Save the previous value of a variable to a note property when assigning a new value to the variable itself.

This would be much easier if we could guarantee that every new value assigned to the variable was a string, and therefore, every old value property would also be a string. My worries, as mentioned earlier, were about arrays, hash tables, ordered dictionaries, and other data structures I may have to save to a note property. Can other data structures like those be put in a note property? Let’s work through these data structures and see if we can get them into note properties, to begin with. In this example, we will add two arrays to two separate note properties, as Array01 and Array02. One of these will and one will not use the array, sub-expression operator (@()).

$TestingVariable = $TestingVariable | Add-Member -NotePropertyName 'Array01' -NotePropertyValue 1,2,3 -PassThru
$TestingVariable = $TestingVariable | Add-Member -NotePropertyName 'Array02' -NotePropertyValue @(4,5,6) -PassThru

Here, we will create a hash table and store it in the $HashTable variable. We will then use that variable as a part of another Add-Member command.

$HashTable = @{Dad = 'David'; Mom = 'Betty'; Daughter = 'Janice'; Son = 'Bryan'}
$TestingVariable = $TestingVariable | Add-Member -NotePropertyName 'HashTable' -NotePropertyValue $HashTable -PassThru

Finally, we’ll create an ordered dictionary and add it as a note property, as well. If the hash table takes, then it is probably safe to assume this will take, too.

$OrderedDictionary = [ordered]@{
    Monday    = 'Chipotle'
    Tuesday   = 'Pizza'
    Wednesday = 'Mahi Mahi';
    Thursday  = 'Ravioli'
    Friday    = 'Orange Chicken'
}
$TestingVariable = $TestingVariable | Add-Member -NotePropertyName 'OrderedDictionary' -NotePropertyValue $OrderedDictionary -PassThru

At this point, we should probably see what Get-Member returns about the note properties we have assigned to our $TestingVariable. We have yet to test that anything has actually been added so far, although we have not received any errors stating otherwise. In the below example, we can see the four, note properties that we have added. The best part, the definition property indicates it knew the data structure of these when they were added as note properties. The arrays show object[], the hash table, hashtable, and the ordered dictionary, OrderedDictionary.

$TestingVariable | Get-Member -MemberType NoteProperty

   TypeName: System.String

Name               MemberType   Definition
----               ----------   ----------
Array01            NoteProperty Object[] Array01=System.Object[]
Array02            NoteProperty Object[] Array02=System.Object[]
HashTable          NoteProperty hashtable Hash Table=System.Collections.Hashtable
OrderedDictionary  NoteProperty OrderedDictionary Ordered Dictionary=System.Collections.Specialized.OrderedDictionary

Let’s take a closer look at each of our new note properties. For each of them, we will run GetType() against the note property and then return the value it has stored. When we return a note property that contains an array, it returns that. Same for the others; the data structure was recognized and retained when it was added as a member. And it is respected on the way out, too. I cannot tell you how grateful I am that I do not have to be the one to figure out the underlying data structure of a value going in and then coming back out. This is great news for some of the other things I have planned.

$TestingVariable.Array01.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

$TestingVariable.Array01
1
2
3

$TestingVariable.Array02.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

$TestingVariable.Array02
4
5
6

$TestingVariable.HashTable.GetType()       

IsPublic IsSerial Name                                     BaseType     
-------- -------- ----                                     --------     
True     True     Hashtable                                System.Object

$TestingVariable.HashTable

Name                           Value
----                           -----
Daughter                       Janice
Son                            Bryan
Dad                            David 
Mom                            Betty

$TestingVariable.OrderedDictionary.GetType()

IsPublic IsSerial Name                                     BaseType      
-------- -------- ----                                     --------      
True     True     OrderedDictionary                        System.Object 

$TestingVariable.OrderedDictionary

Name                           Value
----                           -----
Monday                         Chipotle
Tuesday                        Pizza
Wednesday                      Mahi Mahi
Thursday                       Ravioli
Friday                         Orange Chicken

Leave a Reply

Your email address will not be published. Required fields are marked *