Windows PowerShell Tutorial 3 - Variables

Variables: What is a Variable? How to create a Variable. How to use a Variable.



  1. Regedit32
    Just as in any coding language, PowerShell makes use of Variables.

    Generally, Variables are created by the Programmer, but again, as in other popular Programming Languages there are some reserved Variable names that all ready exist which a User cannot use for anything other that its hard coded purpose. More on that later.

    What is a Variable?

    Variables are in essence a label assigned by the programmer to store data which will be used during the Scripts execution.

    Typically, a Variable will be given a name that reflects the type of data it will be storing (although this is not compulsory), as when reviewing a Scripts code it is often easier to analyze when Variables names are descriptive.

    The Variable name will usually be in the format of lowercase first name, followed by Sentence-cased words should the programmer be using a very descriptive name for their variable. Again this format style is not compulsory, but is a fairly well accepted convention among programmers world-wide.

    For example:

    $thisIsAVariableToStoreMyComputerName = $env:ComputerName

    The above is a perfectly valid if somewhat ludicrous lengthy name for a Variable that ultimately is storing information taken from the right side of the = sign. The first word in the example is lowercase, with each preceding word in the name in Sentence-case (i.e. Starting with an UPPERCASE letter then continuing with lowercase letters).

    PS10.png
    Sample image showing creation of variable then its execution in Windows PowerShell ISE

    If you prefer, Variable names can also be completely in lowercase, or completely in UPPERCASE. The following examples will all work, as will variations on them (provided of course there are no spaces in the label).
    • $annual_Income
    • $Annual_Income
    • $annual_income
    • $ANNUAL_Income
    • $annual_INCOME
    • $ANNUAL_INCOME
    If you are wondering, 'Why do we even call these Variables?' well that is because in programming a Variable can store all types of data, but this data can change, or more to the point, be changed during the execution of the program, hence the information being stored in a Variable can vary, hence the name,Variable

    You can create Variables that are fixed and their data cannot be varied, but that is something I'll touch on in a later tutorial as it is beyond the scope of this brief introduction.

    What types of Variables can we have and How are Variables created?

    In PowerShell, Variables are prefixed with a $ symbol and by doing this PowerShell Scripts are then able to both reference and/or dereference a particular Variable. For those of you familiar with programming in C you will recall the asterisk symbol * was used for this purpose.

    So we start with a $ symbol, then use a label, e.g. $hourlyRate

    Note: You cannot use a space between the labels words!
    • $hourlyRate is fine.
    • $hourly_Rate is also fine.
    • $hourly Rate is not fine! Spaces are not permitted!

    As already alluded to earlier, Variables can store many types of Data:
    • Chars
    • Strings
    • Integers
    • Doubles
    • Arrays
    • Hash Tables
    • Objects
    Char variables will store a single character, which could be a letter, digit or symbol.

    String variables typically store a series of letters that form either a single word, or a sentence, but can also store a mix of letters, digits and symbols, or even the content of another variable.

    Integer variables store a whole number which can be either negative or positive.

    Double variables store numbers with a decimal place. They can be negative or positive.

    Arrays store a sequence of variables, each of which is referenced by an Integer index which starts at index[0], index[1], ... index[n -1], when n is the number of indexed positions stored.

    Technically a String variable is an array, so if for example we said:

    $myName = "Regedit32" then the newly created Variable is now storing 'Regedit32' which contains 9 characters, each stored in their own indexed position, with R beginning at index[0] and 2 at index[9-1], or index[8]

    Thus having created the variable and assigned it a value, if I now typed:

    $myName[7] then pressed Enter key I'd see the character 3 appear on the next line of console as this is the character stored in the indexed position [7] of the current [String] Variable.

    Hash Tables store data in pairs, similar to an Array which allows specific data to be matched.

    Note: Hash Tables are also known as Dictionaries so if reading about this topic online you will know if you see the term Dictionary they are probably talking about Hash Table variables.

    Objects typically store complex data (i.e. more than one piece of information, and thus more than one Variable). That means it can store Variables that are storing different data types too!

    Examples of an Object using complex data that you may write a Script to manipulate are, Windows Defender Security Center, Windows Event Manager, Windows Services, Windows Processes, Microsoft Edge, Browsers, Webpages, Windows Update Service, Windows Registry, Group Policies, XML containers, etcetera.

    The point being an Object can be storing data for literally any thing you can think of, from an orange to something actually useful in terms of Scripting for Windows 10, and that data could contain a mix of variables storing words, numbers, symbols, binary, hexadecimal, ASCII, etcetera.

    How to use Variables

    OK, so we now know the types of Variables we can create, but how do we use them, and more importantly how do we declare then to begin with.

    In PowerShell, as already stated, a Variable is prefixed with a $ Symbol, but that in itself while fine, does not necessary mean a lot to someone reading your Script, and more importantly, what is assigned the Variable (i.e the type of data being assigned) can affect what a Variable becomes.

    To illustrate this, lets take a look at a simple demonstration using three variables to perform an addition and produce a sum.

    PS11.png

    Example of Addition using Windows PowerShell ISE

    Can you spot the problem with two of these examples?

    In examples 1 and 2, I used double and single speech marks to declare the data type being assigned to my variables $number1, $number2, and $sum. This resulted in the computer believing I was assigning a String data type, and thus, my three variables that are supposed to contain an Integer, not a String, produced the incorrect result for the Sum of the two variables.

    In the third sample you can see I removed the speech marks, and now the computer understands I intend that $number1, $number2, and $sum variables to be Integers.

    I see you asking yourself, but how can the + add two Strings? Well that is because when you use the + sign with Strings this is interpreted to mean concatenate (which is to join item on left side of + with the item on right side.

    When the + is used with real numbers, be they Integers or Doubles, then the + symbol is interpreted as Addition (i.e. to add the item on left of + to item on right side).

    Thus in the first two examples, because the speech marks were interpreted to be surrounding a String, the code is actually saying:

    Concatenate String $number1 to String $number2 and store result in String $sum

    i.e. String 6 joined to String 7 results correctly in String 67

    That may seem a little confusing, because often in programming we envelop that which is to be assigned to a Variable within speech marks, but that does not necessarily mean we want it interpreted as a String, so how do we get around this.

    The answer is to declare by casting what the Variable is before assigning it the data to be stored inside it. In PowerShell we cast a Variable type inside [ ] brackets.

    Instead of typing $number1 = 6 to create an Integer variable, do this instead:
    • [int] $number1 = "6"
    The [int] instructs the computer that the Variable following will be an Integer.

    As a result I can now use speech marks around the data I intend to assign the Integer Variable.

    Thus the previous code can now be written as:

    Code (PowerShell):
    [int] $number1 = "6"
    [int] $number2 = "7"
    [int] $sum = $number1 + $number2
    Clear-Host
    Write-Host $number1 + $number2 = $sum

    Likewise, if we wish to work with doubles that being a real number whose fractional portion is represented by a decimal, e.g 4.5, we can cast [double] as we declare our variable.

    This could look like this for example:

    PS12.png

    On a side note, you will notice I used `$ when assigning the String to write to the console. This is because the grave symbol ` escapes the character $ which otherwise would be interpreted as a pretext for a Variable.

    I'll discuss these escapes in another tutorial as there are several you can use.

    You can see to multiply two values you need to use the asterisk * which is just the same as in any other programming language.

    The operators for basic math equations when programming are:

    • + for addition, e.g. $num + $num2
    • - for subtraction, e.g. $num - $num2
    • / for division, e.g. $num / $num2
    • * for multiplication, e.g. $num * $num2
    • You can also use the - to make a Variable a negative, e.g. -$num + $num2
    PS13.png
    While [int] $num equals positive 5, by adding the - before the variable you can make it negative 5 and thus -5 + 10 = 5

    Note: After initially declaring a variable as [int], [double], [string], etcetera, you do not need to keep prefixing these casts as you can see above, because that information is stored in memory and will not be lost, unless you choose to cast a different data type.

    For example you could take [double]$num = 3.6, then later cast [int] to the variable like so:

    PS14.png

    Note though the double value will be rounded to the nearest Integer value.

    To prevent confusion, you do not need the `n but I am using this to force a new line so you can easily ready the result, otherwise, there would be no space between 4 and PS C:\Users\Regedit32>

    Clear-Host is a Cmdlet that clears the lower console before writing to it again. Again, this is not needed, I'm just doing it here to make it easy to see the results of the script code. By the way, Clear-Host has two Aliases. You can type CLS or Clear to achieve the same thing in the console. The aliases are not case sensitive thus you can also type cls or clear.

    String Variables are simple to declare:
    • $str = "Dog" creates a String Variable storing the word dog.
    • [String] $str = "Dog" does exactly the same thing.
    You do not need to cast [String] here but you can use this cast to take a non String variable and turn it into a String. Let's take a look at an example of this:

    PS15.png

    In the above example, I took the Integer $bigNumber and assigned it to two new variables, $num (an Integer variable), and $num2 (a String variable).

    Below in the console you can see typing $num or $num2 produced identical results, but when typing $num[4] versus $num2[4] the results differed, because if you recall a String variable is actually a very basic Array, and arrays index each character from 0 to (length of array - 1), thus we get the result of 5 which is located in indexed position [4] of the [String] $num2 variable.

    Being able to do this can prove very handy when programming.

    Note: You can also use single speech marks when declaring a String, for example:
    • $str = 'Dog'
    Personally, I prefer to use double speech marks " ", but this is entirely up to you.

    Another example of combining String Variables with Cmdlets, allows us to interact with the User. Take a look at the following example:

    PS16.png

    By interacting with User we are able to store what they type into a Variable. We could store their age into an Integer, or Address into an [String] Array, or a Hash Table etcetera.

    Another thing you can do when reviewing Script code is identify what type of Variable you are dealing with, which can be helpful, if the person who programmed the Script gave the variable a non descriptive name, and/or left no comments as to what type of data the variable stores.

    To find out what type of variable it is, you simply type in the console the name of the variable and append to that .getType().Name then press Enter key

    PS17.png
    We identity that $mystery is a [String] variable in above example

    What if you want to store multiple lines of text into a single [String] variable?

    There are a few ways you can approach this as Microsoft anticipated different programmers may use differing styles when programming a multi-line String.

    Below are some ways to achieve this:

    Using multiple lines surrounded by a single pair of speech marks
    PS18.png


    Using instead the special escape
    `n to force a new line
    PS19.png

    This time if we choose to tidy up the style of code it will not cause the multiple lines to tab over into an ugly display.


    Arrays
    are a slightly different way to store Strings, Numbers, or Objects. They are very easy to create. If for example you wish to create an array of animal names, which are Strings, then you can do this in one of two ways:
    • $animalNames = ( "Dog", "Cat", "Duck", "Giraffe" )
    • [Array] $animalNames = "Dog", "Cat", "Duck", "Giraffe"

    Arrays are indexed from 0 to the last item in the array, so in the above examples as we have four items, the indexed positions are [0], [1], [2], [3] which means if we were to run the Array then type $animalNames[2] and press Enter, the result returned would be Duck as this is located at index position [2].

    You may recall earlier I used the term dereference and this is precisely what that is:
    • $animalNames[2] is a dereference to the animal name stored in index [2]

    When we are programming a loop to run through each item in an array, we want to make use of the .Length method. The Length of an array is the number of items in the array. So in the case of the above examples, the Length is 4 as there are 4 animal names stored in the array.

    To get the length of an Array we append the method to the variable like so:
    • $animalNames.Length
    PS20.png
    The method .Length appended to the [Array] $animalNames returns how many items are in the Array. In this case 4.
    If we want to write a loop that will check each item and write to the console that items name we need to first create some Integer variables, then factor in the fact that while the Array Length is X size, because each item is indexed, starting from position 0, then our loop must stop at (Length - 1), otherwise we will get an out of bounds exception, because the loop would go on trying to read a position outside the bounds of the Array.

    PS21.png
    The above example has comments in the script to help you understand what is happening. In PowerShell Scripts anything to the right of #, and on same line becomes a comment and normally would not be seen on console, unless analyzing the code as we are here.

    We can also populate an Array by calling Cmdlets such as Get-ChildItem like so:

    Code (PowerShell):
    CD $env:WinDir
    [Array] $windows = Get-ChildItem
    This stores each object located in the C:\Windows directory to the Array $windows

    Now if we add a loop to the code we can write the object names, and get a count of how many objects exist in C:\Windows.

    PS22.png

    Hash Tables (also known as Dictionaries) allow us to create a type of array that stores two pieces of information. For example we could create a Hash Table to store City names and their population.

    To do this we use @{ } with the names inside " ", and the population assigned following an = sign, with each pair separated by a semi-colon. Take a look at the example below:

    PS23.png
    Above example uses the escape ` character to allow the comma to format the population values

    You can add an additional city to your Hash Table by appending the .Add method:
    • $cityPopulationsNZ.Add("Incercargill","79`,000")
    • Note the slightly different method here. No = sign used in this method!

    You can remove a city from your Hash Table by appending the .Remove method:
    • $cityPopulationsNZ.Remove("Invercargill")
    • Note the slightly different method here. Only name of city needed!
    PS24.png

    Well that is all for now. In the next tutorial we'll be looking at Pipelines and how to Manage Output to the console.

    Regards,

    Regedit32
    JAY B., Ian and Trouble like this.