Private/Wissen/B_Basic/B14_Parsing.ps1

<#
 
# Parsing
 
Da die PowerShell ein Kommandozeileninterpreter ist werden Befehle zu erst geparst und die entstanden Token analysiert und interpretiert.
 
- **Hashtags** Parsing Kommandozeileninterpreter VSCode
 
- **Version** 2020.12.7
 
#>


#region PowerShell-Parsing

# ! Ein PowerShell Kommando wird beim parsen in Token aufgeteilt und analysiert. Diese Tokens werden mit einem SPACE getrennt, z.B.:

  Write-Output -InputObject 'Buch'
# S S => 1. nach [SPACE] splitten
# TTTTTTTTTTTT TTTTTTTTTTTT TTTTTT => 2. Token analysieren:
# Cmdlet Parameter Argument => 3. Interpretieren / Ausführen

# ! PROBLEM:
Get-ChildItem -Path C:\Database Backups
# ! ^
# ! TTTTTTTTTTT TTTTTTT => Zwei Token!
# ! LÖSUNG:
Get-ChildItem -Path 'C:\Database Backups'

# ! Token werden wie folgt analysiert:

# Example Mode Result
# ------------------ ---------- ----------------
2+2                     # Expression 4 (integer)
Write-Output 2+2        # Argument "2+2" (string)
Write-Output (2+2)      # Expression 4 (integer)
$a = 2+2                # Expression $a = 4 (integer)
Write-Output $a         # Expression 4 (integer)
Write-Output $a/2       # Argument "4/2" (string)
Write-Output ($a/2)     # Expression 2 (integer)
Write-Output !1         # Argument "!1" (string)
Write-Output (!1)       # Expression False (Boolean)
Write-Output Get-Date   # Argument "Get-Date" (string)
Write-Output (Get-Date) # Expression 12.12.2020 12:12

# * Das Parsing in der PowerShell abstellen:

# ! Parsing-Problem:
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
# ? Lösung 1:
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
# ? Lösung 2: Stop das parsing nach --% =>
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F

#endregion

#region Zeilenumbrüche im Code

# * Nach einer Pipeline können Zeilenumbrüche (CRLF) eingefügt werden, um die **Lesbarkeit** zu erhöhen:

Get-Process |
    Where-Object -Property 'Company' -ILike -Value 'Microsoft*' |
    Sort-Object -Property 'Name' |
    Select-Object -Property 'Name', 'Company' |
    Out-File -FilePath 'C:\Temp\Process.txt' -Force

# TIPP ACHTUNG - Ab jetzt muss der auszuführende Block selektiert und erst dann mit F8 zur Ausführung gebracht werden. Das ständige Markieren könnte auf die Dauer ein Handling-Nachteil sein. Dieser Nachteil kann über ALT+Z in VSCode relativiert werden, da zwischen einem visuellen Umbruch gewechselt werden kann:

Get-Process | Where-Object  -Property 'Company' -ILike -Value 'Microsoft*' | Sort-Object -Property 'Name' | Select-Object -Property 'Name', 'Company' | Out-File -FilePath 'C:\Temp\Process.txt' -Force

<# ## TIPP Dieser 'visuellen Umbruch' kann in den VSCode-Einstellungen an die eigenen Bedürfnisse angepasst werden:
```json
{
    "editor.wordWrap" : "wordWrapColumn",
    "editor.wordWrapColumn" : 80,
    "editor.wrappingIndent" : "indent",
}
```
#>


#endregion

#region Sonderzeichen und deren Bedeutung

#region Kommentare

# Kommentarzeile: Get-Date

Get-Date # Ab dem Zeichen # ist der rest der Zeile als Kommentar zu behandeln

# Kommentarblock:

<#
Sämtlicher Text zwischen diesen Zeichen wird
als Kommentar behandelt.
Get-Date
#>


# Region um Code-Blöcke zu gruppieren. Ein verschachteln ist möglich. Sämtliche **Regionen** können mittels [CTRL]+[K] anschließend [CTRL]+[8] in VSCode eingeklappt werden:

#region Das Aktuelle Datum
Get-Date
#endregion

#endregion

# Escape characters, Delimiters and Quotes (http://ss64.com/ps/syntax-esc.html):

# TIPP - Sonderzeichen in der PowerShell:
Get-Help -Name 'about_Special_Characters' -ShowWindow

"Hallo `n Köln!"
"Hallo `r`n Köln!"
"Hallo `t Köln!"

# Boolean (Wahr/Falsch):

$true
$false

# Ganzzahl (Integer):

10

# Fließkommazahl (Double):

10.5

# String ohne/mit Variablen-Auflösung:

'PowerShell-Kultur $PSCulture'
"PowerShell-Kultur $PSCulture"
"Jetzt ist $(Get-Date)"

# Array (Das Komma "," ist der Array-Elemente-Trenner):

'Köln' , 'München' , 'Berlin' , 'Stuttgart'

# Das 3. Array-Element [ ] basierend auf 0:

('Köln', 'München', 'Berlin', 'Stuttgart')[2]

# Ausdruck-Auswerten () zzgl. Eigenschaft/Methode des Objektes zurück geben:

(Test-NetConnection 192.168.50.10).PingSucceeded
(Get-Process -Name 'notepad').Kill()

# Abschluss einer Befehlskette mit ;

Get-Process ; Get-Service

# Konvertierung eines String-Objektes in ein DateTime-Objekt([T]O):

'3456' * 10
([int]'3456') * 10
[datetime]'2016-12-31'
([datetime]'2016-12-31').Year
([datetime]'2016-12-31').AddDays(127)

# Eine statische Methode eines Typen aufrufen ([T]::SM):

[DateTime]::Today
[Convert]::ToDateTime('31.12.2016', (Get-Culture))

# ! Call-Operator . und &:

Set-Location -Path 'C:\Temp'
'$nachricht = "Message from Test.ps1"' | Set-Content -Path '.\Test.ps1' -Force

$nachricht = 'Keine Nachricht!'
. '.\Test.ps1' # ! Aufruf im aktuellen Gültigkeitsbereich
"Die akt. Nachricht lautet: $nachricht"

$nachricht = 'Keine Nachricht!'
& '.\Test.ps1' # ! Aufruf im eigenen Gültigkeitsbereich
"Die akt. Nachricht lautet: $nachricht"

#endregion

#region Übungen

# TODO QUIZ - https://attilakrick.com/schlagwort/powershell-parsing/

# ? 1. Welche Bedeutung haben die runden Klammern aus der folgenden Zeile?
SuperPing.exe --% -Computer (DnsToIp dc01.abc.local)

# ? 2. Wie muss folgende Befehlzeile:
Get-Date -Format 'yyyy-MM-dd-HHmmss'
# ? als Argument dem Parameter -Path :
New-Item -Path
# ? übergeben werden, um z.B. die Datei 'C:\temp\System-2020-12-07-123908.log' mit einem aktuellen Zeitstempel zu erzeugen?

# ? 3. Ordnen Sie die Beispiele (A bis M) dem richtigen Thema (1 bis 13) zu:

# ! (A) "Hallo `n Köln!"
# ! (B) "EUR: $Betrag"
# ! (C) 123,124
# ! (D) 255
# ! (E) $false
# ! (F) 'EUR: $Betrag'
# ! (G) 76.3
# ! (H) [Int32]::MaxValue
# ! (I) [decimal]'4678'
# ! (J) $listeX[4]
# ! (K) (Test-NetConnection 192.168.50.10)
# ! (L) 'Köln' ; 'Stuttgart'
# ! (M) & 'C:\temp\KillBill.ps1'

# ! (1) Zeilenumbruch
# ! (2) String mit Expression-Auflösung
# ! (3) Zwei String in einer Zeile
# ! (4) Double
# ! (5) Das 5 Element aus einem Array
# ! (6) Integer
# ! (7) Ausdruck (Expression)
# ! (8) Array mit 2 Elementen
# ! (9) String ohne Expression-Auflösung
# ! (10) Boolean
# ! (11) Eine Objekte-Umwandlung
# ! (12) Auf eines statischen Members
# ! (13) .PS1-Datei ausführen inkl. Schutz meiner Session

#endregion