Private/Wissen/C_Advance/C04_Debugging.ps1

<#
 
# Debugging
 
Debugging in der PowerShell / Visual Studio Code
 
- **Hashtags** Debug dynamic Breakpoint Trace
- **Version** 2019.10.11
 
#>


# TODO Weiterführende und Nachschlage-Informationen
Get-Help -Name about_Debuggers -ShowWindow
Get-Command -Noun PSBreakPoint, *Debug, PsCallStack, StrictMode, Verbose -Module Microsoft.PowerShell.*
Get-ChildItem -Path .\Wissen\C03_AufbauAusführbareDatei.ps1

#region Formal-, Syntax- und Tippfehler erkennen und logische Fehler vermeiden

# ? Wo ist der Fehler:
#$ort = 'München"

# ? Wo ist der Fehler:
<#
function Test-Syntaxfehler {
    param(
        $Path
        $Depth
    )
    Get-ChildItem -Path $Path -Depth $Depth
}
#>


# ? Wo ist der Fehler:
Get-ChildItem -Path c:\ -Recurse -File | Where-Object -Property CreationTime -LE -Value Get-Date.AddDays(-100)

# ? Wo ist der Fehler:
Get-Service | Where-Object -FilterScript { $_.Status = 'Running' }

# ? Wo ist der Fehler:
Get-ChildItem -Path C:\Windows | Where-Object -FilterScript { $_.Lenght -gt 1MB }

# ! TIPP Aktivieren Sie den Strict-Mode, um sicherzustellen das vor der ersten Verwendung
# ! einer Variablen dieser einen Wert zugewiesen wird.
# ! So werden Tippfehler ausgeschlossen da eine Variable deren Namen versentlich falsch geschrieben wurde nicht benutzt werden kann!
Set-StrictMode -Version Latest
$ort = "Würzburg"
"Hallo $ort!"
"Hallo $ord!"
Set-StrictMode -Off

#endregion

#region Den Debug-Modus verwenden

# ! - Nur .PS1-Dateien können vom Debug-Modus profitieren
# ! - Die .PS1-Datei muss vor dem starten des Debug-Modus gespeichert werden
# ! - Änderungen an der .PS1-Datei während der Debug-Modus läuft sind unzulässig
# ! - Im Debug-Mode kann mit der Maus über eine Variable verweilt werden,
# ! worauf im ToolTip der Inhalt dieser angezeigt wird.

# ? VSCode-Debug-Modus-Tastaturbefehle
# F9 => Haltepunkt setzen/lösen
# F5 => Debug-Modus starten, die Ausführung bleibt beim ersten Haltepunkt stehen
# F10 => Funktionsaufrufe werden übersprungen und im gesamt abgearbeitet
# F11 => Führt die nächste Code-Zeile aus (Gelbe Zeile => wurde NOCH NICHT ausgeführt)
# Ein erreichbarer Funktionsaufrufe wird angesprungen
# SHIFT + F5 => Beenden den Debug-Modus vorzeitig

# TODO Um den Debug-Modus kennenzulernen folgendes Beispiel in einer eigenständigen .PS1-Datei (z.B. _SCHNIPPSEL.ps1) kopieren:
function Test-DebugMode {
    1..10 | ForEach-Object -Process {
        $ipId = $_
        "Bearbeite gerade Pipeline-Objekt $_ ..."
        $ipId = "192.168.178.$ipId"
        "Die IP-Adresse wurde gebildet und lautet: $ipId"
    }
}
Test-DebugMode

#endregion

#region In den Debug-Modus wechseln wenn sich Variablen ändern (dynamische Haltepunkte)

# TODO Um den DynamicBreakpoints kennenzulernen folgendes Beispiel in einer eigenständigen .PS1-Datei (z.B. _SCHNIPPSEL.ps1) kopieren:
function Test-DynamicBreakpoints {
    1..5 | ForEach-Object -Process {
        $ipId = $_
        "Bearbeite gerade Pipeline-Objekt $_ ..."
        $ipAddress = "192.168.178.$ipId"
        "Die IP-Adresse wurde gebildet und lautet: $ipAddress"
    }
}
 # ? Anhalten wenn die Variable $ipId beschieben wird:
Set-PSBreakpoint -Variable ipId -Mode Write

# ? Anhalten wenn die Variable den Wert "192.168.178.5" enthält:
Set-PSBreakpoint -Variable ipAddress -Mode Write -Action { if ($ipAddress -ceq "192.168.178.3") { break } }

Test-DynamicBreakpoints

#endregion

#region Debug-Meldungen ausgeben

# TODO Um das Verhalten von Write-Debug kennenzulernen folgendes Beispiel in einer eigenständigen .PS1-Datei (z.B. _SCHNIPPSEL.ps1) kopieren
function Test-WriteDebug {
    1..10 | ForEach-Object -Process {
        $counter = $_
        "Bearbeite gerade Pipeline-Objekt $_ ..."
        $counter++
        '$counter steht jetzt auf {0}' -f $counter | Write-Debug
    }
}

# ! Debug-Meldungen werden unterdrückt (Default-Verhalten)
$DebugPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue # <= DEFAULT
Test-WriteDebug

# ! Script-Ausführung wird abgebrochen bei der ersten Debug-Meldung
$DebugPreference = [System.Management.Automation.ActionPreference]::Stop
Test-WriteDebug
$DebugPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue # <= DEFAULT

# ! Debug-Meldungen werden sichtbar
$DebugPreference = [System.Management.Automation.ActionPreference]::Continue
Test-WriteDebug
$DebugPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue # <= DEFAULT

#endregion

#region Tracing

# ! Die Verarbeitung von Skripten, Cmdlet- oder Pipeline-Benutzung können
# ! auf unterschiedlichster weisen überwacht werden.

# ? Welche Überwachungen es gibt liefert folgendes Cmdlet:
Get-TraceSource | Select-Object -Property Name, Description | Out-GridView

# ? Cmdlet-Verarbeitung analysieren
Trace-Command -Name ParameterBinding -Expression { Get-Process spoolsv } -PSHost

# TODO Um das Verhalten von Set-PSDebug kennenzulernen, folgendes Beispiel in einer eigenständigen .PS1-Datei (z.B. _SCHNIPPSEL.ps1) kopieren
function Test-Tracing {
    1..2 | ForEach-Object -Process {
        $ipId = $_
        "Bearbeite gerade Pipeline-Objekt $_ ..."
        $ipAddress = "192.168.178.$ipId"
        "Die IP-Adresse wurde gebildet und lautet: $ipAddress"
    }
}
# ! 0: Turn script tracing off
# ! 1: Trace script lines as they run;
# ! 2: Trace script lines, variable assignments, function calls, and scripts.
Set-PSDebug -Trace 2
Test-Tracing
Set-PSDebug -Trace 0

#endregion

#region Der Common-Parameter Verbose

Remove-Module -Name AKPT -Verbose
Import-Module -Name .\AKPT -Verbose

#endregion

#region Die Dauer einer Ausführung messen

Measure-Command -Expression { 1..5 | ForEach-Object -Process { "Verarbeite Nummer $_"; Start-Sleep -Seconds 1 } | Out-Default }
1..5 | Measure-Command -Expression { "Verarbeite Nummer $_" | Out-Default; Start-Sleep -Seconds 1 }

#endregion