What is Windows PowerShell and what does it eat? Part 2: Introduction to the programming language

Historically, command-line utilities on Unix systems are better developed than on Windows, however, with the advent of a new solution, the situation has changed.



For PowerShell, you can write scripts in an interpreted multi-paradigm language that contains elements of classical procedural, object-oriented, and even functional programming: conditional branching, loops, variables, arrays, hash tables, classes, error handling, as well as functions, cmdlets and pipelines . The previous article was devoted to the basics of working in an environment, and now we offer our readers a small guide for programmers.

Table of contents:


Comments
Variables and their types
System variables
Scopes
Environment variables (
arithmetic ) Arithmetic and comparison
operators Assignment
operators Logical operators
Conditional transition
Loops
Arrays
Hash tables
Functions
Error handling You

can write code in any text editor or using the integrated development environment - the easiest way to take Windows PowerShell ISE included with Microsoft Server Operating Systems. This is only necessary for fairly complex scripts: short sets of commands are easier to execute interactively.

Comments


Using comments is considered part of a good programming style along with proper indentation and spaces:

#       —     .

<# 

             . 
            .

#>

Variables and their types


Variables in PowerShell are named objects. Their names may include an underscore, as well as letters and numbers. The $ symbol is always used before the name, and to declare a variable, it is enough to indicate to the interpreter a valid name:

image

To initialize the variable (assign a value to it), the assignment operator (symbol =) is used:

$test = 100

You can declare a variable by indicating its type in square brackets (type conversion operator) before the name or value:

[int]$test = 100

$test = [int]100

It is important to understand that variables in PowerShell are full-fledged objects (classes) with properties and methods whose types are based on those available in .NET Core. We list the main ones:
Type (.NET class)
Description
Code example
[string]
System.String
Unicode 
$test = «»
$test = ''
[char]
System.Char
Unicode (16 )
[char]$test = 'c'
[bool]
System.Boolean
( True False)
[bool]$test = $true
[int]
System.Int32
(32 )
[int]$test = 123456789
[long]
System.Int64
(64 )
[long]$test = 12345678910
[single]
System.Single
32
[single]$test = 12345.6789
[double]
System.Double
64 (8 )
[double]$test = 123456789.101112
[decimal]
System.Decimal
128-bit floating-point number (be sure to include d at the end)
[decimal] $ test = 12345.6789d
[DateTime]
System.DateTime
date and time 
$ test = Get-Date
[array]
System.Object []
an array whose element index starts at 0
$ test_array = 1, 2, "test", 3, 4
[hashtable]
System.Collections.Hashtable
hash tables - associative arrays with named keys, built on the principle: @ {key = "value"}
$ test_hashtable = @ {one = "one"; two = "two"; three = "three"}

PowerShell supports implicit type conversion, in addition, the type of the variable can change on the fly (for example, using the assignment operator), if it is not specified forcibly - in this case, the interpreter will throw an error. You can determine the type of a variable from the previous example by calling the GetType () method:

$test.GetType().FullName

image

There are a number of cmdlets for managing variables. Their list in a convenient form is displayed using the command:

Get-Command -Noun Variable | ft -Property Name, Definition -AutoSize -Wrap

image

To view the declared variables and their values, you can use the special cmdlet:

Get-Variable | more

This method seems overly cumbersome, it is much more convenient to work with variables through operators or by accessing their properties and methods directly. However, cmdlets have a right to exist because they allow you to specify some additional parameters. It is important to understand that user variables are defined only within the current session. After closing the console or completing the script, they are deleted.

System variables


In addition to those declared by the user, there are built-in (system) variables that are not deleted after the end of the current session. They are divided into two types, while PowerShell status data is stored in automatic variables, which cannot be assigned arbitrary values ​​on their own. These include, for example, $ PWD:

$PWD.Path

image

To store user settings, you need preference variables whose values ​​can be changed. For example, with the help of $ ErrorActionPreference, the response of the command interpreter to the occurrence of non-critical errors is set.

In addition to operators and cmdlets, the Variable: pseudo-accumulator exists for accessing declared variables. You can work with it by analogy with other drives, and the variables in this case resemble file system objects:

Get-ChildItem Variable: | more

or

ls Variable: | more

image

Scopes


For variables in PowerShell, there is the notion of Scope. The action of the global area (Global) extends to the entire current session - it includes, for example, system variables. Local variables are available only in the area where they were defined: let's say inside the function. There is also the concept of a script scope, but for script commands, it is essentially local. By default, when declaring variables, they are given a local scope, and to change this, we need a special construction of the form: $ Global: variable = value.

For example, like this:

$Global:test = 100

Environment Variables


Another Env pseudo-drive is available from PowerShell, which can be used to access environment variables. When the shell starts, they are copied from the parent process (i.e., from the program that initiated the current session) and usually their initial values ​​coincide with the values ​​in the control panel. To view environment variables, use the Get-ChildItem cmdlet or its aliases (liases): ls and dir.

dir Env:

image

These variables are sequences of bytes (or characters, if you like), the interpretation of which depends only on the program that uses them. * -Variable cmdlets do not work with environment variables. To access them, you will have to use the disk prefix:

$env:TEST = "Hello, World!"

image

Arithmetic and comparison operators


PowerShell has the following arithmetic operators: + (addition), - (subtraction), * (multiplication), / (division) and% (module or remainder of division). The result of an arithmetic expression is calculated from left to right in accordance with the generally accepted order of operations, and parentheses are used to group parts of the expression. Spaces between operators are ignored, they are used only to facilitate perception. The + operator also concatenates, and the * operator repeats the lines. If you try to add a number to a string, it will be converted to a string. In addition, PowerShell has many comparison operators that check the correspondence between two values ​​and return boolean True or False:
Operator
Description
Code example
-eq
Equal (analogue = or == in other languages)
$ test = 100
$ test -eq 123 
-ne
Not equal (analog <> or! =)
$ test = 100
$ test -ne 123   
-gt
Greater than / More (analog>)
$ test = 100
$ test -gt 123
-ge
Greater than or equal / Greater than or equal (analogue> =)
$ test = 100
$ test -ge 123
-lt
Less than (analog <)
$ test = 100
$ test -lt 123  
-le
Less than or equal / Less than or equal (analog <=)
$ test = 100
$ test -le 123

There are other similar operators that allow, for example, comparing strings with a wildcard character or using regular expressions to match patterns. We will consider them in detail in the following articles. The symbols <,> and = are not used for comparison, since they are used for other purposes.

Assignment Operators


In addition to the most common operator =, there are other assignment operators: + =, - =, * =, / = and% =. They change the value before assignment. The unary operators ++ and - behave similarly, which increase or decrease the value of a variable - they also relate to assignment operators.

Logical operators


Comparison is not enough to describe difficult conditions. You can write down any logical expressions using the following operators: -and, -or, -xor, -not and! .. They work like in other programming languages, while you can use parentheses to specify the calculation order:

("" -eq "") -and (100 -eq 100)

-not (123 -gt 321) 

!(123 -gt 321)

Conditional jump


The branching operators in PowerShell are standard: IF (IF ... ELSE, IF ... ELSEIF ... ELSE) and SWITCH. Consider their use with examples:

[int]$test = 100
if ($test -eq 100) {
      Write-Host "test = 100"
}



[int]$test = 50
if ($test -eq 100) {
       Write-Host "test = 100"
}
else {
      Write-Host "test <> 100"
}



[int]$test = 10
if ($test -eq 100) {
      Write-Host "test = 100"
}
elseif ($test -gt 100) {
      Write-Host "test > 100"
}
else {
       Write-Host "test < 100"
}



[int]$test = 5
switch ($test) {
     0 {Write-Host "test = 0"}
     1 {Write-Host "test = 1"}
     2 {Write-Host "test = 2"}
     3 {Write-Host "test = 3"}
     4 {Write-Host "test = 4"}
     5 {Write-Host "test = 5"}
     default {Write-Host "test > 5    "}
}

Cycles


There are several types of loops in PowerShell: WHILE, DO WHILE, DO UNTIL, FOR, and FOREACH.

The precondition loop works if / while it is running:

[int]$test = 0
while ($test -lt 10) {
      Write-Host $test
      $test = $test + 1
}

Loops with a postcondition will work at least once, because the condition is checked after iteration. In this case, DO WHILE works while the condition is true, and DO UNTIL - while it is false:

[int]$test = 0
do {
      Write-Host $test
      $test = $test + 1 
}
while ($test -lt 10)



[int]$test = 0
do {
      Write-Host $test
      $test = $test + 1 
}
until ($test -gt 9)


The number of iterations of the FOR loop is known in advance:

for ([int]$test = 0; $test -lt 10; $test++) {
       Write-Host $test
}


In a FOREACH loop iterates over elements of an array or collection (hash table):

$test_collection = "item1", "item2", "item3"
foreach ($item in $test_collection)
{
        Write-Host $item
}

Arrays


PowerShell variables store not only single objects (number, string, etc.), but also plural ones. The simplest variety of such variables is arrays. An array can consist of several elements, one element or be empty, i.e. do not contain elements. To declare it, use the @ () operator, which we will need in the next article - it is very important for adding other arrays to the array (creating multidimensional arrays), passing arrays to functions as arguments, and similar tasks:

$test_array = @() #  

When the array is initialized, its values ​​are listed with a comma (special operator,):

$test_array = @(1, 2, 3, 4) #      

In most cases, the @ () operator can be omitted:

$test_array = 1, 2, 3, 4

In this case, an array of one element is initialized as follows

$test_array = , 1

To access array elements, an integer index starting from zero and an index operator (square brackets) are used:

$test_array[0] = 1

You can specify multiple indices, separated by commas, including duplicate:

$test_array = "", "", "", ""
$test_array[0,1,2,3]
$test_array[1,1,3,3,0]

image

The operator ..(two points - the range operator) returns an array of integers on a segment defined by the upper and lower bounds. For example, expression 1..4 displays an array of four elements @ (1, 2, 3, 4), and expression 8..5 displays an array of @ (8, 7, 6, 5).

image

Using the range operator, you can initialize an array ($ test_array = 1..4) or get a slice, i.e. a sequence of elements in one array with indices from another. In this case, a negative number -1 indicates the last element of the array, -2 - the penultimate, etc.

$test_array = "", "", "", ""
$test_array[0..2]
$test_array[2..0]
$test_array[-1..0]
$test_array[-2..1]

Please note that the values ​​of the integer array may be greater than the maximum value of the index of the data array. In this case, all values ​​are returned to the last:

$test_array[0..100]

If you try to access a single nonexistent array element, $ null is returned.

image

In PowerShell, arrays can contain elements of different types or be strongly typed:

$test_array = 1, 2, "", 3, 4
for ([int]$i = 0; $i -lt $test_array.count; $i++)
{
          Write-Host $test_array[$i]
}

Where the property $ test_array.count is the number of elements in the array.

An example of creating a strongly typed array:

[int[]]$test_array = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Hash tables


Another basic type of variable in PowerShell is hash tables, also called associative arrays. Hashtable are similar to JSON object and are built on a key-value basis. Unlike ordinary arrays, access to their elements is carried out using named keys, which are object properties (you can also use the index operator - square brackets).

An empty hash table is declared using the service symbol @ and operator brackets:

$test_hashtable = @{}

When declaring, you can immediately create keys and assign values ​​to them:

$test_hashtable = @{one=""; two=""; three=""; "some key"="some value"}

To add an item to the hash table, you must assign it a key that does not yet exist or use the Add () method. If the assignment is done with an existing key, its value will change. To remove an item from a hash table, use the Remove () method.

$test_hashtable."some key"
$test_hashtable["some key"]
$test_hashtable.Add("four", "")
$test_hashtable.five = ""
$test_hashtable['five'] = " "
$test_hashtable.Remove("one")

image

Variables of this type can be passed as arguments to functions and cmdlets - in the next article we will learn how to do this, and also consider another similar type - PSCustomObject.

Functions


PowerShell has all the necessary elements for procedural programming, including functions. The function word Function is used to describe them, after which it is required to indicate the name of the function and the body enclosed in operator brackets. If necessary, pass arguments to the function, you can specify them immediately after the name in parentheses.

function - (1, ..., N) 
{ 
        - 
} 

A function always returns a result - this is an array of the results of all its statements, if there are more than one. If there is one statement, a single value of the corresponding type is returned. The return $ value construct adds an element with the value $ value to the result array and aborts the statement list, and an empty function returns $ null.

For example, create a function for squaring a number:

function sqr ($number)
{
      return $number * $number
}

Note that in the function body you can use any variables declared before its call, and calling functions in PowerShell may seem unusual: arguments (if any) are not enclosed in parentheses and are separated by spaces.

sqr 2

or so:

sqr -number 2

Due to the way arguments are passed, the function itself sometimes has to be enclosed in brackets:

function test_func ($n) {}
test_func -eq $null     #   
(test_func) -eq $null   #   — $true

image

When describing a function, you can assign default values ​​to the arguments:

function func ($arg = value) {
         # 
}

There is another syntax for describing function arguments, in addition, parameters can be read from the pipeline - all this will come in handy in the next article when we consider exported modules and create your own cmdlets.

Error processing


PowerShell has a Try ... Catch ... Finally mechanism to handle exceptions. The Try block contains code in which an error may occur, and the Catch block contains its handler. If there was no error, it is not executed. The Finally block is executed after the Try block, regardless of the occurrence of an error, and there may be several Catch blocks for exceptions of various types. The exception itself is written to the default non-declaration variable ($ _) and can be easily retrieved. In the example below, we implement protection against entering an incorrect value:

try {

        [int]$test = Read-Host " "
        100 / $test

} catch {

         Write-Warning " "
         Write-Host $_

}

image

That’s where the PowerShell programming basics are concerned. In the following articles, we will study in more detail the work with variables of various types, collections, regular expressions, the creation of functions, modules and custom cmdlets, as well as object-oriented programming.

Part 1: the main features of Windows PowerShell
Part 3: passing parameters to scripts and functions, creating cmdlets
Part 4: Working with objects, custom classes



All Articles