Jump Start in PowerShell (Part II)

  • Tutorial
Who if not you? When, if not now?

In the previous part, we learned how to run PowerShell, figured out the script execution policy. We understood what cmdlets are, we know how to transfer them along the pipeline and how to get their properties. Learned that PowerShell has a huge Help.

In this part, we will deal with variables, find out what types they are and how to access them, how to compare and display them in all possible ways. Be sure to deal with cycles and write some functions.

← Go to Part I


I want to start with the answers to the questions that arose in our first Jump Start with you:

What are the great features of PowerShell? Why should I study it?
Everyone under the phrase "great opportunities" can understand something of their own.
If I had to describe PowerShell in a nutshell, I would say: this is an environment that simplifies administration , helps to create tools for automation and management .

It’s definitely worth exploring PowerShell if you are administering Windows Server and Microsoft server software. Take, for example, one of the most popular Microsoft Exchange Server products - and then you come across the Power Management Shell Exchange Management Shell console.
Knowing PoSh, you can easily do any necessary data upload, configure control over any system processes, send reports, create users, solve their problems ...

I do not administer, then what?
This can be compared with how people of completely different professions are addicted to creating web sites. It seems they don’t really need it, but they are doing it. For the sake of their own development, entertainment or pleasure.
Are you a student? Write yourself your first application that will solve the quadratic equation.
Or, for example, study parsing and make your own application for downloading music or beautiful videos from youtube.
It all depends on you and your imagination. Look here , PowerShell can even be taught to talk.

You can just watch the video on MVA!
Yes, I completely agree with you - it can be more effective.
True, not everyone has time to view a 12-15 hour course, and not everyone can perceive information in this way.
Here I try to give basic knowledge with which it will be possible to successfully continue to develop my skills infinitely further.


  • A variable in PowerShell starts with a $ sign (in the European Union with a € sign) and in the name can contain any letters, numbers and underscore.
  • To assign a value to a variable, just assign it to it with the sign " = ". To display the value of a variable, you can simply write this variable. We will analyze the output of information in the text below.

    $var = 619

  • Arithmetic operations can be performed on numbers, lines can be added. If you add a number to a string, the number is automatically converted to a string.

    $a = 1
    $b = 2
    $c = $a + $b
    $c   #c = 3
    $str = "Хабра"
    $str = $str + "хабр"
    $str   #str = Хабрахабр 
    $str = $str + 2014
    $str   #str = Хабрахабр2014

  • If we need to find out what type this or that variable has, we can use the GetType () method

    $s = "Это строка?"

  • The type of variable PowerShell determines automatically or can be assigned manually.

    $var = "one"
    [string]$var = "one"

    PowerShell uses the Microsoft .NET Framework data types. Consider the main ones:

    Type / .NET classDescription


    $var = "one"



    $var = [char]0x263b


    Boolean. It can be $ true or $ false .

    $bvar = $true


    32-bit integer

    $i = 123456789 


    64-bit integer

    $long_var = 12345678910


    128 bit decimal number. The letter d at the end of the number is required

    $dec_var = 12345.6789d


    8-byte decimal floating-point number

    [double]$double_var = 12345.6789


    32 bit floating point number

    [single]$var = 123456789.101112


    Variable date and time.

    $dt_var = Get-Date


    System.Object []
    Array The index of the elements of the array begins with 0 - to refer to the first element of the array $ mas, write $ mas [0] .

    $mas = "one", "two", "three"; 

    To add an element to an array, you can write

    $mas = $mas + "four"

    Each element of the array can have its own type.

    $mas[4] = 1


    Hash tables. The difference between hash tables and arrays is that indexes are used in arrays and named keys are used in the hash table. Hash tables are built on the principle: @ {key = "value"}

    $ht = @{odin="one"; dva="two"; tri="three"} 

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

    $ht.Add("chetyre", "four")
    $ht.pyat = "five"

You probably already understood that in a variable you can write not only some specific value and notice the System.Object [] class in the table. You can also write the output of any cmdlet to a variable.

Let's analyze the combat task : we need to find out the IP address and MAC address of several computers on the network. Computer names domain-comp1, domain-comp2. Solution under the spoiler:
Show code

$MAC = Get-WmiObject -ComputerName domain-comp1, domain-comp2 -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=True  |  Select-Object -Property * | SELECT PSComputerName, @{Name="IPAddress";Expression={$_.IPAddress.get(0)}}, MACAddress, Description

What's happening:

We write the result from the Get-WmiObject cmdlet to the $ MAC variable , using which we send the WMI request to the computers specified in the -computername parameter and return the information we need from the Win32_NetworkAdapterConfiguration class . Please note that if you need to get the IP address and MAC address of the current computer, then instead of computer names, we will pass a dot to the -computername parameter. And, let's, in the following example, save the result to the file D: \ comp_mac_ip.csv:

$MAC = Get-WmiObject -ComputerName . -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=True  |  Select-Object -Property * | SELECT PSComputerName, @{Name="IPAddress";Expression={$_.IPAddress.get(0)}}, MACAddress, Description
$MAC | Export-Csv D:comp_ip_mac.csv -Encoding UTF8

Variable Scope

The scope of a variable in PowerShell can be either local or global . By default, a variable has a local scope and is limited to a scope, for example, it is available only in a function or only in the current script. The global variable is valid throughout the current PowerShell session. To designate a global variable, it is enough to write the following construction: $ Global: variable = value

$Global:var = 12

And another trick on the topic of variables ... Somehow, discussing with a colleague 1C and its Russian-language programming environment, they asked:
- Interesting, and if you set a function or variable in Russian in PowerShell, will it work?
- In theory, it should work, these are also symbols.

And yes, indeed:

function привет() { "Привет, $env:USERNAME. Может не стоит писать на русском?"
                    Start-Sleep 3
                    "Открыть Хабр?"
function открывай() { & "C:\Program Files\Internet Explorer\iexplore.exe" http://habrahabr.ru/post/242425/ }

Comparison operators and logical operators

Comparison operators and logical operators verify the equality or correspondence between two values.

  • When the condition is met, the comparison construct always returns the boolean value $ true or $ false if the condition is false.

The table below shows the comparison operators:

-eqEqual (=)
$var = "619"
$var -eq 123   #$false

-neNot equal (<>)
$var = "619"
$var -ne 123   #$true
-gtGreater than / More (>)
$var = "619"
$var -gt 123   #$true
-geGreater than or equal / Greater than or equal (> =)
$var = "619"
$var -ge 123   #$true
-ltLess than (<)
$var = "619"
$var -lt 123   #$false
-leLess than or equal (<=)
$var = "619"
$var -le 123   #$false
-likeComparison with wildcard
"Habra" -like "habr*"   #true
-notlikeComparison with wildcard mismatch
"Habra" -notlike "habr*"   #false
-containsDoes the value on the left contain the value on the right
1, 2, 3, 4, 5 -contains 3   #$true
-notcontainsIf the value on the left does not contain the value on the right, we get the truth
1, 2, 3, 4, 5 -notcontains 3   #$false
-matchUsing Regular Expressions to Match Patterns
$str = "http://habrahabr.ru"
$str -match "^http://(\S+)+(.ru)$"   #$true
-notmatchUsing Regular Expressions to Find Pattern Mismatches
$str = "http://habrahabr.ru"
$str -notmatch "^http://(\S+)+(.com)$"   #true
-replaceReplaces part or all of the value to the left of the operator
"Microhabr" -replace "Micro","Habra"   #Habrahabr

Let's take an example. In the example, we form the path to a possible user profile on the remote computer, depending on the operating system. Solution under the spoiler:
Show code

#Путь к профилю на удалённом компьютере
Function UProfile ($UCompName, $ULogin) {
        [string]$CompOS = Get-WmiObject -ComputerName $UCompName -Class Win32_OperatingSystem | SELECT Caption   #Получаем заголовок операционной системы компьютера
    if ($CompOS -match "Windows 7") {   #Если в заголовке содержится "Windows 7"
        [string]$LinkUserProfile = "\\$UCompName\d$\users\$ULogin"   #Получаем такой путь
    } elseif ($CompOS -match "Windows XP") {   #Если в заголовке содержится "Windows XP"
        [string]$LinkUserProfile = "\\$UCompName\d$\Documents and Settings\$ULogin"   #Получаем такой путь
UProfile domain-comp1 Administrator   #функция имя-компьютера логин-пользователя

Yes, here we do not check if the profile exists. But you can check. To do this, we add another condition in which we will verify the existence of the path with the Test-Path cmdlet :

#Путь к профилю на удалённом компьютере
Function UProfile ($UCompName, $ULogin) {
        [string]$CompOS = Get-WmiObject -ComputerName $UCompName -Class Win32_OperatingSystem | SELECT Caption   #Получаем заголовок операционной системы компьютера
    if ($CompOS -match "Windows 7") {   #Если в заголовке содержится "Windows 7"
        [string]$LinkUserProfile = "\\$UCompName\d$\users\$ULogin"   #Получаем такой путь
    } elseif ($CompOS -match "Windows XP") {   #Если в заголовке содержится "Windows XP"
        [string]$LinkUserProfile = "\\$UCompName\d$\Documents and Settings\$ULogin"   #Получаем такой путь    
    if (Test-Path $LinkUserProfile) { $LinkUserProfile } else { "Профиль $ULogin не существует на компьютере $UCompName" }   #Проверяем существование профиля
UProfile domain-comp1 Administrator   #функция имя-компьютера логин-пользователя

By the way, Xaegr described his regular expressions in PowerShell very well in his blog . It is worth spending a couple of hours reading and comprehending the ability to write regular expressions.

  • You can optionally specify a condition if the comparison is case sensitive. To do this, substitute the letter " c " before the operator

    $str1 = "Habr"
    $str2 = "habr"
    $str1 -ceq $str2   #$false

  • You can use multiple comparison operators using logical operators. Logical operators are listed in the table below:

-andLogical and
("Строка" -eq "Строка") -and (619 -eq 619)   #$true
-orLogical or
("Строка" -eq "Строка") -or (619 -eq 123)   #$true
-notLogical not
-not (123 -gt 324)   #$true
!(123 -gt 324)   #$true

A few words about if ... elseif and else

if ( условие1-верно ) { выполняем-код }   #если условие 1 верно, выполняем код, если нет - идём дальше
elseif ( условие2-верно ) { выполняем-код }   #необязательное условие: иначе, если условие 2 верно, выполняем код
else { выполняем-код }  #необязательное условие: если прошлое условие не верно, выполняем код

Everything is very simple. If the condition is true, we execute the code following the condition in curly brackets. If the condition is not true, then we skip the execution and see if our condition continues further.
If we find elseif, we check the new condition and also, if successful, execute the code, otherwise, we look again whether there is a continuation in the form of elseif or else.
If the condition is met, the code is executed and the elseif or else branch is skipped.

$str = ""
if ( 1 -gt 2 ) { $str = "Апельсин" } 
elseif ( $str -eq "Апельсин" ) { $str } 
else { $str = "Яблоко"; $str } 


Information output

Consider several basic options for displaying information on the screen:
  • Writing to a file using Out-File

    $str = "Hello Habr!"
    $str | Out-File D:\out_test1.txt

    or, as we said in Part I, use the " > " sign

    $str = "Hello Habr!"
    $str > D:\out_test2.txt

  • Export data to .csv file using Export-Csv

    $p = Get-Process
    $p | SELECT Name, Path | Export-Csv -Path D:\out_test3.csv

  • Writing to HTML file using ConvertTo-Html

    $h = Get-Process
    $h | ConvertTo-Html -Property Name, Path > D:\out_test4.html
    & D:\out_test4.html   #Откроем файле после формирования

    Working with HTML output is actually very nice. Having web programming skills, you can add styles and get very nice reports at the end.

The familiar Get-Content cmdlet will help us read the file.

Get-Content D:\out_test1.txt


PowerShell loops are not much different from loops in other languages. Almost everything as elsewhere:

Do while

Do as long as the condition is true

$x = 10
    $x = $x - 1    
while ($x -gt 0)

Do until

A loop that repeats a set of commands while a condition is satisfied

$x = 0
    $x = $x + 1    
until ($x -gt 10)


A cycle that repeats the same steps a certain number of times

for ($i = 0; $i -lt 10; $i++)


Collection cycle

$collection = "Имя-Компьютера1", "Имя-Компьютера2", "Имя-Компьютера3"
foreach ($item in $collection)

Writing functions

  • Functions in PowerShell have the following structure:

    function имя-функции ([параметр1, ..., параметрN]) 

  • Functions do not have to return a result.
  • When calling a function, all parameters are separated by spaces.

For example, a function to get the square of a number on PowerShell would look like this:

function sqr ($a)
      return $a * $a
sqr 2   #Результат: 4

And finally, an example of a function that will help us perform transliteration. In this example, just everything that we considered today:
Show code

function Translit ([string]$inString)
    $Translit = @{    #Создаём хеш-таблицу соответствия символов
    [char]'а' = "a"
    [char]'А' = "A"
    [char]'б' = "b"
    [char]'Б' = "B"
    [char]'в' = "v"
    [char]'В' = "V"
    [char]'г' = "g"
    [char]'Г' = "G"
    [char]'д' = "d"
    [char]'Д' = "D"
    [char]'е' = "e"
    [char]'Е' = "E"
    [char]'ё' = "yo"
    [char]'Ё' = "Yo"
    [char]'ж' = "zh"
    [char]'Ж' = "Zh"
    [char]'з' = "z"
    [char]'З' = "Z"
    [char]'и' = "i"
    [char]'И' = "I"
    [char]'й' = "j"
    [char]'Й' = "J"
    [char]'к' = "k"
    [char]'К' = "K"
    [char]'л' = "l"
    [char]'Л' = "L"
    [char]'м' = "m"
    [char]'М' = "M"
    [char]'н' = "n"
    [char]'Н' = "N"
    [char]'о' = "o"
    [char]'О' = "O"
    [char]'п' = "p"
    [char]'П' = "P"
    [char]'р' = "r"
    [char]'Р' = "R"
    [char]'с' = "s"
    [char]'С' = "S"
    [char]'т' = "t"
    [char]'Т' = "T"
    [char]'у' = "u"
    [char]'У' = "U"
    [char]'ф' = "f"
    [char]'Ф' = "F"
    [char]'х' = "h"
    [char]'Х' = "H"
    [char]'ц' = "c"
    [char]'Ц' = "C"
    [char]'ч' = "ch"
    [char]'Ч' = "Ch"
    [char]'ш' = "sh"
    [char]'Ш' = "Sh"
    [char]'щ' = "sch"
    [char]'Щ' = "Sch"
    [char]'ъ' = ""
    [char]'Ъ' = ""
    [char]'ы' = "y"
    [char]'Ы' = "Y"
    [char]'ь' = ""
    [char]'Ь' = ""
    [char]'э' = "e"
    [char]'Э' = "E"
    [char]'ю' = "yu"
    [char]'Ю' = "Yu"
    [char]'я' = "ya"
    [char]'Я' = "Ya"
    $TranslitText = ""
    foreach ($CHR in $inCHR = $inString.ToCharArray())
        if ($Translit[$CHR] -cne $Null) 
            { $TranslitText += $Translit[$CHR] }   #аналог записи $TranslitText = $TranslitText + $Translit[$CHR] 
            { $TranslitText += $CHR }
    return $TranslitText
Translit Хабрахабр   #Вывод: Habrahabr


Now we know enough information to start diving deeper into PowerShell. In this part, we met with variables, data types, sorted out the output of information, comparison operators, loops ... Look, it turns out that starting is not so difficult!

Keep calm and learn PowerShell.

To be continued...

Additional Information

Also popular now: