@()

The @() is used to create an empty array.

PS:> $array = @()

To confirm the $array contains an array run the following and inspect the output:

$array.GetType().FullName

 

System.Object[]

To see how many objects are saved in the array use the count property:

$array.count

 

0  

Great, you in fact have an empty array. The @() itself is more powerful because it can be used not only to create array with 0 length but it can also wrap objects in array even if only one is returned. To show you an example let’s set our current PowerShell session to strict mode (version 2) by:

Set-StrictMode -Version 2

In this mode PowerShell will check if the property is available on the object and if not it will throw an exception, as opposed to no output in normal (non-strict) mode. We need something that gives only one object back, ideal candidate is the Idle process that runs only once on every computer.

$process = Get-Process -Name Idle

If you try to get Count on the $process variable an exception is raised. The $process variable does not contain an array and hence the Count property is not available on the object.

$process = Get-Process -Name Idle
$process.Count

 

. : Property 'Count' cannot be found on this object. Make sure that it exists.

If you try it again instructing PowerShell to save the result of the get-process command as an array you will be able to confirm that the $process variable contains only one value.

$process = @(Get-Process -Name Idle)
$process.Count

 

1

And that the $process in fact contains an array:

$process.GetType().FullName

 

System.Object[]
Note: Although available this feature is rarely needed. For example the correct way to implement the previous example is using Measure-Object cmdlet that would give you correct results when used with both scalar and array value. Before using it make sure you do not have another option.

@{}

The @{} is used to create a hashtable. To create an empty hashtable use it in the samilar manner as the @():

$hashtable = @{}
$hashtable.GetType().FullName

 

System.Collections.Hashtable

 

$hashtable.count

 

0

And to create a hashtable with one or more keys, separating the keys with semicolon or newline:

$hashtable = @{name="nohandle";domain="powershell.cz"}
$hashtable.Count

 

2

The data are stored as key=value pairs in the hashtable. You can access the values by $hashtable.name, called dot notation, or by $hashtable[“name“], called array notation. The hashtable type is frequently used in PowerShell to create custom objects with new-object or Select-object cmdlets but originally hashtable was invented to handle long lists of key=value pairs efficiently.

What if I exchange them?

If you do assignment nothing will happen because the original content of the variable is replaced with the new one. Unless you hard-typed the variable, in that case I assume you already know what you are doing and accept the risk. But usually you create an empty array because you are planning to add some values to it. If you create a hashtable instead of an array and you perform add operation on it, as such:

$hashtable = @{}
$hashtable+="value"

You will receive a terminating exception.

+= : You can add another hash table only to a hash table.

If you do it the opposite way and create an empty array instead of a hashtable and use the same approach to add data you won’t get any error on the assignment.

$array = @()

$array += @{domain="powershell.cz"}

But you won’t be able to access the data:

$array.name

If you try to add a pair by the Add method that you assume is available on the hashtable object you also recieve an exception:

$array.Add("suffix","cz")

 

Add : Method invocation failed because [System.Object[]] doesn't contain a method named 'Add'.

Summary

If you happen to create a variable containing array instead of hashtable (or likewise) you will very likely encounter terminating runtime errors.