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 |