Variables, Arrays, and Hash Tables

PowerShell Tutorial 7: Accumulate, Recall, and Modify Data


In this PowerShell training session we are going to discuss storing, retrieving, and manipulating data within PowerShell. PowerShell enables us to store information using the following methods:

  • Variables – allows us to store single bits of information.
  • Arrays – allows us to store information in an index.
  • Hash Table – allows us to store in key-value pairs.

Launch PowerShell and let’s get started…

PowerShell Variables

Think of a variable as an imaginary box where we store information. Two basic uses of variables are:

  • Store information that will be later utilized within a script.
  • Store information that is a result of running a script.

In PowerShell, variables can contain text strings, integers, and even objects (complete with properties and methods). Special variables exist, which are pre-defined within PowerShell. We have worked with one of these variables ($_) in a prior tutorial.

Special Variable Examples

  • $_ – Contains the current pipeline object, used in script blocks, filters, and the where statement.
  • $Args – Contains an array of the parameters passed to a function.
  • $Error – Contains objects for which an error occurred while being processed in a cmdlet.
  • $Home – Specifies the user’s home directory.
  • $PsHome – The directory where the Windows PowerShell is installed.

To view the complete list of Special Variables in PowerShell, type the following:

Get-Help about_automatic_variables<enter>

In VBScript, we have to declare variables before using them. For example:

dim strComputer
dim strUser
dim intDate
strComputer = “MyComputer”
etc…

In PowerShell, ALL variable names must start with the “$” character. Once data is assigned to a PowerShell variable, it’s automatically declared. The “=” operator is used to assign data to a variable. Here is a simple example of creating a variable in PowerShell:

$strComputer = “Computer1″<enter>

There is a “Set-Variable” cmdlet that can also be used:

Set-Variable -Name strUser -Value “John Doe”<enter>

You can use virtually any variable name you choose, names are not case sensitive. Note: there are illegal characters such as; ! @ # % & , . and spaces. PowerShell will throw an error if you use an illegal character.

I stated virtually any name as PowerShell does have a set of keywords that are reserved and cannot be used as variable names:

  • break
  • continue
  • do
  • else
  • elseif
  • filter
  • foreach
  • function
  • if
  • in
  • return
  • switch
  • until
  • where
  • while

When naming variables, I continue to use the caMel case naming convention I became accustomed to in VBScript. The first part of the name (str) reminds me that the variable I’m working with contains “text string” data. If I were working with numbers, it might look like something this “$intMegaBytes.” Again, you can use any naming convention you wish.

Let’s verify that the $strComputer variable is holding the data we assigned to it.

Write-Output $strComputer<enter>

-or just type-

$strComputer<enter>
PowerShell Tutorial - strComputer

$strComputer Variable

image 7.0

The output verifies the data in the $strComputer variable is the “Computer1″ text string. Go ahead and verify the data value for the “strUser” variable.

$strUser<enter>

Did you get John Doe for the output? Yes… great! No?… I knew you were going to skip the long version of using the “Set-Variable” cmdlet.

Note: If you use the “Set-Variable” cmdlet and specify the -Name parameter, you do not use the “$” character when defining variables. Most of the time I use ($strComputer = “computerName”) to create variables. Just be conscious of this rule when using the “Set-Variable” cmdlet.

Working with Strings

A [sting] is a “text string” data type. There are many data types that we will be working with in PowerShell:

Type Description
[int] 32-bit signed integer
[long] 64-bit signed integer
[string] Fixed-length string of Unicode characters
[char] A Unicode 16-bit character
[byte] An 8-bit unsigned character
[bool] Boolean True/False value
[decimal] An 128-bit decimal value
[single] Single-precision 32-bit floating point number
[double] Double-precision 64-bit floating point number
[xml] Xml object
[array] An array of values
[hashtable] Hashtable object

Yep, we will be discussing them all at some point…

String Concatenation

Concatenation is the process of joining together two strings. Here is an example:

$strA = “Hello “<enter>
$strB = “World!”<enter>
$strC = $strA += $strB<enter>
$strC<enter>

We used += to join together variables $strA and $strB and store the new “text string” in variable $strC. The output from $strC is Hello World!

Most of the time you will see two strings joined together by using just the “+” operator. Like so; $strC = $strA + $StrB. Both result in the same output.

Aside from joining strings we can also replace words using the -replace parameter.

$strA = “Go east young man!”<enter>
$strB = $strA -replace “east”, “west”<enter>
$strB<enter>

Go west young man!

What the heck is Interpolation?

Quotes are used when working with string data, either double-quotes(” “) or single-quotes(‘ ‘). What’s the difference? Glad you asked… It’s called Interpolation. As stated at the beginning of this PowerShell training session, variables are stored for later use. Interpolation occurs when a string variable is enclosed in double-quotes and does not occur when single-quoted. Let me give you an example of what this means:

$strA = “fast”<enter>
Write-Host “Tom drives a $strA car.”<enter>

By double-quoting, the output of the “Write-Host” cmdlet is – Tom drives a fast car. This is interpolation, PowerShell substitutes the value of variable $strA. Let’s see what happens when using single-quotes:

$strA = “fast”<enter>
Write-Host ‘Tom drives a $strA car.’<enter>

Output – Tom drives a $strA car.
PowerShell does not substitute the variable.

Working with Numbers

PowerShell works with a number of data types, for example integers(9) and decimals (9.9). The PowerShell engine can automatically recognize the data type assigned to a variable. For example, it knows that $x = 1 is an integer data type. It also knows that $x = “Hello World!” is a string data type.

Assigning integer and decimal values are simple:

$x = 1<enter>
$y = 1.2<enter>
$x<enter>
$y<enter>

There are those rare occasions when PowerShell may have not assigned the proper data type to a variable, causing havoc with your script. Though it is not required, it is considered good form to assign the data type of a variable. Refer to the data type table presented earlier in the tutorial. Here are some examples:

[string]$strComputer = “MyFileServer01″<enter>
[int]$x = 9<enter>
[decimal]$y = 9.9<enter>

PowerShell Operators

  • = Assigns a value to a variable.
  • + or += Addition.
  • - or -= Subtraction.
  • * or *= Multiplication.
  • / or /= Division.
  • % or %= Modulus (retrieves the remainder of a division operation).

PowerShell follows the rules of math. Equations are read from left-to-right, multiplication and division are preformed then addition and subtraction.

$x = 10 * 2 / 5 * 2 + 5 * 5<enter>
$x<enter>

What answer did you get? Hopefully 33.

What about:

$x = 10 * 2 / 5 * (2 + 5) * 5<enter>
$x<enter>

Parenthesis can be used to alter the order of the mathematical rule. O.k. enough math class.

Note: PowerShell has two additional operators that you will use frequently. Make a mental note of these operators as you will be using them often in your script writing.

  • “++” Increments a value by 1.
  • “–” Decrements a value by 1. -Hard to see, it is minus minus or (- -) without the space.

Examples:

$x = 1<enter>
$x<enter>
1
$x++<enter>
$x<enter>
2
$x++<enter>
$x<enter>
3
$x–<enter>
$x<enter>
2

We will work with more data types when the advanced PowerShell tutorials are launched.
Here are nine exercises to complete. See if you can get through them all without looking at the answers. Answers provided below the exercise:

  1. Create a variable named $strComputer and assign the files server name FSrv01.
  2. Create a variable named $x and assign the number 7.
  3. Create a variable named $y, assign the data type and number 11.
  4. Create a variable named $Pi, assign the data type and number 3.14
  5. Concatenate the following variables, strA = “This is a ” and strB = “text string.”
  6. Using two variables, subtract 5 from 9.
  7. Using two variables, add 5 and 9.
  8. Assign the number 1 to variable $x and increment by 1.
  9. Get the answer for the following equation. 5 * 2 / 10 + 7 / 3 * 2.

Answers:

  1. $strComputer = “FSrv01″
  2. $x = 7
  3. [int]$y = 11
  4. [decimal]$Pi = 3.14
  5. strA + strB -or- strA += strB
  6. $x = 9<enter> $y = 5<enter> $x – $y<enter>
  7. $y + $x<enter>
  8. $x = 1<enter> $x++<enter> $x<enter>
  9. $x = 5 * 2 / 10 + 7 / 3 * 2<enter> $x = 6


PowerShell Arrays

Variables can also store arrays which by definition are an indexed list of values. Each item is assigned a unique index number. The first item in an array is assigned the value of (0), the next item (1), then (2), and so on. One of the more popular uses of an array is to run a script against remote computers. If you’ve looked at the PowerShell scripts in the Microsoft Script Center Repository, notice that a lot of scripts only run on the local computer by using strComputer = “.” variable. “.” means the local computer the script is running on. You could run the script on a remote computer by modifying the code like this strComputer = “RemoteComputerName”. But, what if you want to run the script against multiple computers on your network? Ok… besides using a logon script! In essence a logon script still runs locally and you have limited control over when it runs. The answer is by using an array!

To create an array, we create a variable and assign the array. Arrays are noted by the “@” symbol. Let’s take the discussion above and use an array to connect to multiple remote computers:

$strComputers = @(“Server1″, “Server2″, “Server3″)<enter>

We now have three values stored in the $strComputers variable. Note: Since I am working with string values, I’m quoting. Also each array value is separated by a comma.

How to list the values in the array:

$strComputers<enter>

List the number of items within the array using the count property.

$strComputers.Count<enter>

Now that we know there are three elements within the array, we can list an item by it’s index number. Remember, array index numbers start at 0. List values by their index number:

$strComputers[0]<enter>
$strComputers[1]<enter>
$strComputers[2]<enter>

We can also modify elements in an array. Here I’m modifying an element in an existing array by providing the index number and the new string value. This changes the item Server3 to Server4.

$strComputers[2] = “Server4″<enter>

Verify the element was modified:

$strComputers<enter>

Using the + operator, we can combine arrays:

$x = @(1, 2, 3, 4, 5)<enter>
$y = @(6, 7, 8, 9, 10)<enter>
$z = $x + $y<enter>
$z<enter>

Back to our discussion on using arrays to get information from multiple computers. Here is a typical script taken from the Microsoft Script Repository that enumerates the BIOS information on the (strComputer = “.”) local computer. Note: you don’t have to copy the following script code into a .ps1 (PowerShell) script file to run. Just copy and paste the code into the PowerShell Console; to paste in PowerShell just do a right mouse click. When the code has been copied into the shell, just hit <enter> twice to get the results. Just another cool thing you can do with PowerShell…

$strComputer = “.”

$colItems = get-wmiobject -class Win32_BIOS -namespace root\CIMV2 -comp $strComputer

foreach ($objItem in $colItems) {
write-host “BIOS Characteristics: ” $objItem.BiosCharacteristics
write-host “BIOS Version: ” $objItem.BIOSVersion
write-host “Build Number: ” $objItem.BuildNumber
write-host “Caption: ” $objItem.Caption
write-host “Code Set: ” $objItem.CodeSet
write-host “Current Language: ” $objItem.CurrentLanguage
write-host “Description: ” $objItem.Description
write-host “Identification Code: ” $objItem.IdentificationCode
write-host “Installable Languages: ” $objItem.InstallableLanguages
write-host “Installation Date: ” $objItem.InstallDate
write-host “Language Edition: ” $objItem.LanguageEdition
write-host “List Of Languages: ” $objItem.ListOfLanguages
write-host “Manufacturer: ” $objItem.Manufacturer
write-host “Name: ” $objItem.Name
write-host “Other Target Operating System: ” $objItem.OtherTargetOS
write-host “Primary BIOS: ” $objItem.PrimaryBIOS
write-host “Release Date: ” $objItem.ReleaseDate
write-host “Serial Number: ” $objItem.SerialNumber
write-host “SMBIOS BIOS Version: ” $objItem.SMBIOSBIOSVersion
write-host “SMBIOS Major Version: ” $objItem.SMBIOSMajorVersion
write-host “SMBIOS Minor Version: ” $objItem.SMBIOSMinorVersion
write-host “SMBIOS Present: ” $objItem.SMBIOSPresent
write-host “Software Element ID: ” $objItem.SoftwareElementID
write-host “Software Element State: ” $objItem.SoftwareElementState
write-host “Status: ” $objItem.Status
write-host “Target Operating System: ” $objItem.TargetOperatingSystem
write-host “Version: ” $objItem.Version
write-host
}

Now we want the same information from multiple remote computers. This time you choose which ones. Create an array with two (or more) computers, FYI – you must have local admin rights on each computer to run the script. Use notepad and change the computer names in the array. Copy and paste your new code into PowerShell.

$strComputer = @(“computer1″, “computer2″, “computer3″)

$colItems = get-wmiobject -class Win32_BIOS -namespace root\CIMV2 -comp $strComputer

foreach ($objItem in $colItems) {
write-host “BIOS Characteristics: ” $objItem.BiosCharacteristics
write-host “BIOS Version: ” $objItem.BIOSVersion
write-host “Build Number: ” $objItem.BuildNumber
write-host “Caption: ” $objItem.Caption
write-host “Code Set: ” $objItem.CodeSet
write-host “Current Language: ” $objItem.CurrentLanguage
write-host “Description: ” $objItem.Description
write-host “Identification Code: ” $objItem.IdentificationCode
write-host “Installable Languages: ” $objItem.InstallableLanguages
write-host “Installation Date: ” $objItem.InstallDate
write-host “Language Edition: ” $objItem.LanguageEdition
write-host “List Of Languages: ” $objItem.ListOfLanguages
write-host “Manufacturer: ” $objItem.Manufacturer
write-host “Name: ” $objItem.Name
write-host “Other Target Operating System: ” $objItem.OtherTargetOS
write-host “Primary BIOS: ” $objItem.PrimaryBIOS
write-host “Release Date: ” $objItem.ReleaseDate
write-host “Serial Number: ” $objItem.SerialNumber
write-host “SMBIOS BIOS Version: ” $objItem.SMBIOSBIOSVersion
write-host “SMBIOS Major Version: ” $objItem.SMBIOSMajorVersion
write-host “SMBIOS Minor Version: ” $objItem.SMBIOSMinorVersion
write-host “SMBIOS Present: ” $objItem.SMBIOSPresent
write-host “Software Element ID: ” $objItem.SoftwareElementID
write-host “Software Element State: ” $objItem.SoftwareElementState
write-host “Status: ” $objItem.Status
write-host “Target Operating System: ” $objItem.TargetOperatingSystem
write-host “Version: ” $objItem.Version
write-host
}

For more information on building arrays to enumerate remote computers, here is a very cool article I’ve written: 3 easy steps to get information from remote computers.

Hash Tables

A Hash table is also known as a dictionary. It is an array that allows you to store data in a “key-value” pair association. The “key” and “value” entries can be any data type and length. The elements must be quoted if they contain a space.

Just like an array we designate a hash table with the @ symbol. There are differences, array elements are enclosed in parenthesis () where hash “key-value” pairs are enclosed in curly brackets {}. Hash elements are separated by the semi-colon.

Creating a hash of users associated with their employee number:

$EmpNumbers = @{“John Doe” = 112233; “Dave Davis” = 223344; “Justine Smith” = 334455}<enter>

Verify the hash table was created:

$EmpNumbers<enter>
PowerShell Trianing Hash table

Hast Table

Image 7.1

Looks like a mini-database. How would we find John Doe’s employee number?

$EmpNumbers["John Doe"]<enter>

Add a new employee record:

$EmpNumbers["Rose Jones"] = 445566<enter>

Verify the creation of new “key-value” pair.

$EmpNumbers<enter>

Delete an employee record:

$EmpNumbers.Remove(“Rose Jones”)<enter>

Verify record deletion:

$EmpNumbers<enter>

To Remove all records in the hash table, we use the clear method:

$EmpNumbers.Clear()<enter>

To recap, variables are items of information that we store for later retrieval. Arrays consist of numerous values that can be stored in a variable. Hash tables are associative arrays that use a “key-value” pairs. Since a hash table is like a dictionary, it is much easier to find values within the array (as there is an association created). Standard arrays are indexed starting from the number 0. This makes it difficult to find values, unless you’re a large brain and can tell me what value was assigned to index 245.

Thanks again for your time… In our next PowerShell training session we are going to talk about using Conditional logic. See you in the next tutorial.

Email This Page To A Friend Email This Page To A Friend

Comments

Great–keep them coming.
Clear, concise, examples!

By Lawson Dyer on March 17th, 2008 at 10:03 am

In your answers you have $strComputer = FSrv01 should it not be $strComputer = “FSrv01″. You left of the double-quotes. When do you plan to post the ADSI training session? Keep up the good work.

Ooooppps! Good catch Lawson. I am launching WMI part 3 tutorial tomorrow 3/19. I am looking to start ADSI next week, so look for it.

$x = 5 * 2 / 10 + 7 / 3 * 2 $x = 6

only comes out equal to 6 if you declare the variable as an integer
[int]$x = …

otherwise you get:

$x = 5.66666666666667

I am enjoying this material; thanks for putting it together. In your string concatenation example of $strC = $strA += $strB, you correctly state that the value of $strC is the concatenation of strings $strA and $strB. However, the += operator is not the same as the + operator. The += operator will concatenate the operand on the left side with the operand on the right and store the result in the operand on the left. A += B is shorthand for A = A + B. So in this example, after the operation, $strA also contains the concatenation of $strA and $strB. Similarly, A -= B is shorthand for A = A – B.

How can we create and initialize dynamic multidimensional arrays ?

By poiuytrez on July 25th, 2008 at 10:12 am

I love your tutorial.
Thanks a lot

Additional comment:

You say that
$strC = $strA += $strB
will cause $strC to have the value “Hello World!”

That’s true.

BUT… $strA will now ALSO have the value “Hello World!”

Great tutorial, tho!
What you want is $strC = $strA + $strB.

You don’t have to dim variables in VBscript unless you use the option explicit keywords.

I implement your example of -replace parameter ,in my PS script .As a result , it made my code readable and simple to maintain

I have a problem to get value from Hash:
####################
#Create hash
$App_dll=@{}
#define string
$Hyrarchy=”ABC\def”
$temp=$Hyrarchy.split(‘\’)
#devide the string
$App=$temp[0].split()
$dll=$temp[1].split()

#Update Hash Table
$App_dll.Add($dll,$App)

$dll
$a=”def”
$b=$App_dll.Get_Item($a)
###################################
The problem is that $b contains nothing

By Jerry Eakle on February 24th, 2009 at 8:24 pm

Variables can contain spaces, however they must be enlcosed in {}.
This is a legal variable name, {a*?,v**} although I would advice no one to ever use it….on purpose.
Sometimes you get data exported to you in a csv and the import gives you a variable name you don’t really want. But if you have to work with and have no other choice…

I’m having a problem w/ the right click code into powershell and hit enter twice part… I’m not sure if my powershell didn’t install correctly or what, but that doesnt work, nor does executing saved scripts, I wonder if you can help me figure out what I’m doing wrong, thanks

After taking a look on another box, it is still a problem so I’m sure I must be doing something wrong, or maybe I need to install something in addition to PowerShell… On the first big block of code I get this error:

Get-WmiObject : A parameter cannt be found that matches parameter name ‘Characteristics:’ . At line:1 cha:26 + $colItems = get-wmiobject <<<< -class “Win32_BIOS” -namespace “root\CIMV2?

Josh,
Nothing wrong with PowerShell. Looks like there is a formatting issue when copying text from code on this page to powershell. For some reason it is not understanding the closed quote. look at the -namespace in the error you are getting “root\CIMV2? -the question mark is the problem. It should read “root\CIMV2″ – I’ve changed the code above until I can work out the issue on the site.

huh, that seemed to work, thanks a lot. BTH this is a great site, I’m a junior studying comp science, and I just started working as a DBA on campus… I’m going to try and do some fun stuff with this and SQL Server’s Report Services

By Jesse Hamrick on March 12th, 2009 at 12:52 pm

Check out this link for working with PowerShell and SQL. http://www.idera.com/Content/Show76.aspx
Free PowerShell scripts for SQL DBAs.

wow, dang good stuff. I had another question, somewhat relating to arrays… more on the .net objects though… Thanks to your tutorials (and msdn I guess I have to give them some credit : /), I was able to make this within ~5-6 hrs of learning what powershell even was:
$date = get-date -uformat “%Y-%m-%d”
Get-WmiObject win32_LogicalDisk|Where-Object {$_.Size -gt 0}|Select-Object Name,Description,FreeSpace,Size|Export-CSV -Path “C:\serverStatusReport\dailyFiles\driveInfo $date.csv”

This works wonderfully, and I can just run an SSIS package on it to import it. Now I want to run it from my VM and collect this file from every SQL server in the building. The hickup I’m running into right now is that while get-wmiobject win32_LogicalDisk works fine, get-wmiobject win32_Logicaldisk -comp XYZ throws an error… what am I doing wrong?

The samples for working with arrays don’t seem to be completely correct?
$strComputers = “comp 1″, “comp 2″ defines an array, but $strComputers = @{“comp 1″ = “Dell”} is defining a hashtable?

Great tutorial to get up to speed in a quick and efficient way! Thanks!

By David Rogers on May 26th, 2009 at 4:43 pm

RE: “Did you get John Doe for the output? Yes… great! No?… I knew you were going to skip the long version of using the “Set-Variable” cmdlet.”

Smarty Pants! ;-)

Hi,
I’ve just started to use the PowerShell and (one of my first todos) it is really easy to create a hash from astring or a file but I hven’t found anywhere to store a hash hopefully that easy (??) into a file.
Can you add this (write hash to a file) to your hash-section, I would appreciate this!
THanks Carl

hello

pls, how i have to to wenth i save or restor variables
thnx

Hi,
About moshe’problem :
You’ve to assigne the data type to variables, like this casting :
[String]$App=$temp[0].split()
[String]$dll=$temp[1].split()

Without this you can’t Update Hash Table
$App_dll.Add($dll,$App)
-> because $dll and $App was System.Array in your first script…

By marizion on June 3rd, 2010 at 4:17 pm

i’ve been trying very hard to go through this code to figure out what moshe is doing wrong but i can’t seem to figure it out
when i print out $app_dll instead of showing
def abc
it shows
{def} {abc}

By moshe ro on January 18th, 2009 at 6:11 am
I have a problem to get value from Hash:
####################
#Create hash
$App_dll=@{}
#define string
$Hyrarchy=”ABC\def”
$temp=$Hyrarchy.split(’\’)
#devide the string
$App=$temp[0].split()
$dll=$temp[1].split()

#Update Hash Table
$App_dll.Add($dll,$App)

$dll
$a=”def”
$b=$App_dll.Get_Item($a)
###################################
The problem is that $b contains nothing

By marizion on June 4th, 2010 at 1:58 am

i figured out whats wrong with the code,

the split method of the string is returning a string array so the key for the app_dll is an array of strings rather than a single string, and the variable a contains a single string, so to solve the problem, remove the .split() behind app = temp[0].split and remove the .split behind dll = $temp[1].split()

great tutorial by the way, keep them coming, i’ve come so far just from your teachings

now one thing i don’t understand, $app_dll.get_item($dll) produces results after the change but why dosen’t $app_dll[$dll] produce anything ?
thanks

By marizion on June 4th, 2010 at 2:01 am

i figured out whats wrong with the code,

the split method of the string is returning a string array so the key for the app_dll is an array of strings rather than a single string, and the variable a contains a single string, so to solve the problem, remove the .split() behind app = temp[0].split and remove the .split behind dll = $temp[1].split()

great tutorial by the way, keep them coming, i’ve come so far just from your teachings

Correction below without the change, sorry

now one thing i don’t understand, $app_dll.get_item($dll) produces results without the change but why dosen’t $app_dll[$dll] produce anything ?
thanks

By Alasdair Carnie on June 20th, 2010 at 6:23 am

Hi,

I am trying to figure out how to set the ip address of an array of hosts using two arrays. Array 1 has the host names and array 2 has the IP addresses. I tried using a for each loop but I can’t figure out how to get the information from the second array into the loop. I then tried a regular for loop and then a do loop, but I can’t get the code to work with the values for the second array.

Any help would be appreciated.

Alasdair Carnie:
Try using a hash instead. Then you can loop through the Name Value pairs

When trying to complete this part of the tutorial:

Using the + operator, we can combine arrays:
$x = @(1, 2, 3, 4, 5)
$y = @(6, 7, 8, 9, 10)
$z = $x + $y
$z

I get the following error:

Cannot convert the “System.Object[]” value of type “System.Object[]” to type “System.Int32″. $x <<<< = @(1,2,3,4,5)

Thanks,
Bob

Same Bob. Try this:

$strComputers = @(“Server1″, “Server2″, “Server3″)
$strComputers2 = @(“Server11″, “Server12″, “Server13″)
$strAllComputers = $strComputers + $strComputers2
$strAllComputers

Adding a record to a hash table is described in the section above as:

Add a new employee record:

$EmpNumbers["Rose Jones"] = 445566

How would that work exactly? Rather than adding a record, this looks more like setting a record that has already been added.

Bob, Brent: Same problem. Changed to new variable, unused names, and it worked fine.

I am trying to parse xml files from database exports to validate data in the database.

How do I get just the tag value when the tag as both attributes and values.

Sample XML

00728cam a22002531 4500
100112

MP 0465.D 01

Here is the code:

$VRPPath = “C:\horizon\horizon-random-sample-formatted.xml”
[xml]$VRLfile = Get-Content $VRPPath
foreach( $record in $VRLfile.collection.record)
{
write-host “leader = “, $record.leader
foreach( $cf in $record.controlfield)
{
write-host “cf tags = “, $cf.tag,” value: “, $cf
$cf
}
}

OutPut:

leader = 01653nam a22002651 4500
cf tags = 001 value:
001 101396
“““““““““
In the second line of the output where the tag has attributes as well as a value, I can get the attribute values just fine but the tag value returned is null or empty.

In the 3rd line of the output, the tag value is returned as a table of attribute and value pairs. I just need the value or text that is stored in the tag without any attribute values.

In your ‘Working with Strings’ section, ‘string’ is misspelled in the following sentence: “A [sting] is a “text string” data type”.

I hope they didn’t use “sting” as the type.

Awesome tutorial. Really easy to understand and follow :)

I am enjoying the tutorials. They are easy to understand, use good examples and have enough material, but not so much as to confuse.
However, I am a little unclear as to when to use the square brackets [], or the curly brackets {} or parens ().
Is there any rule or guide to assist with remembering which to use in which situations?

Question…
To add a variable to the Hash Table, we put it in square brackets. To remove it, it was just in parens. Why the difference?

Thanks!!

You still have not corrected the error about using +=, in your example after doing $strC = $strA += $strB if you do $StrA you will get “Hello World!”. Please update the tutorial as it is misleading.

Hi Jesse.
I’m wondering if there is a way for asking the user some information instead of instruc him/her to pass parameters.

What I’d like to do is to check a few windows services on a given server list (a text file). The goal is to have inputs from the user like “amount of services to check”, and with that value create the array index – 1 (of course as indexes starts with 0), and the another pause to ask for the service name.

What will be the sintax that makes a pause at running time and wait for the user to type something, and store that within a variable?

I hope you get the idea.

Thanks for the tutorials. You’re really good!

$JUser=”Veronica Nelson”
$JAlias = $Juser | get-mailbox | select-object alias
write-host Going to create “\\svr1\I$\PSTS\\$JUser\$JAlias.PST”

Output
Going to create \\svr1\I$\PSTS\Veronica Nelson\@{alias=vnelson}.PST

Problem: creates a HashTable and I just want the value of Alias to appear, what do I need to add to my code for this?

By NomadAbhi on March 5th, 2012 at 3:30 am

Bob, Brent:

The X and Y variables have been used in exercise before as Integers [INT].
Later, we are trying to use the same variables i.e. $x and $y as Array. Hence the error as it has been same powershell session.
2 ways:
Either close the shell session and start new one
Or use different unused variables.

Muy buen tutorial.
Solamente he tenido una duda, cómo definir una variable de manera interactiva al ejecutar un archivo de powershell (como por ejemplo *.ps1, es como el equivalente de un archivo por lotes), es decir que en cmd.exe (ms-dos), se utiliza “set /p variable=valorparadefinirdemanerainteractiva”, pero no puedo utilizar este comando en powershell porque no puedo obtener el valor de la variable definida con el comando set, entonces cuál seria la manera de permitir definir una variable de manera interactiva al ejecutar un archivo de powershell en powershell. Saludos.

The hash tables remind me very much of lisp.

By annonymous on May 15th, 2012 at 11:30 am

Great tutorial. Thank you much.

++ and — are not as simple as stated in the tutorial. They are what are called pre and post increment/decrement operators. Take a look at this script.
$a = 10
write-output ($a–) #you will get 10
write-output (–$a) #you will get 8!
write-output ($a) #you get 8.
#the same applies to ++

Essentially when you use a POST increment/decrement, you use the value in the variable, change it, and then assign the result to the variable. When you use a PRE increment/decrement, you change the value, assign it to the variable, and then use it.

This is useful for several reasons, various especially looping operations.

Other than that and the += and -= operators, very good introductory to PowerShell.

Could you please add how to add variable values to hashtables such as

$myhash = @{ValueofA = $a}

Thanks!

Excellent! Thanks for this!

The concatenation example is bad:

$a = $b += $c

doesn’t point out the side effect that += has, that is, storing the concatenated result in $b as well as $a

This does not work in a function but does out of the function, Why?

Param([Array]$Data)

Function try-Count([Array]$Data){
Clear-Host

If($Data -eq $Null){“Its Null Fool. Try -Data 1..1000″}
$range = $Data
$range = $range
$count = $range.Count
For($i=0; $i -lt $count; $i++) {
$i
}
}

$a = try-Count -Data $Data
$a

#$Data = 1..1000
#$range = $Data
#$count = $range.Count
#For($i=0; $i -lt $count; $i++) {
# $i
# }

In Powershell Operators question 9 you show the answer as $x=6.
Powershell shows $x=5.666666666667.

I suspect Powershell is right. :-)

You’ve taken a dangerous step equalizing + and +=, because there’s an important difference between these two operators, which can result in a totally messed up output.
$a += $b is an abbreviation for $a = $a + $b, so += doesn’t just add the two variables but also assigns the result to $a. This is basic knowledge in programming and I’m surprised you did not differ.

Let’s use your example:
$strA = “Hello “
$strB = “World!”
$strC = $strA += $strB
$strC

Line three concatenates $strA and $strB and assigns the value to $strA, and afterwards the value of $strA is assigned to $strC.
Now, both, $strC AND $strA equal “Hello World!”
With $strC = $strA + $strB only $strC equals “Hello World!” while $strA stays “Hello “.
Who cares, one may think but let’s assume you want to further use $strA, and send out a personal greet to Jane.
$strD = “Jane!”
$strE = $strA += $strD
$strE
Now the result is “Hello World! Jane!”. Not what you inteded to get …

can someon eplease explain $objitem .. how it is used, i have often sen in scripts with for each $objitem or $i is used, how do we know what to use and when..

any help is much appriciated.

i want to elaborate my above question.. what i intended to ask was this

$strComputer = @(“computer1?, “computer2?, “computer3?)

$colItems = get-wmiobject -class Win32_BIOS -namespace root\CIMV2 -comp $strComputer
foreach ($objItem in $colItems) {

In above code there are 3 variables $strComputer and $colItems are defined but $objItem is not … i have seen this in many scripts where foreach is used

so my question is what is $objItem and how to and when to use them, what i understand is when we use this with foreach the action is performed on every object..but i dont understand it fully…

could be please explain this…

When I assign $x to a value, then add values using the $x++ function, that works fine. However, when I try to invoke the subtract function $x- I’m presented with this promt:

>>

Soonafter, I get the error: ”
You must provide a value expression on the right-hand side of the ‘-’ operator.
At line:1 char:4
+ $x- <<<<
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordExcept
+ FullyQualifiedErrorId : ExpectedValueExpression"

Has something changed in PowerShell or am I doing something wrong? Thanks for your replies.

Steve, You only have one ‘-’ symbol after $x, you need two minus symbols, e.g. $x–

@Singh

If you’re using foreach you iterate every object in an array. $objitem references the current item that is being iterated.

foreach($number in $number_array){
echo (“Current Item: “+$number);
}

So by using $number in this example you can reference the current object within the loop body. Else you’d not be able to access the current object or in a rather complicated way.

Beware that you won’t be able to change the value of the current item. You’re only able to access it!

Not to nit-pick but, you don’t actually have to dimension variables in VBScript. VBScript can dynamically dimension variables, but it will assume the smallest scope possible. So, if you want to set the scope of a variable higher than it will assume at it’s first use, THEN you have to explicitly dimension it. Otherwise, it’s just a good practice. :-)

Excellence examples are there…

By Terry Hobart on April 24th, 2013 at 8:50 am

I noticed that the Array & Hash variables had members. $x.count etc. So, I concluded that they were objects. So, I tried to apply Get-Member to them ie Get-Member $x to see what other members they have. However, this throws an error saying $x is not an object. Can you elaborate? Just a nob question. Thanks for the tutorial.

I am seeing a problem similar to the the one “Josh” experienced with the array code except my problem is on the second example where you instructed us to try multiple computers. The first one worked correctly. Here is the error I receive when I cut and paste the code into PowerShell . . .

Get-WmiObject : Invalid parameter
At line:1 char:26
+ $colItems = get-wmiobject <<<< -class Win32_BIOS -namespace root\CIMV2 -comp
$strComputer
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
tException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
ommands.GetWmiObjectCommand

The only thing I did was change the computer names to ones I work with but the error does not seem to refer to those computers. Everything else was exactly the same as what is on this site. Any idea what is causing this?

By Thinkerbot on May 26th, 2013 at 11:28 pm

Your array example is pretty stupid. Many to most arrays are going to be more than 3 or 4 items. People need to be able to populate an array using iteration to add values, that’s the example you should have provided.

Just a thought, are you not using Hungarian notation, rather than CamelCase which is more of a marketing thing.

PPL, all please realize the author, Jesse H., has not posted since 2009 and therefore calls for him to correct this stuff will go unheeded!! Read and go on; experiment and find other instructional essays.

I never got past the first paragraph as soon as I noticed that two out of the three definitions are wrong….

“Variables – allows us to store single bits of information.” Single bits of information??? That is not at all a good explanation of what a variable stores. First, the word “bit” has a specific meaning in the context of programming (and could potentially be confused with individual 1′s and 0′s). But even if most readers don’t take that mistaken interpretation, saying that variables store “single bits” of information doesn’t say anything clear at all. A variable can store the whole output of a command, or the whole text content of a file. Would anyone really think of these as “single bits of information”? It’s just a poor definition.

“Arrays – allows us to store information in an index”. No they don’t. An index is how you refer to a position in the array. You cannot “store” information “in” an index.

I didn’t bother to go any further, but from the looks of some of these comments, there are lots of problems with the rest of the article too.

I’m trying to programmatically access individual elements in an array. This is what it looks like and it’s not doing what I expected:

$i=1
foreach($sourceFile in $sourceFileArray) {
CopyFileToFolder $sourceFile $destFileArray[$]
Write-Host “sourceFile: $sourceFile” (this is correct)
Write-Host “destFileArray[$i]: $destFilearray[$i]” (prints destfileArray[1]: c:\test H:\ E:\ G:\ G:\[1] which is incorrect…I just want ith item)

Thanx for fine material!

Intheresthing posth

 

Leave a Comment