JC88o

                    To distinguish Anna-Maria from Get-Alias use
                    Get-Verb | Measure-Object
                    Count    : 98

# POWERSHELL PORTFOLIO


## PowerShell 7 / Windows Terminal

Install Powershell7 Preview:

  > iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI -Preview"

Install Windows Terminal (preview) from Microsoft Store.
Configure Windows Terminal [v]:

find:

    "commandline" : "powershell.exe",

replace with:

    "commandline" : "C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe",
    "fontFace" : "Consolas",
    "fontSize" : 16,
  
  
(0) 2+2=4

zero.ps1

  $n1 = Read-Host -Prompt 'Enter first number'
  $n2 = Read-Host -Prompt 'Enter second number'
  [int]$x = [int]$n1 + [int]$n2
  Write-Host $x
  
------

(1) binary to decimal

  PS> "1101" | % { [convert]::ToInt32($_,2) }
  13
  
------
  
(2) split string by regular expression

  PS> "1101  11 10010" -split "\s+"
  1101
  11
  10010
  
------
  
(3) read tape of { c (- 0,1,\s }

  PS> "1000100  1000110 1001011" -split "\s+" | % { [char][convert]::ToInt32($_,2) }
  D
  F
  K

------

(4) pass through pipe, % -- important ForEach commandlet

  PS> cat .\ansi.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 .\ansi.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
  
------

(5) convert to {0,1,\s} tape

  PS> cat .\ansi.txt | % { $_.toCharArray() | % { $_ } }
  
  $s = ""
  cat .\ansi.txt | 
  % { $_.toCharArray() | 
  % { $s+=[Convert]::ToString([int]$_,2); $s+=" " } }
  $s

------

(6) shorter if
 
  $CarColor = 'Blue'
  @{ $true = 'The car color is blue'; $false = 'The car color is not blue'
  [$CarColor -eq 'Blue']
  
------

(7) string length
  
  PS> "abc" |  % { $_.length }
  3
  
------

(8) Back and Forth

s.ps1

  $a = $s = ""
  Get-Content .\ansi.txt | 
  % { $_.toCharArray() | 
      % { $s+=[Convert]::ToString([int]$_,2); $s+=" " } 
      $s+="1010 "
  }
  $s
  "oooooooo"
  $s -split "\s+" | 
  % { if ($_.length -ne 0) { $a += [char][Convert]::ToInt32($_,2) } }
  $a

------
  
(9) 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]+)?
  
------

(10) Learn AWK/ARDUINO/PROCESSING template: BEGIN LOOP END
     include the functions into your session.
     Learn $input variable.
     
  PS> cat myfunc.ps1  
  Function Echo-Pipe {
    Begin { "revisiting AWK BEGIN" }
    # Executes once for each pipeline object
    Process { echo $_  }
    End { "revisiting AWK END" }
  }

  Function Echo-Pipe2 { foreach ($i in $input) { $i } }

  PS> . .\myfunc.ps1
  PS> cat data.txt | Echo-Pipe
                                                                          revisiting AWK BEGIN
  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
  revisiting AWK END

  PS> cat data.txt | Echo-Pipe2

  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

------

(11) Arguments

foo.ps1

  param(  
  [Parameter(
      Position=0, 
      Mandatory=$true, 
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true)
  ]
  [Alias('Arguments')]
  [String[]]$Args
  ) 

  foreach($path in $Args) {
    Write-Host "file path is: $path"
  }
  
------

(12) Best Practice: Use named parameters avoid positional and partial

   Get-Alias echo Write-Output
   Get-Alias cat  Get-Content

  ! #1: Use full cmdlet name in scripts (not alias)
        Get-Command -CommandType Alias ~300                                                                           
          % -> ForEach-Object
          ? -> Where-Object
  B #2: Use named parameter in scripts (not positional and partial parameter)
  T #3: Avoid Write-Host
  ! #8: Use WhatIf and Confirm parameters
    WhatIf : Only displays the objects that would be affected and what changes would be made to those objects (without the worry of modifying those objects)
    Confirm: Stops processing before any changes are made  to an object.
  ! #10: Avoid empty Catch block
  ! #11: Use Set-StrictMode in your dev scripts
         Set-StrictMode -Version Latest
  ! #21: Use #Requires statement
        #Requires -Version 3.0 
        #Requires -Modules ActiveDirectory, DnsClient
        #Requires -RunAsAdministrator
where
    
  B -- inherited from common practices
  T -- like Taylor rules for Linux
  ! -- Important

------

(13) Imortant ? Commandlet.
     4 ways to operate with Windows Services. 

  services.msc
  
  Get-Service | ? {$_.StartType -eq "Automatic"}
  PS#> Start-Service sshd
  PS#> Set-Service -Name sshd -StartupType 'Automatic'
  
  CMD#> net start|stop|pause <servicename>
  CMD#> sc start|stop|create|delete|query <servicename>
  
*) ? -- Where-Object

-----

(14) search

  $Events | Select-String -InputObject {$_.message} -Pattern 'Failed'
  
  PS> cat .\data.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 .\data.txt | Select-String -Pattern '^[^AEIOU]'

  Lived a man who sailed to sea
  
Another example

  $x | Select-String -InputObject {$_.message} -Pattern '[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?'

------

(15) Search and Replace. BackReference and BackTick.

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

------

(16) 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

------

(17) Validate input. Attention EE-style: 1,5 but not 1.5

  PS> $x=Read-Host
  33 bananas
  PS> $x -match '^\s*[-+]?[0-9]*,?[0-9]+([eE][-+]?[0-9]+)?\s*$'
  False
  PS> $x=Read-Host
     12,5
  PS> $x -match '^\s*[-+]?[0-9]*,?[0-9]+([eE][-+]?[0-9]+)?\s*$'
  True

------

(18) Read file line by line in PowerShell

  PS> Get-Content .\file.txt | ? {$_ -match $regex} | % { $_ }

------

(19) Read argument

  args.ps1

    Get-Content $args[0]

  EOF

  PS> .\args.ps1 .\file.txt

------

(20) Read variable from file

$text = Get-Content $filePath -Raw

------

(21) Write variable to a file

  $hello | Out-File c:\debug.txt

Basic idea -- Store Escape character in variable first:

  PS\> $esc = "$([char]27)".
  
(22) Coloring text

  Black:   $esc[90m
  Dark:    $esc[90m
  Red:     $esc[91m
  Green:   $esc[92m
  Yellow:  $esc[93m
  Blue:    $esc[94m
  Magenta: $esc[95m
  Cyan:    $esc[96m
  White:   $esc[97m
  
  Default: $esc[0m

Synthetic command (visible colors, or how it works in Powershell v.5.1):

"$esc[90mD$esc[91mR$esc[92mG$esc[94mB$esc[93mY$esc[96mC$esc[95mM$esc[0m"
"$esc[90mDARK$esc[91mRED$esc[92mGREEN$esc[94mBLUE$esc[93mYELLOW$esc[96mCYAN$esc[95mMAGENTA$esc[0m"
  
Reset to defaults:

  Reset all: $esc[0m
  

# LINKS TO (n):

   1. https://devblogs.microsoft.com/scripting
      /use-powershell-to-easily-convert-decimal-to-binary-and-back/

   2. https://stackoverflow.com/questions/29119383
      /powershell-use-regular-expression-to-split-a-string
     
   6. https://adamtheautomator.com
      /a-simpler-ifthen-conditional-logic-in-powershell/
     
   9. https://www.ntu.edu.sg/home/ehchua/programming/howto/Regexe.html
      https://www.regular-expressions.info/floatingpoint.html
     
  10. https://stackoverflow.com/questions/885349
      /how-do-i-write-a-powershell-script-that-accepts-pipeline-input
      
  11. https://stackoverflow.com/questions/885349
      /how-do-i-write-a-powershell-script-that-accepts-pipeline-input

  12. http://powershell-guru.com/powershell-best-practice-2-
      use-named-parameters-not-positional-and-partial-parameters/

  14. https://docs.microsoft.com/en-us/powershell/module
      /microsoft.powershell.utility/select-string?view=powershell-6
      
  15. https://stackoverflow.com/questions/53867147
      /grep-and-sed-equivalent-in-powershell
      
  16. https://docs.microsoft.com/en-us/powershell/module
      /microsoft.powershell.utility/out-file?view=powershell-6

  17. https://devblogs.microsoft.com/scripting
      /powertip-use-powershell-to-check-string-for-a-match/
      
  18. https://stackoverflow.com/questions/33511772
      /read-file-line-by-line-in-powershell
      
  19. https://stackoverflow.com/questions/5592531
      /how-to-pass-an-argument-to-a-powershell-script      

  20. https://stackoverflow.com/questions/7976646
      /powershell-store-entire-text-file-contents-in-variable
  
  21. https://stackoverflow.com/questions/19122755
      /output-echo-a-variable-to-a-text-file
    
  22. https://powershell.org/forums/topic
      /how-to-use-ansi-vt100-formatting-in-powershell-ooh-pretty-colors/
  

# ANNEX A. POWERSHELL BEST PRACTICES 

!  #1: Use full cmdlet name in scripts (not alias)
       Get-Command -CommandType Alias ~300    
         % -> ForEach-Object
         ? -> Where-Object
B  #2: Use named parameter in scripts 
       (not positional and partial parameter)
T  #3: Avoid Write-Host
   #4: Use CIM cmdlet (not WMI cmdlet)
B  #5: Avoid excessive comments (over-commenting)
   #6: Use singular noun for cmdlet (not plural noun, boat -- boats)
   #7: Use approved verb 
       (not unapproved verb, Get-Verb vs all other verbs)
!  #8: Use WhatIf and Confirm parameters
       WhatIf : Only displays the objects that would be affected 
                and what changes would be made to those objects 
                (without the worry of modifying those objects)
       Confirm: Stops processing before any changes are made 
                to an object.
B  #9: It is recommended to use region statement to split your code 
      into logical parts in your scripts.
! #10: Avoid empty Catch block
! #11: Use Set-StrictMode in your dev scripts
       Set-StrictMode -Version Latest
  #12: Avoid Out-Null cmdlet
  #13: Avoid doublequotes in strings if not necessary 
       (Use proper quotes: 'strict' or "weak")
  #14: Specify the extension for applications
  #15: Execute scripts with -NoProfile parameter
  #16: Update the help
  #17: Use the same parameter name than the native one
  #18: Don’t use Notepad as a script editor (use PS ISE or VS Code)
  #19: Check parameters with PSBoundParameters
  #20: Use full key name for calculated properties
! #21: Use #Requires statement
         #Requires -Version 3.0 
         #Requires -Modules ActiveDirectory, DnsClient
         #Requires -RunAsAdministrator
  #22: Use Obsolete attribute for backwards compatibility
B #23: Avoid the horizontal scrolling (too long one-liners commands)*

That's it.

*) http://powershell-guru.com
     /powershell-best-practice-23-avoid-the-horizontal-scrolling-
     too-long-one-liners-commands/


# ANNEX B. Get-Verb

  PS D:\TMP\Ps> Get-Verb | Measure-Object

  Count    : 98
  Average  :
  Sum      :
  Maximum  :
  Minimum  :
  Property :

  PS D:\TMP\Ps> Get-Verb

  Verb        Group
  ----        -----
  Add         Common
  Clear       Common
  Close       Common
  Copy        Common
  Enter       Common
  Exit        Common
  Find        Common
  Format      Common
  Get         Common
  Hide        Common
  Join        Common
  Lock        Common
  Move        Common
  New         Common
  Open        Common
  Optimize    Common
  Pop         Common
  Push        Common
  Redo        Common
  Remove      Common
  Rename      Common
  Reset       Common
  Resize      Common
  Search      Common
  Select      Common
  Set         Common
  Show        Common
  Skip        Common
  Split       Common
  Step        Common
  Switch      Common
  Undo        Common
  Unlock      Common
  Watch       Common
  Backup      Data
  Checkpoint  Data
  Compare     Data
  Compress    Data
  Convert     Data
  ConvertFrom Data
  ConvertTo   Data
  Dismount    Data
  Edit        Data
  Expand      Data
  Export      Data
  Group       Data
  Import      Data
  Initialize  Data
  Limit       Data
  Merge       Data
  Mount       Data
  Out         Data
  Publish     Data
  Restore     Data
  Save        Data
  Sync        Data
  Unpublish   Data
  Update      Data
  Approve     Lifecycle
  Assert      Lifecycle
  Complete    Lifecycle
  Confirm     Lifecycle
  Deny        Lifecycle
  Disable     Lifecycle
  Enable      Lifecycle
  Install     Lifecycle
  Invoke      Lifecycle
  Register    Lifecycle
  Request     Lifecycle
  Restart     Lifecycle
  Resume      Lifecycle
  Start       Lifecycle
  Stop        Lifecycle
  Submit      Lifecycle
  Suspend     Lifecycle
  Uninstall   Lifecycle
  Unregister  Lifecycle
  Wait        Lifecycle
  Debug       Diagnostic
  Measure     Diagnostic
  Ping        Diagnostic
  Repair      Diagnostic
  Resolve     Diagnostic
  Test        Diagnostic
  Trace       Diagnostic
  Connect     Communications
  Disconnect  Communications
  Read        Communications
  Receive     Communications
  Send        Communications
  Write       Communications
  Block       Security
  Grant       Security
  Protect     Security
  Revoke      Security
  Unblock     Security
  Unprotect   Security
  Use         Other
