K1K7V

            Cons:

              Powershell 7 Note: Input redirection not supported*
              (works in Unix since 1970), so you have 
              to modify your script instead..
              
            *) http://blog.kondratev.pro/2017/08
               /input-redirection-with-powershell.html

            Pros:

              But why use PowerShell.. on Linux?
              One reason is the beauty of the language and 
              the powerful capability of the object-piping*.
              
            *) https://www.starwindsoftware.com
               /blog/using-powershell-on-linux

## HOW TO SURVIVE IN THE KINGDOM OF CROOKED MIRRORS 
   (BEHIND FIREWALL, SQUID):
===================================================

1. Windows Terminal: https://github.com/microsoft/terminal
   Powershell 7: https://github.com/PowerShell/PowerShell/releases

  o  Install Chocolatey as in https://chocolatey.org/docs/installation
  
  o  Install powershell 7
  
       choco install powershell-preview
       (located here C:\Program Files\PowerShell\7-preview)
       
      NB! if install does not succeed, try:

        1. Remove Powershell Preview using Control Panel -> Programs and Features.
        
        2. choco list --local-only | Select-String -Pattern 'power'
           choco uninstall powershell-preview

  o  Install Windows Terminal 
     (requires Windows 19.03 and newer, check with Winver app)

       choco install microsoft-windows-terminal
       ..
      NB! microsoft-windows-terminal package files install completed.
          Performing other installation steps.
          ERROR: This package requires at least 
          Windows 10 version 1903/OS build 18362.x.
          The install of microsoft-windows-terminal was NOT successful.
          ..

  o  Configure Windows Terminal (if installed):

       find in Settings:

         "commandline" : "powershell.exe",

       replace with:

        "commandline" : "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
        "fontFace" : "Consolas",
        "fontSize" : 16,
        
2. Install Debian Linux using WSL (sometimes reboot is required):

  Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  Invoke-WebRequest -Uri https://aka.ms/wsl-debian-gnulinux -OutFile Debian.appx -UseBasicParsing
  Rename-Item ./Debian.appx ./Debian.zip
  Expand-Archive ./Debian.zip ./Debian
  cd .\Debian\
  .\debian.exe
  
  NB! if install does not succeed, try:

    a. Remove Debian app previously installed from Microsoft Store
    
    b. wsl --list
       wsl --terminate Debian
       wsl --unregister Debian
       wsl --setdefault Debian
       
    c. on old Windows builds wsl works not the way you may like, restart or stop LXSS manager service instead.
    
    d. WSL user/password problems
    
      https://winaero.com/blog
      /reset-password-wsl-linux-distro-windows-10/

3. Powershell 7 on Debian 10 "Buster"

  https://docs.microsoft.com/en-us/powershell/scripting/install
  /installing-powershell-core-on-linux?view=powershell-7
  
  $ sudo apt-get update
  $ sudo apt-get install -y \
          less \
          locales \
          ca-certificates \
          libicu63 \
          libssl1.1 \
          libc6 \
          libgcc1 \
          libgssapi-krb5-2 \
          liblttng-ust0 \
          libstdc++6 \
          zlib1g \
          curl
  $ curl -L https://github.com/PowerShell/PowerShell/releases/download/v7.0.0-rc.2/powershell-7.0.0-rc.2-linux-x64.tar.gz -o /tmp/powershell.tar.gz

  $ sudo mkdir -p /opt/microsoft/powershell/7-preview

  $ sudo tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7-preview

  $ sudo chmod +x /opt/microsoft/powershell/7-preview/pwsh

  $ sudo ln -s /opt/microsoft/powershell/7-preview/pwsh /usr/bin/pwsh

  # Start PowerShell
  $ pwsh

4. Create file with hints like 'how to perform most needed actions (Portfolio)':

  https://www.red-gate.com/simple-talk/sysadmin/powershell
    /powershell-one-liners-collections-hashtables-arrays-and-strings/


## ANNEX A. REGEX -- SHORT CHEAT SHEET
======================================

Special Regex Characters: 

  . + * ? ^ $ | () [] {}
  
  https://www.ntu.edu.sg/home/ehchua/programming/howto/Regexe.html
  
Minimized:

  \           -- escape from character set
  ^ $         -- anchors (line, beginning, line end)
  .           -- any
  []          -- list, range
  ? * + {n,m} -- greedy multipliers:  0..1  0..n  1..n
  *? +?       -- lazy multipliers:  0..1  0..n  1..n
  |           -- OR (greedy) 
  (a|b)       -- OR (lazy) 
  ()          -- group
  \1..\9      -- backreference (Unix style)
  `$1..`$9    -- backreference (Powershell style)
  
Examples (tested with PS7rc2) 

1. Multiline echo

   PS> Write-Output "one
    >> two
    >> three" | % { $_ -replace "\n"," " }
   one two three
   
2. Multiline echo in script

   PS> Write-Output genscipt.ps1
   Write-Output @"
   one
   two
   three
   "@ | Out-File -FilePath onetwothree
   PS> .\genscipt.ps1
   PS> wsl
   $ cat onetwothree | xxd
   00000000: 6f6e 650a 7477 6f0a 7468 7265 650d 0a    one.two.three..

3. Good-enough :)

   PS> Write-Output "1
    >> 2
    >> 3" | Out-File -FilePath 123
   PS> Get-Content -Raw 123 | % { $_ -replace "\n"," " }
     2 3
   PS> Get-Content -Raw 123 | % { $_ -replace "\n"," " } | 
    >> % { $_ -replace "\r","X" }
   1 2 3X


## ANNEX B. POWERSHELL -- SHORT CHEAT SHEET
===========================================

# CHECK POWERSHELL VERSION
--------------------------

Use $PSVersionTable.PSVersion to determine the engine version.

  PS> $PSVersionTable.PSVersion

  Major  Minor  Patch  PreReleaseLabel BuildLabel
  -----  -----  -----  --------------- ----------
  7      0      0      rc.2
  
Located in

  C:\Program Files\PowerShell\7-preview


# PERMANENT CONFIGURATION
--------------------------

  PS > cat C:\Users\Administrator\Documents\WindowsPowerShell\profile.ps1

  "Welcome to Hell"
  $PSDefaultParameterValues['Out-File:Encoding']="UTF8"
  $PSDefaultParameterValues

  Name                           Value
  ----                           -----
  Out-File:Encoding              Unicode
  
See also 

  https://gist.github.com/jpoehls/2406504


# COMMANDS
----------

For help on any commandlet, use Get-Help

  Get-Help Get-Service

To get a list of available commandlets, use Get-Command

  Get-Command

To get a list of all properties and methods of an object, use Get-Member

  Get-Service | Get-Member


# SETTING A SECURITY POLICY
---------------------------

View and change security policies using Get-ExecutionPolicy and Set-ExecutionPolicy

  Get-Executionpolicy 
  Set-Executionpolicy remotesigned
  
Script execution

  powershell.exe -noexit &"c:\myscript.psl"


# FUNCTIONS
-----------

Parameters are separated by spaces. Return is optional.

  function sum ( [int]$a, [int]$b)
  {
    return $a + $b
  }
  sum 4 5
  
Write your functions into a script file. Try this on the PowerShell command line:

  PS> . .\MyFunctions.ps1  
  
The dot operator is used for script include*2


# VARIABLES:
------------

Must start with $

  $а  =  32

May have the type

  [int]$a =  32

Arrays: Initialization:

  $а  =  1,2,4,8

Item request:

  $b  =  $а[3]


# CONSTANTS
-----------

Create without $

  Set-Variable -name b -value 3.142 -option constant

Use with с $

  $b


# OBJECT CREATION
-----------------

Creating an instance of a COM object

  New-Object -comobject <ProgID>
  
  $а = New-Object -comobject "wscript.network"
  $a.username
  
Creating an instance of .Net Framework object. Parameters can be passed if neeeded

  New-Object -type <.Net Object>
  $d = New-Object -Type System.DateTime 2006,12,25
  $d.get DayOfWeek()


# USER INPUT
------------

To get input from the user, use Read-Host

  $а = Read-Host "Enter your name"
  Write-Host "Hello" $a
  
Read from file
 
  param(
      [parameter(ValueFromPipeline)]$string
  )

  if ($string) {
    $in = "$string"
  } else {
    $in = read-host -prompt "input"
  }

  Write-Host $in
  
File to Hash

  PS> Get-Content ./a.txt
  Version = 1.3
  Name = First

  PS> $x = Get-Content ./a.txt -raw | convertfrom-stringdata; $x

  Name                           Value
  ----                           -----
  Version                        1.3
  Name                           First

  PS> $x = get-content ./a.txt -raw | convertfrom-stringdata; $x.Name
  First

File to Array

  PS> $x = @(get-content ./a.txt ) ; $x
  Version = 1.3
  Name = First

  PS> $x = @(get-content ./a.txt ) ; $x[1]
  Name = First
  
  
# EXPLODE
---------

  PS> cat .\Game.txt
  chess         male        шахматы
  chess_board   malelaud    шахматная_доска
  rock          vanker      ладья
  knight        ratsu       конь
  bishop        oda         слон
  queen         lipp        ферзь
  king          kuningas    король
  pawn          ettur       пешка

  PS> cat .\Game.txt | % { $D = $_ -split "\s+"; $D[1] }
  male
  malelaud
  vanker
  ratsu
  oda
  lipp
  kuningas
  ettur

  PS> cat .\Game.txt | % { $D = $_ -split "\s+"; $D[2] }
  шахматы
  шахматная_доска
  ладья
  конь
  слон
  ферзь
  король
  пешка
  
  PS> $x = "1101 11 10010" -split "\s+"
  PS> $x[0]
  1101
  PS> $x[1]
  11
  PS> $x[2]
  10010


# STRING LENGTH
---------------

  PS> "abc" |  % { $_.length }
  3


# MATCH *3
----------

  # This expression returns true if the pattern 
  # matches big, bog, or bug.

  "big" -match "b[iou]g"


# FIND
------

  PS> get-content .\game.txt
  chess         male        шахматы
  chess_board   malelaud    шахматная_доска
  rock          vanker      ладья
  knight        ratsu       конь
  bishop        oda         слон
  queen         lipp        ферзь
  king          kuningas    король
  pawn          ettur       пешка
 
  PS> $x = get-content .\game.txt
  PS> $x | Select-String -Pattern "o(d|p)"

  bishop        oda         слон
      --

  PS> $x | Select-String -Pattern "o(d|p)" -AllMatches

  bishop        oda         слон
      --        --


# REPLACE
---------

Search and Replace. BackReference and BackTick.

  PS> Write-Output "ABA" | % { $_ -Replace "(B)","`$1`$1" }
  ABBA
  
  
# AWK'ish
---------

  PS> cat ./api.ps1
  Function AWKISH {
    Begin { "revisiting AWK BEGIN" }
    # Executes once for each pipeline object
    Process { Write-Output $_ }
    End { "revisiting AWK END" }
  }
  
  PS> cat .\game.txt | AWKISH
  revisiting AWK BEGIN
  chess         male        шахматы
  chess_board   malelaud    шахматная_доска
  rock          vanker      ладья
  knight        ratsu       конь
  bishop        oda         слон
  queen         lipp        ферзь
  king          kuningas    король
  pawn          ettur       пешка
  revisiting AWK END


# VALIDATORS
------------

Validators

Boolean

  (true|false)

Integer

  [+-]?[1-9][0-9]*|0

Real. If you also want to match numbers with exponents, you can use:

  [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?



# CONSOLE OUTPUT
----------------

Variable name

  $a

or

  Write-Host $a -foregroundcolor "green"


# PASS THROUGH PIPE
-------------------

% -- important ForEach commandlet

  PS> cat .\yellow.txt
  In the town where I was born
  Lived a man who sailed to sea
  And he told us of his life
  In the land of submarines

  PS> cat .\yellow.txt | % { $_ }
  In the town where I was born
  Lived a man who sailed to sea
  And he told us of his life
  In the land of submarines
  
  
# PASSING COMMAND-LINE ARGUMENTS 
--------------------------------

Passed to the script, separated by spaces

  myscript.ps1 server1 benp 

Are obtained in the script in the $args array

  $servername = $args[0] 
  $username = $args[1]


# MISCELLANEOUS
---------------

Line break `
............

  Get-Process | Select-Object `
  name, ID


Comments #
..........

  # the code from here is not executed 


Multiple commands on the same line
..................................

  $а=1;$Ь=3;$с=9


Sending output data over a pipe to another command |
....................................................

  Get-Service | Get-Member


Do While Loop
.............

Repeats the set of commands until the condition is met

  $а=1
  Do {$a; $а++ } 
  While ($а -lt 10)
 
 
The Do Until Loop
.................

Repeats the set of commands until the condition is met

  $а=1
  Do {$a; $а++}
  Until ($a -gt 10)


The For Loop
............

Repeats the same steps a certain number of times

  For ($a=1; $a –le 10; $a++) {$a}


Foreach loop
............

Loop through a collection of objects

  Foreach ($i in Get-Childitem c:\windows) {$i.name; $i.creationtime}


The If Statement
................

Depending on the specified condition, a particular section of code is executed

  $а = "white"
  if ($a -eq "red")
    {"The colour is red"}
  elseif ($a -eq "white")
    {"The colour is white"}
  else
    {"Another colour"}


Switch statement
................

Another way to execute a specific section of code depending on the specified conditions

  $а = "red"
  switch ($a)
  {
    "red"   {"The color is red"}
    "white" {"The color is white"}
    default {"Another color"}
  }


Writing to a simple file 
........................

For a simple text file, use Out-File or >

  $а = "Hello world" 
  $а | out-file test.txt 

Or use > to output the results of the script to a simple text file 

  .\test.ps1 > test.txt


Reading from a file
...................

Use Get-Content to create an array of strings. Then loop through the array

  $а = Get-Content "c:\servers.txt"
  foreach ($i in $a) {$i}


Writing to an HTML file 
.......................

Use ConvertTo-Html and >

  $a = Get-Process
  $a | Convertto-Html -property Name,Path,Company > test.htm


Writing to a CSV file
.....................

Use Export-Csv and Select-Object to filter the output data

  $а = Get-Process
  $а | Select-Object Name,Path,Company | Export-Csv -path test.csv
  

# GET-ALIAS
-----------

  PS> get-alias ?

CommandType     Name
-----------     ----
Alias           % -> ForEach-Object
Alias           ? -> Where-Object
Alias           h -> Get-History
Alias           r -> Invoke-History

Windows PowerShell has a special Out-File command for this, better known in the ">" symbol variant*1.

Well, it's not exact, but good enough to memorize it.


# OUTPUT FORMAT WITH OUT-FILE
-----------------------------

  PS> Write-Output "kukarekuuu..!" | Out-File demo -Encoding ascii
  PS> Get-Content demo
  kukarekuuu..!
 
also

  ascii    bigendianunicode  default  oem   string  
  unicode  unknown           utf32    utf7  utf8
  

# INPUT REDIRECTION WITH POWERSHELL
-----------------------------------

PowerShell doesn't support input redirection:

  PS> mysql -u root < some.sql
  ERROR

Use Get-Content instead:

  PS> Get-Content ./some.sql | mysql


# FORMAT STRING
---------------

  PS> $m = "alpha bravo charlie" -split "\s+"
  PS> "first {0} second {1} third {2}" -f $m[2], $m[1], $m[0]
  first charlie second bravo third alpha


# GET-RANDOM *4
---------------

Example 1: Get a random integer between 0 and Int32.MaxValue.

  PS> Get-Random
  3951433

Example 2: Get a random integer between -100 and 99

  PS> Get-Random -Minimum -100 -Maximum 100
  56

Example 3: Get a random floating-point number

  PS> Get-Random -Minimum 10.7 -Maximum 20.93
  18.08467273887

Example 4: Get several random integers from an array

  PS> 1, 2, 3, 5, 8, 13 | Get-Random -Count 3
  3
  1
  13

Example 5: Randomize an entire collection

  PS> 1, 2, 3, 5, 8, 13 | Get-Random -Count ([int]::MaxValue)
  2
  3
  5
  1
  8
  13

Example 6: Get a random non-numeric value

  PS> "red", "yellow", "blue" | Get-Random
  yellow

Example 7: Use the Count parameter

  PS> Get-Random -Count 3 -Maximum 10
  9
  0
  8

Example 8: Roll fair dice

This example rolls a fair die 1200 times and counts the outcomes. The first command, For-EachObject repeats the call to Get-Random from the piped in numbers (1-6). The results are grouped by their value with Group-Object and formatted as a table with Select-Object.

  PS> 1..1200 | % { 1..6 | Get-Random } | 
   >> Group-Object | Select-Object Name,Count

  Name Count *
  ---- -----
  1      206
  2      199
  3      196
  4      226
  5      185
  6      188
  
*) How many times:206+199+196+226+185+188=1200

# OLD DOG, NEW TRICKS
---------------------

Inline if in Powershell 7
.........................

  PS> $a = 0; $a++ ; $a
  1
  PS> $b = $a -lt 0; $b
  False
  PS> $b = $a -lt 0 ? $false : $true; $b
  True

Seialize Object, Write to json file, Restore Object
...................................................

  $s=Get-Service
  $s | ConvertTo-Json > services.json
  $z = Get-Content -Raw -Path services.json | ConvertFrom-Json
  $z | Select-Object DisplayName
  
Minimum, Maximum, Referenced
............................

First name starts and ends with the same letter

   PS> $p = Get-Content .\people.txt ; $p
   Malwina Sidorova MoreA MoreB MoreC
   ..
   PS> $q = $p | % { $pc = $_ -split '\s+' ; $pc[0] }; $q
   Sidorova
   ..
   PS> $q | % { if ($_ -imatch '^([a-zöäüõšž]).*?\1$') 
     >>  { $p[$q.IndexOf($_)] } }
     
Shortest name

   PS> $mx = 1000; $q | % { if ($mx -ge $_.Length) 
    >>   { $mx = $_.Length; $i = $q.IndexOf($_); $_ } } ; $p[$i]
   
Longest name

   PS> $mx = 1; $q | % { if ($mx -le $_.Length) 
    >>   { $mx = $_.Length; $i = $q.IndexOf($_); $_ } } ; $p[$i]

  
Random Date, Unix style*5*6
...........................

  PS> $b = (New-Object -Type DateTime -ArgumentList 1970,1,1,0,0,0,0).
   >>   AddSeconds($(Get-Random)); $b

  Friday, March 8, 1996 11:09:19 PM

  PS> "{0}{1:yyMMdd}xxxx" -f 
   >>   (20-[math]::floor($b.year/100) -eq 0 ? 5 : 3), $b
  3960308xxxx


# REFERENCE
-----------

*1) Frank Koch, Free PowerShell Book

  https://www.infoq.com/news/2007/07/PowerShell-Book/
      
*2) Powershell, Functions

  https://stackoverflow.com/questions/6016436
      /in-powershell-how-do-i-define-a-function-in-a-file-
      and-call-it-from-the-powersh

*3) Powershell, Regular Expressions

    https://docs.microsoft.com/en-us/powershell/module
    /microsoft.powershell.core/about
    /about_regular_expressions?view=powershell-7

*4) Get-Random

    https://docs.microsoft.com/en-us/powershell/module
    /microsoft.powershell.utility/get-random?view=powershell-7
    
*5) Formatted output

    https://ss64.com/ps/syntax-f-operator.html

*6) Random date and time

    https://www.reddit.com/r/PowerShell/comments/77oeuz/getrandomdate/
    
    
# TIPS
------

1. UTF8 with Perl
 
  $ sudo apt install libutf8-all-perl
  ..
  $ Write-Output "Сосна, Сосна, я Береза" | \
    perl -Mutf8::all -pe 's/([а-ю])([^а-ю])/\1"\2/g' | \
    perl -Mutf8::all -pe 's/([^А-Юа-ю]|^)([А-Юа-ю])/\1"\2/g'

  "Сосна", "Сосна", я "Береза" *
  
*) Центр, Цвет ветки, К 60-летию, 2019


2. Flowgorithm

  a. Copy-Paste input data from UTF8 no bom unix EOL
  b. Declare multiple variables in one block (comma separated)
  c. [ "MUST KNOW" ] toolbar buttons: 
       bubbles, source code viewer, function manager
  d. Function arguments: by Value and by Reference
  e. Read and understand <xml> based fprg format
  f. Cook fprg from pseudocode


# EXERCISES
-----------

Topic: Generate and cook data (notepad++, powershell)
.....................................................

1.1. Read file with female or male names. Build an array. Generate random name.

  Find '^.$' Replace with ''
  Find '^\s+$' Replace with ''
  Find '\n\n+' Replace with '\n'
 
  $x = @(Get-Content .\girls.txt -raw)
  $a = ($x | % { $_ -Replace "\s+"," " }) -split ' '
  $a | Get-Random
  
1.2. Read file with top 500 surnames. Build two arrays depending on gender. Generate random surname.

1.3. Generate random age (15..50) weight (40..80) height (150..190) 

1.4. Generate random color from the list below:

     black gray white brown red pink orange yellow green blue violet

1.5. Create following API based on exercises 1..4

     cook-gender cook-name cook-surname cook-eyes cook-hair cook-height cook-weight cook-age
     
1.6. Create table 20 rows toll containing random cell values:

     name eyes hair height weight age
     
1.7. a) Dump, build array of hashes variable. b) Read array of hashes.

1.8. Given: some bool int real string variables in random order.
   Cook single string of values to initialize them.
   
1.9. Generate spice netlists of R, C, L, E, I, OA analog electronic circuits

1.10 Generate spice netlist of NAND2 circuit from truth table (CC, no memory)


Topic: Analyze and process data 
...............................

Flowgorithm, cat/grep/sed/awk/perl, powershell, sql, c/c++/c#(LINQ). Exercises from general purpose task books:

  2.1. Abramyan 1000 (201x)
  2.2. Goldenberg I and II (1903)
  2.3. ..

 
Topic: Presentation
...................

  3.1. HTML/CSS/JS from text
  3.2. Drawn circuit from netlist
  3.3. flowchart from pseudocode
