User Tools

Site Tools


woche_1_-_microsoft_windows_server_kurs

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
woche_1_-_microsoft_windows_server_kurs [2025/02/17 09:27] – [Übung 8.18 Teil 2 (Seite 118)] kalaschnikowwoche_1_-_microsoft_windows_server_kurs [2025/03/31 15:11] (current) – [Woche 1 - Microsoft Windows Server Kurs] kalaschnikow
Line 1: Line 1:
 +====== Woche 1 - Microsoft Windows Server Kurs ======
  
 +  * [[GFN Sysadmin Kurs]]
 +    * [[Microsoft Windows Server Kurs]]
 +      * [[Woche 1 - Microsoft Windows Server Kurs]]
 +      * [[Woche 2 - Microsoft Windows Server Kurs]]
 +      * [[Woche 3 - Microsoft Windows Server Kurs]]
 +      * [[Woche 4 - Microsoft Windows Server Kurs]]
 +      * [[Woche 5 - Microsoft Windows Server Kurs]]
 +      * [[Woche 6 - Microsoft Windows Server Kurs]]
 +      * [[Woche 7 - Microsoft Windows Server Kurs]]
 +      * [[Woche 8 - Microsoft Windows Server Kurs]]
 +
 +
 +  * [[Moegliche Pruefungsfragen - Microsoft Windows Server Kurs]]
 +
 +
 +===== Tag 1: 10.02.2025 Montag =====
 +
 +  * Themen dieser Woche: 
 +    * PowerShell
 +    * IP Adressierung
 +      * Subnettierung
 +      * Supernettierung
 +      * NAT
 +      * DNS
 +      * DHCP
 +    * Active Directory
 +
 +  * Verzeichnis "ISOs" auf dem Notebook (vom GFN)
 +    * Win11_German
 +    * Windows_Server_2022_German
 +
 +  * SLMGR
 +    * Service License Manager (?)
 +
 +  * In der virtuellen Umgebung (Remote Lab Host)
 +    * "Win" -> Systemsteuerung
 +      * Große Symbole
 +      * System
 +      * Windows Edition auf dem Host
 +        * = Windows Server 2022 Datacenter
 +        * = RAM = 24 GB (auf dem Server für jeden)
 +        * = Xeon
 +    * Verwaltung der Virtuellen Maschinen
 +      * Hyper-V manager
 +
 +  * Jetzt Im Hyper-V manager:
 +
 +  * Host "WIN-DH-..." auswählen
 +  * Im Arbeitsbereich 
 +    * GFN-DC (Domänenkontroller)
 +    * ...
 +  * Aktionsbereich (rechts)
 +  * Host auswählen (WIN-DH...)
 +    * Aktion "Hyper-V Einstellungen"
 +      * Virt.Festplatten= ''C:\VM''
 +      * Virt.Computer= ''C:\VM''
 +  * Live Migrationen
 +  * Speichermigrationen
 +
 +  * Manager Virt.Switches
 +  * GFN-Privat
 +    * aufklappen
 +      * Erweiterungen
 +  * R_LAB_Internet_NICHTS_AENDERN
 +  * Globale Einstellungen
 +    * MAC-Adressbereich
 +
 +  * Tag 1
 +    * Unterschied Client-Server
 +    * SAM
 +    * LSA (Local Security Authority)
 +    * Hardware Anforderungen
 +    * Erste Schritte mit einem Server
 +    * Rollen und Features
 +    * Windows Admin Center
 +    * Windows 11 als Client
 +
 +  * Die Versionen von Windows Server 2022 (Prüfungsfrage!)
 +    * Essentials
 +      * SQL Server
 +      * Exchange
 +      * "File Server"
 +      * ...
 +    * Standard
 +      * keine Einschränkung 
 +        * bzgl. Ressourcen (?)
 +        * bzgl. Benutzerzugriffe
 +    * Datacenter
 +      * max. 16 Knoten
 +    * Datacenter Azure Edition
 +
 +  * SAM = Security Account Manager
 +    * Locale Benutzer verwalten
 +    * Benutzer & Gruppen verwalten
 +
 +  * Hyper-V Manager
 +    * Neu -> Virt. Computer
 +      * Assistent startet
 +      * Name
 +        * WS-2022-BSP1
 +      * Generation
 +        * Gen 1
 +          * 32 und 64 bit
 +          * nur IDE
 +        * Gen 2
 +          * 64 bit
 +          * SCSI
 +          * UEFI (statt BIOS)
 +        * => Generation 2 wählen
 +      * Speicher
 +        * in 1024 Schritten
 +        * => 4096 MB
 +        * Option "Dynamisch..." NICHT wählen
 +      * Netzwerk
 +        * "R-LAB..." wählen, da nur dieses Netz im Internet ist
 +      * Virtuelle Festplatten
 +        * momentan alles so wie es ist lassen
 +      * Installationsoptionen
 +        * von startbaren Imagedatei
 +      * Zusammenfassung
 +    * Im Hyper-V Manager
 +      * den (neu erstellten) Server auswählen (also den "WS-2022...")
 +      * Firmware (=Bootreihenfolge ändern)
 +        * umstellen in:
 +          * 1. Festplatte
 +          * 2. DVD
 +          * 3. Netzwerk
 +      * Sicherheit
 +        * "Sicherer Start" soll aktiviert sein
 +          * -> "MS Windows"
 +        * "Trusted Platform Mode" soll NICHT aktiv sein (N.B. bei der "Windows 11 Client" Installation aber schon)
 +        * Arbeitsspeicher
 +          * alles (?)
 +        * Prozessor
 +          * -> auf 2 umstellen
 +        * SCSI
 +          * nichts ändern
 +        * Netzwerkkarte
 +          * nichts ändern
 +      * also: nur bei "Prozessoren" auf 2 umstellen, sonst alles so lassen wie vorgeschlagen
 +    * Server starten
 +      * WICHTIG: rechtzeitig Taste drücken
 +    * ...
 +    * "Jetzt installieren"
 +    * "Ich habe keinen Product Key"
 +    * Zu installierendes Betriebssystem
 +      * -> Datacenter (Desktopdarstellung)
 +        * WICHTIG: diese Option wählen, da sonst keine GUI da ist!
 +    * Lizenz akzeptieren
 +    * Installationsart
 +      * -> Benutzerdefiniert
 +    * Wie möchten Sie das Betriebssystem installieren
 +      * -> 127 GB (= vollständig)
 +
 +    * Nach dem Start muss man "Ctrl+Alt+Del" drücken
 +      * => über Fenstermenü "Aktion" (NICHT über Tastatur)
 +    * Netzwerke
 +      * "Möchten Sie zulassen..."
 +        * -> Ja
 +    * Admin Center noch nicht installieren
 +      * => Einfach schließen (?)
 +
 +  * Nach dem Serverstart
 +    * Win Menü
 +      * "Server Manager" (wichtigstes Werkzeug)
 +  * Im Server Manager
 +    * Dashboard
 +    * Lokaler Server
 +      * Computername
 +        * am besten gleich ändern (in das gleiche wie vorhin, also "WS-2022-BSP1")
 +      * Arbeitsgruppe "WORKGROUP"
 +    * ...
 +    * Ereignisse
 +    * ...
 +
 +  * "Win" -> Windows Verwaltungsprogramme
 +    * auch in den Kacheln zu finden
 +  * Verwaltungsprogramme
 +    * Systemkonfiguration
 +    * Systeminformation
 +    * Computerverwaltung
 +      * Aufgabenplanung
 +      * ...
 +      * Gerätemanager
 +    * Systemsteuerung
 +      * am besten Anzeige auf "Kategorien/Symbole" ändern
 +    * Lokale Benutzer / Gruppen
 +      * Benutzer
 +        * neuen Benutzer erstellen
 +          * "Benutzer muss Passwort ändern" 
 +            * -> deaktivieren
 +          * "Kennwort läuft nie ab"
 +            * -> aktivieren
 +      * Gruppe
 +        * Administratoren
 +          * den Benutzer dorthin hinzufügen
 +
 +
 +  * Zustand vom Server "einfrieren"
 +    * Prüfpunkt erstellen (im Hyper-V Manager ?)
 +
 +  * Misc:
 +    * Passes
 +      * Administrator / AdminPass=8
 +      * kalaschnikow / VKPass=8
 +
 +===== Tag 2: 11.02.2025 Dienstag =====
 +
 +  * PowerShell
 +  * Prozesse automatisieren
 +  * die Server-Anwendungen können damit vollständig automatisiert administriert werden
 +    * z.B. Exchange oder sogar Azure
 +  * Evaluierungszyklus (?) kann NUR über PowerShell administriert werden
 +  * 14-20 Tausend Befehle
 +  * Objektorientiert
 +  * .NET-basiert
 +
 +---
 +  * Windows 11 Client anlegen (hat mit dem heutigen Thema nichts zu tun)
 +    * Hyper-V-Manager verwenden
 +    * dort einen virtuellen Rechner anlegen
 +    * Name: WC-11-BSP2
 +    * Generation 2 (NUR Gen2!)
 +    * 8192 MB
 +    * Verbindung "R-LAB...NICHT-AENDERN"
 +    * Virt...
 +      * hier nichts ändern
 +    * Image: Win11_German_22...iso
 +    * Einstellungen vom Client
 +      * Startreihenfolge
 +        * Festplatte
 +        * DVD
 +        * Netz
 +      * Sicherheit
 +        * Trusted Platform Module (TPM)
 +          * -> aktivieren
 +      * Prozessoren
 +        * 4
 +    * Starten
 +    * DE/DE/DE
 +    * Setup wird gestartet
 +    * "Windows 11 Pro" wählen
 +    * Lizenz akzeptieren
 +    * Benutzerdefiniert
 +    * 127 GB (so lassen)
 +    * Server Manager (auf dem gestarteten Rechner)
 +      * jeder Server ist anders
 +      * Rollen
 +        * normalerweise nur eine Rolle auf dem Server
 +        * e.g. "DB Server" und "File Server" sind zwei verschiedene Sachen und man sollte nicht beide auf einem physikalischen Rechner haben
 +    * Tastaturlayout (nicht ändern?)
 +    *  Benennen wir Ihr Gerät
 +      * WC-11-BSP2
 +      * -> Weiter
 +    * dann startet der Rechner neu (wg. Namensänderung)
 +    * Wie möchten Sie Ihre Gerät einrichten?
 +      * -> "Für Arbeit..." wählen
 +    * Einrichtung Kontos
 +      * Anmeldeoptionen
 +      * Stattdessen Domäne beitreten
 +    * Von wem wird dieses Gerät...
 +      * Name: "kalaschnikow"
 +      * Kennwort
 +      * Sicherheitsabfrage 1/2/3
 +    * Standort
 +      * Nein
 +    * Suchen
 +      * Nein
 +    * Diagnose
 +      * Nur die erforderliche
 +    * Werbe-ID
 +      * Nein
 +    * Nach Updates wird gesucht...
 +    * N.B. Wenn der Rechner gelöscht wird, dann sollte man auch die virtuellen Festplatten auch löschen (in ''C:\VM'')
 +    * Auf Win 11 gibt es keinen "Servermanager", aber "Computerverwaltung"
 +      * Win-Knopf mit rechten Maustaste
 +        * dann "Computerverwaltung" anklicken
 +      * Lokale Benutzer & Gruppen
 +      * Der Benutzer, der angeklickt wurde ist automatisch "Administrator" auf Windows 11 Client (NICHT auf dem Windows Server)
 +      * Einstellungen
 +        * System
 +          * ...
 +          * Computernamen ändern
 +        * Windows Tools (auf dem Win 11 Client) = Windows Verwaltungsprogramme (auf dem Server)
 +
 +---
 +
 +      * Servermanager
 +        * Oben "Verwalten"
 +        * Rollen und Features hinzufügen
 +        * Assitent startet
 +        * den Server auswählen
 +        * Serverrollen
 +          * z.B. "DHCP-Server", "File Server"
 +        * Features
 +          * z.B. "Container", "Cluster Service"
 +      * Task Manager (auf R-LAB)
 +        * Prozesse
 +        * Rechte Maustaste auf dem Header
 +          * Spalten auswählen
 +            * Handles
 +            * Threads
 +            * Seitenfehler
 +      * Server Manager
 +        * "Tools" oben
 +          * Dienste
 +            * Menü "Ansicht"
 +              * Spalten hinzufügen
 +                * es gibt nichts mehr
 +                * PowerShell bietet aber mehr Info dazu (zu den Diensten?)
 +
 +  * PowerShell
 +    * PowerShell-Konsole (CLI=Command Line Interface)
 +    * PowerShell ISE (Integrated Scripting Environment)
 +  * Ausführung in PowerShell muss man explizit einschalten
 +    * auf dem Server ist sie aber standardmäßig an
 +  * Grundlagen
 +    * Batch-Befehle
 +    * WSH = Windows Scripting Host
 +    * PowerShell 1.0 - Nov 2006 (outdated)
 +    * PowerShell 2.0 - Okt 2009 (immer noch aktuell)
 +    * ...
 +    * PowerShell 5.0 - Apr 2014 (Win 10)
 +  * PowerShell MUSS administrativ ausgeführt werden
 +    * sieht man oben im Fenster ("Administrator")
 +    * starten mit der rechten Maustaste und "Als Administrator ausführen"
 +  * ISE beim ersten Start 
 +    * oben "Skript" anklicken, dann sieht man auch den Editor
 +  * IntelliSense
 +    * tut auch in der Console
 +    * mit der Tab Taste
 +  * Parametereingabe (mit ''-'')
 +  * Syntax-Highlighting
 +  * Bei Win 11 die "Windows PowerShell (x86)" NICHT ausführen, da nur 32 bit
 +  * In der PowerShell können auch 
 +    * cmd Befehle eingegeben werden
 +      * dir, cls, copy, echo...
 +    * externe Befehle
 +      * e.g. ipconfig, ping ...
 +  * F5 = Skript ausführen
 +  * F8 = nur gewähltes Stück Code (bzw. die Zeile wo der Cursor steht) ausführen  
 +  * Normalerweise ISE ist komfortabler als Console
 +  * Console verwenden nur wenn Benutzereingaben erwartet werden
 +  * PowerShell kann einfaches Rechnen:
 +    * Plus, Minus, Modulo ...
 +  * Hex geht auch
 +    * Ergebnis kommt aber dezimal
 +  * Bereiche
 +    * z.B. 1..6
 +  * PowerShell Cmdlets
 +  * <Verb>-<Substantiv>
 +  * Parameter
 +    * Cmdlet-spezifisch
 +    * Allgemeine
 +  * Verbe:
 +    * Get -> ausgeben
 +    * Set
 +    * Add
 +    * Delete
 +    * Remove
 +    * ...
 +  * Beispiele
 +    * Get-Process
 +      * Prozesse ausgeben
 +    * Get-Command
 +      * Befehle ausgeben
 +    * Get-Service
 +      * Dienste ausgeben
 +  * Parameter
 +    * Benannte
 +      * der Name muss eingegeben werden
 +    * Positionsparameter
 +      * müssen an einer bestimmten Stelle stehen
 +    * Switch-parameter
 +      * braucht keinen Wert
 +  * Beispiel
 +    * ''Get-Process -Name a*''
 +      * alle Prozesse, die mit ''a'' anfangen anzeigen
 +    * ''Get-Process -Name a*, se*''
 +      * alle Prozesse, die mit ''a'' ODER ''se'' anfangen anzeigen
 +  * Get-Cmdlets für den Einstieg (9 Stück)
 +    * Get-ChildItem
 +    * ...
 +    * Get-Date
 +    * Get-History
 +      * History der aktuellen PowerShell-Sitzung
 +    * Get-Module
 +      * Module = Bibliotheken von der PowerShell
 +      * Beispiele
 +        * ''Get-Module -ListAvailable''
 +          * Module auflisten, die verfügbar sind
 +          * ohne ''-ListAvailable'' werden nur die aktiven angezeigt
 +    * Get-NetIPAddress
 +      * aktuelle IP Konfiguration anzeigen
 +    * Get-PSDrive
 +      * aktuelle "Laufwerke" anzeigen
 +        * Laufwerke - NICHT Festplatten, sondern "Datenspeicher-Laufwerke"
 +    * Get-PSProvider
 +      * Anbieter der "Laufwerke" anzeigen
 +    * Get-LocalUser
 +      * lokale Benutzer anzeigen
 +
 +  * Hilfesystem der PowerShell (WICHTIG!)
 +    * ''Get-Help''
 +      * Sprachen für die Hilfe installieren
 +        * ''Update-Help -UICulture "en-US"''
 +          * Beim ersten Aufruf wird die Hilfe geupdatet (von Microsoft geholt)
 +            * das wird aber nur in der Console gemacht, im ISE geht das leider nicht
 +      * ''Get-Help Get-Process -Detailed''
 +        * detaillierte Hilfe für ''Get-Process'' anzeigen
 +      * ''Get-Help Get-Process -Examples''
 +      * ''Get-Help Get-Process -Full''
 +      * ''Get-Help Get-Process -Online''
 +        * die Online Version (von Microsoft) im Browser anzeigen
 +      * ''Get-Help Get-Process -ShowWindow''
 +        * die Hilfe im speziellen Fenster anzeigen (wo man suchen kann)
 +      * ''Get-Help about-<Topic>''
 +        * die Hilfe nicht über ein Befehl sondern über ein Thema anzeigen
 +
 +==== Übung "Verwenden der PowerShell-Hilfe" (Seite 38) ====
 +
 +
 +  * 1. Führen Sie Update-Help auf Ihrem System aus. Wie lautet das vollständige Cmdlet, das den sofortigen Download garantiert?
 +    * ''Update-Help'' bzw.
 +    * ''Update-Help -UICulture "de-DE"'' (für Deutsch)
 +  * 2. Rufen Sie die Hilfe für das Cmdlet ''Get-Service'' auf. Vergleichen Sie die Ausgabe, wenn Sie keine weiteren Parameter angeben, mit der Ausgabe, die Sie jeweils bei zusätzlicher Eingabe des Parameters –Detailed, –Full bzw. –Examples erhalten.
 +    * ''Get-Help Get-Service -Detailed''
 +    * ''Get-Help Get-Service -Full''
 +    * ''Get-Help Get-Service -Examples''
 +  * 3. Finden Sie heraus, welche Cmdlets den Parameter –Verb verwenden. Lesen Sie in der Hilfe zu einem der angezeigten Cmdlets nach, was der Parameter bedeutet.
 +    * ''Get-Help -Name * -Parameter Verb''
 +  * 4. Lassen Sie sich Beispiele für das Cmdlet Get-Process anzeigen.
 +    * ''Get-Help Get-Process -Examples''
 +
 +==== Übung "Verwenden wichtiger Cmdlets" (Seite 38) ====
 +
 +  * 1. Finden Sie heraus, welche Befehle das Verb ''Import'' verwendet.
 +    * ''Get-Help -Name Import*''
 +  * 2. Welche Eigenschaften von Diensten auf Ihrem Rechner kann das Cmdlet ''Get-Service'' anzeigen?
 +    * ''Get-Service | Get-Member''
 +    * Noch eine Möglichkeit: einfach Hilfe zum Befehl aufrufen (also ''Get-Help GetService'') und nachschauen was alles dort steht
 +  * 3. Recherchieren Sie mit den im Kapitel vorgestellten Mitteln
 +    * a) die Syntax des Cmdlets ''Get-Module'',
 +      * ''Get-Help Get-Module -Online''
 +    * b) Beispiele zum Einsatz des Cmdlets Get-PSDrive,
 +      * ''Get-Help Get-PSDrive -Examples''
 +      * ''Get-Help Get-PSDrive -Examples -Online'' -> funktioniert NICHT!
 +      * ''Get-Help Get-PSDrive -Examples -ShowWindow'' -> funktioniert NICHT!
 +    * c) was der Parameter ''–Format'' des Cmdlets Get-Date bedeutet.
 +      * ''Get-Help Get-Date -Parameter Format -Online'' -> funktioniert NICHT!
 +  * 4. Lesen Sie die vollständigen Hilfetexte zu den vorgestellten Get-Befehlen Get-History, Get-Process und Get-PSProvider.
 +      * ''Get-Help Get-History -Full''
 +      * ''Get-Help Get-Process -Full''
 +      * ''Get-Help Get-PSProvider -Full''
 +  * 5. Finden Sie heraus, welche Eigenschaften Ihnen für das Cmdlet Get-Module zur Verfügung stehen
 +      * ''Get-Help Get-Module -Online''
 +      * bzw.
 +      * ''Get-Module | Get-Member''
 +
 +
 +==== Musterlösungen von Michael ====
 +<code>
 +# Übung Kapitel 3 Teil 1
 +
 +
 +#1)
 +Update-help
 +
 +
 +
 +#2)
 +get-help -Name Get-Service
 +get-help -Name Get-Service -Detailed
 +get-help -Name Get-Service -Full
 +get-help -Name Get-Service -Examples
 +
 +
 +
 +#3)
 +Get-Help -Name * -Parameter Verb
 +Get-Help -Name Get-Command -Parameter Verb
 +
 +
 +
 +#4)
 +Get-Help -Name Get-Process -Examples
 +
 +
 +
 +# Übung Kapitel 3 Teil 2
 +
 +#1)
 +get-command -verb import
 +Get-Command -noun csv
 +Get-Command -Name import-csv
 +
 +
 +#2)
 +Get-Service | Get-Member
 +
 +Get-Service | Get-Member -MemberType Property
 +
 +
 +#3)
 +Get-help -Name Get-Module
 +
 +Get-Help -Name Get-PSDrive -Examples
 +
 +Get-Help -Name Get-Date -Parameter Format
 +
 +
 +
 +#4)
 +Get-Help -Name Get-History -Full
 +Get-Help -Name Get-Process -Full
 +Get-Help -Name Get-PSProvider -Online
 +
 +
 +#5)
 +Get-Module | Get-Member -MemberType Property
 +
 +</code>
 +
 +
 +===== Tag 3: 12.02.2025 Mittwoch =====
 +
 +==== Musterlösung zu Übungen zu Where-Object etc ====
 +<code>
 +#1)
 +
 +get-service | Where-Object -Property status -eq stopped
 +
 +#2)
 +
 +Get-Process -Name W*
 +Get-Process w*
 +
 +Get-Process | Where-Object -Property Name -Like w*
 +
 +#3)
 +
 +Get-EventLog -LogName system | Where-Object -FilterScript {$_.EntryType -eq "Warning"}
 +Get-EventLog -LogName system | Where-Object  EntryType -eq warning
 +
 +#4)
 +
 +Get-Command -CommandType Cmdlet | Where-Object -Property Verb -eq import | Measure-Object
 +
 +#5)
 +
 +Get-ChildItem -Path C:\Windows| `
 +Where-Object -FilterScript {$_.Extension -eq ".exe" -and $_.Length -gt 1KB} | `
 +Sort-Object -Property Length -Descending
 +
 +Get-ChildItem C:\Windows\*.exe | Where-Object Length -gt 1KB | Sort-Object Length -Descending
 +</code>
 +
 +==== Vorlesung ====
 +
 +  * Informationen verarbeiten und ausgeben
 +  * PowerShell Pipeline
 +    * der vorhergehende Befehl gibt die Daten an den nächsten
 +  * Object-Cmdlets
 +  * Formatierung und Ausgabe
 +  * Schrittweise Entwicklung einer Pipeline
 +  * Prinzip der Pipeline
 +    * 1. Daten bereitstellen (''Get-...'')
 +    * 2. Ergebnis bearbeiten (''...-Object'')
 +    * 3. Endergebnis ausgeben 
 +      * ''Export-...''
 +      * ''Format-...''
 +      * ''Out-...''
 +  * Verarbeitung vorliegenden Daten
 +    * ''Select-Object''
 +<code>
 +Get-Process -Name a* | Select-Object -Property ProcessName, id, Handles
 +
 +# Liste der Properties ausgeben von Get-Process
 +Get-Process | Get-Member
 +
 +Get-Process -Name a* | Select-Object -Property Name, id, cpu, threads
 +</code>
 +
 +  * Sort-Object
 +<code>
 +# Nach Id sortieren
 +Get-Process | Sort-Object -Property Id
 +
 +# Nach Cpu sortieren
 +Get-Process | Sort-Object -Property cpu -Descending
 +</code>
 +
 +  * Tee-Object (Ausgabe "duplizieren" in Datei oder Variable)
 +<code>
 +# Get-Process Ausgabe in Datei C:\tmp.txt
 +Get-Process | Tee-Object -File -Path C:\tmp.txt
 +
 +# Get-Process Ausgabe in Variable MyList
 +Get-Process | Tee-Object -Variable MyList
 +</code>
 +
 +  * Where-Object
 +    * filtert Ausgabe nach definierten Kriterien
 +      * ''{}'' - Process Block 
 +    * Where-Object macht "Einzelverarbeitung"
 +      * ''$_'' -> aktuelles Element
 +
 +<code>
 +# alle Prozesse anzeigen, deren Id größer als 4000 ist
 +Get-Process | Where-Object {$_.Id -ge 4000}
 +
 +# alle Files anzeigen, die größer als 4000 Bytes sind
 +Get-ChildItem -Path C:\Windows -File | Where-Object {$_.Length -ge 4000}
 +</code>
 +
 +  * Select-Object
 +<code>
 +# alle Prozesse anzeigen, die mit 's' anfangen (=ein paar Dutzend wg svchost)
 +Get-Process -Name s*
 +
 +# alle Prozesse anzeigen, die mit 's' anfangen und Unique sind (kommen nur ein paar raus)
 +Get-Process -Name s*| Select-Object Unique
 +</code>
 +
 +  * Sort-Object
 +<code>
 +# 50 neueste EventLog Einträge anzeigen, sortiert nach InstanceId 
 +Get-EventLog -LogName System -Newest 50 | Sort-Object -Property InstanceId
 +</code>
 +
 +  * Where-Object
 +<code>
 +# Vereinfachte Syntax (einfacher, kann aber keine UND, ODER etc)
 +Get-Service | Where-Object Status -EQ Running
 +
 +# Klassische Syntax
 +Get-Service | Where-Object {$_.Status -EQ "Running"}
 +
 +Get-Service | Where-Object {$_.Status -EQ "Running" OR $_.Name -Like "s*"}
 +</code>
 +
 +  * Einsatztipps für Pipeline
 +    * So einfach wie möglich gestalten
 +    * ...
 +
 +  * Übung ...
 +<code>
 +# 1 Alle Dienste, die nicht aktiv sind
 +Get-Service | Where-Object {$_.Status -ne "Running"}
 +
 +# oder
 +Get-Service | Where-Object Status -eq Stopped
 +
 +# 2 Alle Prozesse, die mit W beginnen
 +Get-Process -Name W*
 +# oder
 +Get-Process W*
 +
 +# 3 Alle Ereignisse mit Status Warning
 +Get-EventLog -LogName System -EntryType Warning
 +
 +# 4 Wie viele Befehle mit Verb Import
 +(Get-Command -CommandType Cmdlet -Verb Import).count
 +
 +# 5 Sortiere alle .exe die größer als 1KB in C:\Windows nach Größe absteigend
 +Get-ChildItem -Path C:\Windows | Where-Object -FilterScript {$.Extension -eq ".exe" -and $_.Length -gt 1KB} | Sort-Object -Property Length -Descending
 +</code>
 +
 +  * ForEach-Object
 +<code>
 +# jede Ziffer mit 2 multiplizieren
 +3,4,5,6,7 | ForEach-Object -Process {$_ * 2}
 +</code>
 +
 +  * Group-Object
 +    * Aggregation
 +<code>
 +Get-Service | Group-Object -Property Status
 +
 +# Dateien nach Erweiterung gruppieren, sortiert nach Anzahl
 +Get-ChildItem C:\Windows -File | Group-Object -Property Extension | Sort-Object -Property Count -Descending
 +</code>
 +
 +  * Measure-Object
 +    * "Statistik" der Ergebnisse
 +<code>
 +# Cmdlets zählen
 +Get-Command -CommandType Cmdlet| MeasureObject
 +
 +# Dateien nach Erweiterung gruppieren, sortiert nach Anzahl
 +Get-ChildItem C:\Windows -File | Measure-Object -Property Length -Sum -Maximum -Minimum -Average
 +</code>
 +
 +  * ForEach
 +    * kann auch 
 +      * Begin <Skript>
 +        * führt Skript VOR der Schleife aus
 +      * End <Skript>
 +        * führt Skript NACH der Schleife aus
 +
 +  * WhatIf
 +    * simuliert den Befehl, führt ihn aber nicht aus (gut zum Testen von "gefährlichen" Befehlen)
 +
 +  * Formatierung und Ausgabe
 +    * Out-File
 +      * in eine Datei ausgeben
 +    * Out-GridView
 +      * in eine interaktive(!) Tabelle ausgeben
 +    * Out-Host
 +      * in die Konsole ausgeben
 +    * Out-Null
 +      * auf "Null"-Konsole (=nichts ausgeben)
 +    * Out-Printer
 +      * auf einen Drucker ausgeben
 +
 +  * PassThru
 +    * an den nächsten Befehl ausgeben (?)
 +
 +  * Export-Cmdlets
 +    * Export-Clixml
 +      * export als XML
 +    * Export-Csv
 +      * export als CSV
 +
 +<code>
 +Get-Process | Export-Clixml -Path C:\prozess.xml
 +</code>
 +
 +  * ConvertTo-Cmdlets
 +    * ähnlich wie Export-Cmdlets, aber geschrieben wird nicht in eine Datei, sondern auf den Bildschirm
 +    * ConvertTo-Csv
 +    * ConvertTo-Html
 +    * ConvertTo-SecureString
 +      * Kennwörter speichern
 +==== Übung 4 ====
 +
 +Meine Lösung:
 +
 +<code>
 +# 1
 +Get-Service -Name s* | Where-Object {$_.Status -eq "Stopped"}
 +
 +# 2
 +Get-ChildItem C:\Windows -File| Sort-Object Length -Descending | Export-Csv -Path C:\Users\v.kalaschnikow\Desktop\dateien.csv
 +
 +# 3
 +Get-Process | Export-Csv -Path C:\Users\v.kalaschnikow\Desktop\processe1.csv
 +Get-Process | Export-Csv -Path C:\Users\v.kalaschnikow\Desktop\processe2.csv -Delimiter ";"
 +Get-Process | Export-Csv -Path C:\Users\v.kalaschnikow\Desktop\processe3.csv -UseCulture
 +
 +# 4
 +Get-ChildItem -Path C:\Windows -File -Name *.exe | Measure-Object -Property Length -Sum -Average
 +
 +# 5 a)
 +1..10 | ForEach-Object -Process {notepad.exe}
 +
 +# 5 b)
 +Get-Process -Name notepad | ForEach-Object -Process {Stop-Process $_}
 +
 +
 +</code>
 +
 +Muster-Lösung von Michael:
 +
 +<code>
 +# 1
 +Get-Service -Name s* | Where-Object {$_.Status -EQ "Stopped"}
 +
 +# Alternative:
 +Get-Service -Name s* | Where Status -EQ Stopped
 +
 +# 2
 +Get-ChildItem C:\Windows -File| Sort-Object -Property Length -Descending | Export-Csv -Path .\dateien.csv
 +
 +# 3
 +Get-Process | Export-Csv -Path .\processe1.csv
 +Get-Process | Export-Csv -Path .\processe2.csv -Delimiter ";"
 +# nimmt den Trennzeichen abhängig von der Tastatureinstellung, also bei (de_DE) => ";"
 +Get-Process | Export-Csv -Path .\processe3.csv -UseCulture
 +
 +# 4
 +Get-ChildItem -Path C:\Windows -File -Name *.exe | Measure-Object -Property Length -Sum -Average
 +# Alternative
 +Get-ChildItem C:\Windows\*.exe | Measure-Object -Property Length -Sum -Average
 +# Alternative
 +Get-ChildItem -Path C:\Windows | Where-Object {$_.Extension -EQ ".exe"} | Measure-Object -Property Length -Sum -Average
 +
 +# 5 a)
 +1..10 | ForEach-Object -Process {notepad.exe}
 +
 +# 5 b)
 +Get-Process -Name notepad | Stop-Process
 +# Alternative
 +Get-Process -Name notepad | ForEach-Object -Process {Stop-Process $_}
 +
 +</code>
 +
 +==== Skript / Buch ====
 +
 +
 +Wir haben Kapitel 4 vom Buch "PowerShell 5. Grundlagen und Verwaltung des Active Directory" durchgenommen (nicht wirklich, aber der Michael orientiert sich ungefähr darauf). 
 +
 +
 +===== Tag 4: 13.02.2025 Donnerstag =====
 +
 +==== Vorlesung ====
 +
 +  * Wildcards in den Parametern nicht immer möglich
 +    * => im Einzelfall Dokumentation prüfen
 +  * ''Where-Object'' = ''Where'' (über Alias?)
 +  * ''Export-Csv'' kann man auch mit ''ConvertTo-Csv'' und dann ''Out-File'' implementieren
 +  * Datenspeicher in der PowerShell
 +    * RAM
 +    * Festplatte
 +    * DB
 +    * ...
 +
 +  * PowerShell Provider
 +    * Alias
 +    * Environment
 +    * FileSystem
 +    * Function
 +    * Variable
 +    * ...
 +  * Get-PSProvider
 +    * die verfügbaren Provider auflisten
 +<code>
 +# alle auflisten
 +Get-PSProvider
 +
 +# Info über PSProvider "Registry"
 +Get-PSProvider -PSProvider Registry
 +</code>
 +
 +  * PowerShell Laufwerke (PSDrive)
 +    * ''Get-PSDrive''
 +      * anzeigen
 +<code>
 +Get-PSDrive -Name Daten
 +
 +# alle properties anzeigen
 +Get-PSDrive -Name Daten | Select-Object -Property *
 +</code>
 +    * ''New-PSDrive''
 +      * anlegen
 +    * ''Remove-PSDrive''
 +      * löschen
 +
 +<code>
 +# Verzeichnis C:\Test\Privat anlegen (bzw. muss vorhanden sein), dann PSDrive anlegen
 +New-PSDrive -PSProvider FileSystem -Name prv -Root C:\Test\Privat
 +
 +# ins prv wechseln
 +Set-Location prv:
 +
 +# Prozesse in die Datei .\prozesse.txt schreiben
 +Get-Process | Set-Content .\prozesse.txt
 +</code>
 +
 +  * Löschen
 +    * man kann nicht löschen, wenn man drin ist
 +      * das kann man mit dem Parameter ''-Force'' umgehen
 +
 +  * Cmdlets für die Arbeit mit Verzeichnissen
 +    * Get-Location
 +    * Set-Location
 +    * Push-Location
 +    * Pop-Location (?)
 +
 +  * Set-Location
 +<code>
 +Set-Location alias:
 +
 +# alle in alias: auflisten
 +Get-ChildItem 
 +
 +Set-Location env:
 +# alle in env: auflisten
 +Get-ChildItem
 +
 +Set-Location variable:
 +# alle in variable: auflisten
 +Get-ChildItem
 +
 +Set-Location D:\
 +Set-Location D:\Support
 +</code>
 +
 +  * Push-Location
 +    * speichert aktuelle Location auf dem Stack
 +  * Pop-Location
 +    * eine Position im Stack hoch
 +      * => die oberste Location löschen
 +        * => man landet in der vorherigen
 +        * => wenn Stack leer -> in der aktuellen bleiben
 +
 +  * Cmdlets für die Arbeit mit Elementen und ihren Eigenschaften
 +    * Clear-Item
 +      * löscht Inhalt(!) eines Elements
 +    * Clear-ItemProperty
 +      * löscht den Wert(!) einer Property vom Element
 +    * Copy-Item
 +      * Element kopieren
 +    * Copy-ItemProperty
 +      * Property eines Elements kopieren
 +    * Get-Item
 +      * Ruft Infos eines Elements ab
 +    * Get-ItemProperty
 +      * Ruft den Wert einer Property ab
 +    * Invoke-Item
 +      * Standardaktion festlegen
 +    * Move-Item
 +      * Verschieben eines Elements (z.B. einer Datei)
 +    * Move-ItemProperty
 +      * verschieben einer Property
 +        * sinnvoll z.B. bei Registry Schlüsseln
 +    * New-Item
 +      * Items erstellen (Dateien, Registry Elemente etc.)
 +    * New-ItemProperty
 +    * Remove-Item
 +    * Remove-ItemProperty
 +    * Rename-Item
 +    * Rename-ItemProperty
 +    * Set-Item
 +      * dem Element einen neuen Wert zuweisen
 +        * funktioniert nicht immer (z.B. es funktioniert nicht bei Dateien)
 +    * Set-ItemProperty
 +      * ...
 +
 +<code>
 +Copy-Item -Path C:\Windows\Logs\DISM\dism.log -Destination C:\MeineLogs
 +
 +# Rekursiv:
 +Copy-Item -Path C:\Windows\Logs -Destination C:\MeineLogs
 +
 +Get-ChildItem -Path C:\Test -Include *.tmp | Remove-Item
 +
 +Get-ItemProperty -Path C:\test.txt | Select-Object -Property *
 +
 +# Property "Schreibgeschützt" auf TRUE setzen
 +Set-ItemProperty -Path C:\test.txt -Name IsReadOnly -Value $true
 +
 +# Erstellungsdatum auf heute minus 2 Tage setzen
 +Set-ItemProperty -Path C:\test.txt -Name creationTime -Value ((get-date).addDays(-2))
 +
 +</code>
 +
 +  * Laufwerke im Dateisystem
 +    * Add-Content
 +      * Content zur Datei hinzufügen
 +    * Create-Content
 +      * Content der Datei setzen (erstellen)
 +    * Get-Content
 +      * Content der Datei abrufen
 +    * Set-Content
 +      * Content der Datei setzen
 +
 +<code>
 +# (wenn Datei existiert wird sie überschrieben)
 +Get-Process -Name a* | Set-Content -Path C:\process.txt
 +
 +# die ersten 2 Zeilen der *.txt Dateien ausgeben
 +Get-ChildItem -Path C:\*.txt -Recurse | Get-Content -TotalCount 2
 +
 +# in die Datei notiz.txt Text "Wichtiger Termin um 14 Uhr!" schreiben
 +Set-Content -Path .\notiz.txt -Value "Wichtiger Termin um 14 Uhr!"
 +</code>
 +
 +  * N.B. Der Parameter ''-PassThru'' gibt die Ergebnisse an den nächste Befehl
 +    * wichtig z.B. bei GridView
 +
 +  * Registry Laufwerke
 +    * 2 Laufwerke
 +      * HKCU
 +        * HKEY_CURRENT_USER
 +      * HKLM
 +        * HKEY_LOCAL_MACHINE
 +<code>
 +Set-Location -Path HKLM:\SOFTWARE
 +
 +# Neues Verzeichnis dort (in der Registry) erstellen
 +# Type "Container" bedeutet so was wie "Verzeichnis" in der Registry
 +New-Item -Path "MeineSoftware" -ItemType Container 
 +
 +New-ItemProperty -Path "HKLM:\SOFTWARE\MeineSoftware" -Name Version -Value "1.0" -PropertyType String
 +
 +# man kann auch Hex-Werte anlegen
 +New-ItemProperty -Path "HKLM:\SOFTWARE\MeineSoftware" -Name MyHex -Value 0xABC -PropertyType DWORD
 +</code>
 +
 +  * Set-ItemProperty
 +    * Werte ändern
 +  * Remove-ItemProperty
 +    * Werte löschen
 +
 +  * Laufwerk für Umgebungsvariablen (Provider Environment)
 +
 +<code>
 +Get-ChildItem -Path Env:\
 +</code>
 +
 +  * händisch kann man die Umgebungsvariablen unter "Systemeigenschaften / Umgebungsvariablen" finden
 +
 +  * ''Env:'' hat keine Hierarchie, alle Variablen sind direkt in ''Env:''
 +  * Variablen addressieren
 +    * ''$env:<VariablenName>''
 +      * z.B. ''$env:PATH'' oder ''$env:computername''
 +
 +  * Aliase
 +    * Abkürzungen für Befehle
 +      * 2 Arten
 +        * eingebaut
 +        * User-definiert
 +    * es gibt einen Provider ''Alias''
 +
 +<code>
 +# in die Location alias: wechseln
 +Set-Location alias:
 +
 +# Alle Aliase auflisten
 +Get-ChildItem
 +
 +# alle auflisten
 +Get-Alias
 +
 +# alle wo der Befehl "MyCmd" vorkommt auflisten
 +Get-Alias -Definition MyCmd
 +</code>
 +
 +  * Eigene Aliase definieren
 +    * Set-Alias
 +      * einen neuen oder vorhandenen definieren
 +    * New-Alias
 +      * einen neuen definieren
 +        * wenn existiert -> Fehler
 +
 +  * Export / Import von Aliasen
 +    * die Aliase sind nur für die aktuelle Sitzung gültig deshalb macht es Sinn sie zu exportieren / importieren
 +
 +<code>
 +# alle exportieren
 +Export-Alias -Path alias-export.txt
 +
 +Import-Alias -Path alias-export.txt
 +
 +
 +# nur mit den definierten Namen exportieren
 +Export-Alias -Path alias-export.txt -Name alias1, alias2, alias3
 +
 +# zu der bestehenden Datei hinzufügen
 +Export-Alias -Path alias-export.txt -Name alias4, alias5, alias6
 +
 +</code>
 +
 +  * Aliase entfernen
 +    * Remove-Item
 +
 +<code>
 +Remove-Item -Path alias:\aliasNameToRemove
 +</code>
 +
 +==== Übung 5.9 (Seite 78) ====
 +<code>
 +# 1
 +Get-PSDrive -PSProvider FileSystem
 +
 +# 2 a)
 +New-Item -Path C:\Testdaten -ItemType Directory
 +
 +# Alternativ
 +# mkdir C:\Testdaten
 +
 +# 2 b)
 +New-PSDrive -PSProvider FileSystem -Name Testdaten -Root C:\Testdaten
 +
 +# 2 c)
 +Set-Location Testdaten:
 +
 +# 3 a)
 +New-Item notiz.txt -ItemType File
 +
 +# 3 b)
 +Get-Process -Name s*, w* | Select-Object –Property Name, ID | Set-Content .\prozesse.txt
 +# Alternativ
 +# Get-Process | Select-Object –Property Name, Id | Where {$_.Name -Like "s*" -or $_.Name -Like "w*"} | Set-Content .\prozesse.txt
 +
 +# 4. Schreiben Sie in die Datei notiz.txt
 +# a) aktuelle Datumsinformationen sowie
 +Get-Date | Set-Content .\notiz.txt
 +# Alternativ
 +# Add-Content -Path .\notiz.txt -Value (Get-Date)
 +
 +# b) die Liste der Dateinamen im Laufwerk Testdaten:.
 +Set-Location Testdaten:
 +Get-ChildItem Testdaten: | Add-Content -Path .\notiz.txt
 +
 +# 5. Versehen Sie die Datei prozesse.txt mit einem Schreibschutz.
 +Set-ItemProperty -Path C:\Testdaten\prozesse.txt -Name IsReadOnly -Value $true
 +
 +# 6. Löschen Sie den Inhalt(!) der Datei prozesse.txt.
 +Clear-Content -Path .\prozesse.txt
 +# tut nicht, da IsReadOnly auf true steht, also zuerst auf false setzen oder mit -Force Parameter
 +Clear-Content -Path .\prozesse.txt -Force
 +
 +# 7. Löschen Sie das virtuelle PowerShell-Laufwerk Testdaten: aus der Liste der PowerShell-Laufwerke.
 +# (alle Laufwerke kann man mit "Get-PSDrive" auflisten)
 +Remove-PSDrive Testdaten
 +# wird nicht direkt funktionieren, da "Testdaten" aktuelles Laufwerk ist
 +# => also zuerst auf ein anderes Laufwerk wechseln (z.B. mit "Set-Location C:")
 +# ODER auch mit -Force Parameter
 +Remove-PSDrive Testdaten -Force
 +
 +
 +</code>
 +
 +==== Übung 6.6 (Seite 85) ====
 +
 +Meine Lösung:
 +
 +<code>
 +# 1. Listen Sie alle Aliase auf, deren Name mit dem Buchstaben H beginnen.
 +Get-Alias -Name H*
 +
 +# 2. Listen Sie alle Aliase für das Cmdlet Remove-Item auf.
 +Get-Alias -Definition Remove-Item
 +
 +# 3. Definieren Sie drei eigene Aliase mit den Namen aaa, bbb und ccc, die stellvertretend für die Cmdlets GetProcess, Get-Random und Get-Service verwendet werden sollen.
 +New-Alias -Name "aaa" Get-Process
 +New-Alias -Name "bbb" Get-Random
 +New-Alias -Name "ccc" Get-Service
 +
 +# Macht es einen Unterschied, ob Sie für die Definition der Aliase das Cmdlet New-Alias oder das
 +# Cmdlet Set-Alias verwenden?
 +#
 +# Antwort: 
 +# Ja, New-Alias kann nur erstellen. Wenn Alias vorhanden, wird es New-Alias auf Fehler gehen. 
 +# Also wenn vorhanden kann man nur Set-Alias verwenden.
 +
 +# 4. Exportieren Sie die drei gerade definierten Aliase in eine Textdatei eigene-aliase.txt im aktuellen
 +# Verzeichnis.
 +Export-Alias -Path .\Desktop\eigene-aliase.txt -Name aaa, bbb, ccc
 +
 +# 5. Definieren Sie einen vierten Alias ddd für das Cmdlet Get-PSProvider.
 +Set-Alias -Name "ddd" Get-PSProvider
 +
 +# 6. Exportieren Sie den vierten Alias in die vorhandene Textdatei eigene-aliase.txt. Überschreiben Sie dabei
 +# nicht die bereits vorhandenen Daten.
 +Export-Alias -Path .\Desktop\eigene-aliase.txt -Name ddd -Append
 +
 +# 7. Schließen Sie die PowerShell und öffnen Sie sie erneut. Importieren Sie Ihre eigenen Aliase aus der Datei
 +# eigene-aliase.txt. Überprüfen Sie dann, ob die Aliase vorhanden sind.
 +Import-Alias -Path .\Desktop\eigene-aliase.txt
 +
 +# 8. Löschen Sie manuell die vier von Ihnen erstellten Aliase.
 +Remove-Item -Path alias:\aaa, alias:\bbb, alias:\ccc, alias:\ddd
 +</code>
 +
 +
 +Musterlösung von Michael:
 +
 +<code>
 +# Aufgabe 1
 +Get-Alias -Name h*
 +
 +# Aufgabe 2
 +Get-Alias -Definition Remove-Item
 +
 +# Aufgabe 3
 +Set-Alias -Name aaa -Value Get-Process
 +Set-Alias -Name bbb -Value Get-Random
 +Set-Alias -Name ccc -Value Get-Service
 +
 +# Aufgabe 4
 +Export-Alias -Path .\eigene-aliase.txt -Name aaa, bbb, ccc
 +
 +# Aufgabe 5
 +Set-Alias -Name ddd -Value Get-PSProvider
 +
 +# Aufgabe 6
 +Export-Alias -Path .\eigene-aliase.txt -Name ddd -Append
 +
 +# Aufgabe 7
 +Import-Alias -Path .\eigene-aliase.txt
 +Get-Alias -Name aaa, bbb, ccc, ddd
 +
 +# Aufgabe 8
 +Remove-Item -Path Alias:\aaa
 +Remove-Item -Path Alias:\bbb
 +Remove-Item -Path Alias:\ccc
 +Remove-Item -Path Alias:\ddd
 +</code>
 +
 +===== Tag 5: 14.02.2025 Freitag =====
 +==== Vorlesung ====
 +  * "Kapitel 7. Profile" wird erstmal ausgelassen
 +  * Wir machen weiter mit "Kapitel 8.
 +
 +  * Variablen
 +    * Speicher -> Variable
 +
 +<code>
 +Get-PSDrive
 +cd variable:
 +</code>
 +
 +  * Einstellungsvariablen
 +    * Speichern Einstellungen der PowerShell
 +      * z.B. ''$MaximumAliasCount'' oder ''$MaximumHistoryCount''
 +
 +<code>
 +# Ausgabe einer Variable
 +$HOME
 +C:\Users\Administrator
 +</code>
 +
 +  * Automatische Variablen
 +    * haben ihre Werte abhängig von der "Situation"
 +      * z.B. $HOME ist abhängig vom angemeldeten Benutzer
 +      * $?
 +      * $Error
 +  * Benutzerdefinierte Variablen
 +    * New-Variable
 +      * erstellen einer Variable
 +      * $null -> Default-Wert einer Variable wenn nichts zugewiesen
 +<code>
 +New-Variable -Name myVar -Value 123
 +</code>
 +    * Set-Variable
 +    * Clear-Variable
 +    * Remove-Variable
 +
 +<code>
 +New-Variable -Name zahl1
 +New-Variable -Name zahl2 -Value 200
 +New-Variable -Name text1 -Value "Hallo, Welt!"
 +
 +# alle auflisten
 +Get-Variable
 +
 +# Wert setzen
 +Set-Variable -Name zahl2 -Value 200
 +
 +# Erstellen (vereinfachte Schreibweise) mit Wert 300
 +$zahl3 = 300
 +
 +# Ändern auf 200
 +$zahl3 = 200
 +
 +# Inhalt löschen
 +$zahl3 = $null
 +
 +# Typbindung gibt es nicht
 +$text2 = 50
 +$text2 = "Das ist ein Text"
 +
 +</code>
 +
 +  * Eigene Variablen sind flüchtig
 +    * => sie gelten nur für die aktuelle Session
 +  * Bei Set-Value
 +    * 37 * 11
 +      * => Fehler, da als 3 Parameter interpretiert wird
 +    * 37*11
 +      * => Fehler, da als Zeichenkette interpretiert wird
 +    * (37*11)
 +      * => Ergebnis ist 407
 +    * also wenn rechnen notwendig ist => in Klammern setzen
 +      * aber bei der "vereinfachten" Schreibweise funktioniert rechnen
 +
 +  * Anderes Beispiel
 +<code>
 +# aktuelles Datum speichern
 +$datum1 = Get-Date
 +
 +# Zeichenkette "Get-Date" drin (!)
 +New-Variable -Name datum1 -Value Get-Date
 +
 +# Datum drin (wg. Klammern)
 +New-Variable -Name datum1 -Value (Get-Date)
 +</code>
 +
 +  * Variablentypen (aus .NET genommen)
 +    * int
 +    * long
 +    * string (Unicode)
 +    * char (Unicode => 16bit)
 +    * bool
 +    * decimal
 +    * ...
 +    * Byte
 +      * -127 bis +127
 +      * wg. 1 bit => Vorzeichen
 +
 +<code>
 +# Type explizit definieren
 +[int] $zahl5=200
 +
 +# geht nicht wg. Typeverletzung
 +$zahl5 = "MeinText"
 +</code>
 +
 +  * N.B. In diesem Kurs wird aber keine Typenbindung verwendet
 +
 +<code>
 +# array
 +$zahlen=1,2,3,200
 +
 +# dem nullten element wert zuweisen
 +$zahlen[0] = 23
 +
 +# Wert des nullten Elementes holen
 +$zahlen[0]
 +
 +# Ein Element zum Array hinzufügen
 +$zahlen += 250
 +
 +# prozesse in den array holen
 +$prozesse = Get-Process
 +
 +# das 4-te element holen
 +$prozesse[4]
 +
 +# dateien aus C:\Windows in Variable speichern
 +$dateien = Get-ChildItem C:\Windows\ -File
 +
 +# Alle properties von dem 2-ten element holen
 +$dateien[2] | Select -Property *
 +
 +</code>
 +
 +  * Konstanten
 +
 +<code>
 +New-Variable -Name MyConst -Value 3.1415 -Option Constant
 +</code>
 +
 +  * Variablen auf dem Bildschirm ausgeben
 +
 +<code>
 +# Mit double quotes wird die Variablenauflösung gemacht
 +Write-Host "Ergebnis: $ergebnis"
 +
 +# Mit single quotes wird KEINE Variablenauflösung gemacht
 +Write-Host 'Ergebnis: $ergebnis#
 +</code>
 +
 +  * Arithmetische Operationen
 +    * +, -, *, /, %, ++, --, +=, -=, *=, /=
 +      * N.B. zu "+="
 +        * $a += $b
 +        * ist dasgleiche wie
 +        * $a = $a + $b
 +  * Vergleichsoperatoren
 +    * -eq, -ne, -gt, -ge, -lt, -le, -Contains, -NotContains
 +    * Textvergleiche sind nicht Case-sensitive
 +      * "Harry" -eq "harry"
 +        * => liefert TRUE
 +    * case-sensitive Vergleiche
 +      * -ceq, -cne, ...
 +      * "Harry" -ceq "harry"
 +        * => liefert FALSE
 +        * (-ceq ist case-sensitive variante von -eq)
 +    * -Contains, -NotContains
 +      * prüft ob im Array(!) ein Wert vorkommt / nicht vorkommt
 +    * -In, -NotIn
 +      * Contains, aber "andersherum" (also ob ein Array ein Wert enthält)
 +<code>
 +"ab" -In "ab", "bc", "cd"
 +</code>
 +
 +    * -Is / -IsNot
 +      * Prüfung auf Typgleichheit
 +    * -Like / -NotLike
 +      * Mustervergleich (mit Wildcards)
 +    * -Match / -NotMatch
 +      * Mustervergleich OHNE Wildcards (aber RegExes möglich)
 +    * TypeOf / GetType (<- Functions)
 +      * ''$zahl1.GetType()
 +
 +  * Logische Operatoren
 +    * -and, -or, -xor, -not ...
 +
 +
 +  * Kontrollstrukturen in der PowerShell
 +...
 +
 +
 +  * Kontrollstrukturen in der PowerShell
 +    * If - Anweisung
 +<code>
 +If($x -eq 27)
 +{
 +  Write-Host "Der Wert der Variable x ist gleich 27"
 +}
 +</code>
 +    * If/Else - Anweisung
 +<code>
 +If($x -eq 27)
 +{
 +  Write-Host "Der Wert der Variable x ist gleich 27"
 +}
 +Else
 +{
 +  Write-Host "Der Wert der Variable x ist nicht 27"
 +}
 +</code>
 +
 +
 +  * Beispiel
 +<code>
 +$eingabe = read-host -Prompt "Bitte eine Zahl eingeben"
 +If($eingabe -gt 8)
 +{
 +  Write-Host "Die Zahl $eingabe ist größer 8"
 +}
 +Else
 +{
 +  Write-Host "Die Zahl $eingabe ist kleiner oder gleich 8"
 +}
 +</code>
 +
 +    * If/ElseIf - Anweisung
 +
 +<code>
 +if($x -eq 27)
 +{
 +  Write-Host "Der Wert ist 27"
 +}
 +</code>
 +    * If/Else
 +    * If/IfElse
 +    * If / IfElse / Else
 +    * Switch
 +<code>
 +switch ($variable)
 +{
 +  Wert1 {
 +    # block1
 +  }
 +  Wert2 {
 +    # block1
 +  }
 +  default {
 +    # default block
 +  }
 +}
 +</code>
 +
 +  * Schleifen
 +    * While
 +    * Do-While
 +    * Do-Until 
 +      * wiederholen solange die Bedingung FALSE ist
 +    * For
 +<code>
 +for($a=1;$a -le 5; $a++)
 +{
 +# ...
 +}
 +</code>
 +    * ForEach
 +<code>
 +$array = 2, 4, 5, 6
 +forEach($wert in $array)
 +{
 +# ...
 +}
 +
 +# anderes Beispiel
 +$dateien = Get-ChildItem C:\Windows -File
 +forEach($datei in $dateien)
 +{
 +# ...
 +  $datei.Length / 1024 + " KB" + " - " + $datei.Name
 +}
 +</code>
 +
 +  * Anweisungen zur Ablaufsteuerung
 +    * break
 +      * Schleife komplett beenden
 +    * continue
 +      * den aktuellen Durchlauf beenden
 +==== Übung 8.18 Teil 1 (Seite 118) ====
 +
 +<code>
 +# 1. 
 +# a) Erstellen Sie eine Variable $geld und weisen Sie ihr den Wert 68 zu.
 +$geld = 68
 +
 +
 +# b) Teilen Sie den Wert mit einem weiteren Befehl durch 4. Nutzen Sie dafür einen möglichst kurzen Befehl.
 +$geld /= 4
 +
 +# c) Erstellen Sie eine Konstante $c_euro mit dem Wert Euro in meiner Geldbörse.
 +
 +New-Variable -Name c_euro -Value "Euro in meiner Geldbörse" -Option Constant
 +
 +$c_euro
 +
 +# d) Lassen Sie den Satz "Ich habe x Euro in meiner Geldbörse." ausgeben. Anstelle des "x" soll der Wert der Variablen $geld stehen.
 +
 +"Ich habe $geld Euro in meiner Geldbörse"
 +
 +# 2. a) Legen Sie eine Arrayvariable $prozesse an, die als Werte die Namen der aktuell auf Ihrem System
 +# laufenden Prozesse enthält.
 +$processe = (Get-Process).Name
 +
 +# b) Lassen Sie sich den 6. Eintrag des Arrays anzeigen.
 +$processe[5]
 +
 +# 3. a) Vergleichen Sie, ob "Hans" mit "hans" identisch ist (einmal mit und einmal ohne Unterscheidung von
 +# Groß- und Kleinschreibung).
 +"Hans" -eq "hans"
 +
 +"Hans" -ceq "hans"
 +
 +
 +# b) Prüfen Sie, ob 74 / 3 größer oder gleich 24.6 ist.
 +
 +(74 / 3) -ge 24.6 
 +
 +# c) Finden Sie heraus, ob im Wert der Variablen $HOME der Buchstabe o enthalten ist.
 +$HOME -Match "o"
 +# alternative
 +$HOME -Like "*o*"
 +
 +</code>
 +
 +==== Übung 8.18 Teil 2 (Seite 118) ====
 +
 +Meine Lösung:
 +<code>
 +# 1. 
 +# a) Speichern Sie einen Wert zwischen 1 und 10 in einer Variablen. Fragen Sie ab, ob der Wert größer als 5
 +# ist, und geben Sie den Text "Wert ist größer als 5" aus, wenn die Bedingung zutrifft.
 +
 +#$myVar = 4
 +
 +$myVar = Read-Host -Prompt "Bitte geben Sie eine Zahl ein"
 +if($myVar -gt 5)
 +{
 +  "Der Wert $myVar ist größer als 5"
 +}
 +
 +
 +# b) Erweitern Sie das Beispiel: Prüfen Sie, ob der Variablenwert gleich 5 ist, und geben Sie in dem Fall den
 +# Text "Wert ist gleich 5" aus.
 +
 +#$myVar = 5
 +$myVar = Read-Host -Prompt "Bitte geben Sie eine Zahl ein"
 +if($myVar -gt 5)
 +{
 +  "Der Wert $myVar ist größer als 5"
 +}
 +ElseIf($myVar -eq 5)
 +{
 +  "Der Wert $myVar ist gleich 5"
 +}
 +
 +# c) Erweitern Sie nochmals das Beispiel: Geben Sie jetzt noch für alle anderen Fälle den Text "Wert ist
 +# kleiner als 5" aus. (Prüfen Sie mit unterschiedlichen Werten.)
 +
 +$myVar = 4
 +if($myVar -gt 5)
 +{
 +  "Der Wert $myVar ist größer als 5"
 +}
 +ElseIf($myVar -eq 5)
 +{
 +  "Der Wert $myVar ist gleich 5"
 +}
 +Else
 +{
 +  "Der Wert $myVar ist kleiner als 5"
 +}
 +
 +# 2. Legen Sie eine Variable $note an und weisen Sie ihr einen Wert zwischen 1 und 6 zu. Verwenden Sie die
 +# Switch-Anweisung, um für die Werte die entsprechenden Texte gemäß der folgenden Tabelle auszugeben:
 +# Note Text
 +# 1 sehr gut
 +# 2 gut
 +# 3 befriedigend
 +# 4 ausreichend
 +# 5 mangelhaft
 +# 6 ungenügend
 +# Experimentieren Sie mit verschiedenen Werten.
 +
 +#$note = 1
 +$note = Read-Host -Prompt "Bitte geben Sie eine Note ein: "
 +Switch ($note)
 +{
 +  1 {
 +    "sehr gut"
 +  }
 +  2 {
 +    "gut"
 +  }
 +  3 {
 +    "befriedigend"
 +  }
 +  4 {
 +    "ausreichend"
 +  }
 +  5 {
 +    "mangelhaft"
 +  }
 +  6 {
 +    "ungenügend"
 +  }
 +  default {
 +    "Diese Note ist nicht bekannt"
 +  }
 + 
 +}
 +
 +# 3. Programmieren Sie eine Schleife, die die Werte 10 bis 100 in Zehnerschritten ausgibt.
 +
 +For($i=10;$i -le 100; $i+=10) 
 +{
 +  $i
 +}
 +
 +# 4. Geben Sie mithilfe einer For-Schleife die ganzen Vielfachen der Zahl 5 bis zum Wert 100 aus.
 +For($i=1;$i -le 100; $i++) 
 +{
 +  if($i%5 -eq 0)
 +  {
 +    $i
 +  }
 +}
 +</code>
 +
 +Muster-Lösung von Michael:
 +<code>
 +# Uebung zu Kapitel 8
 +
 +#1a. Erstellung einer Variablen geld und Zuweisung des Wertes 68
 +$geld = 68
 +
 +
 +
 +
 +#1b. Den Wert der Variablen durch 4 Teilen mit einem kurzen Befehl
 +
 +$geld /= 4
 +
 +
 +
 +
 +#1c. Erstellung einer Konstanten $c_euro mit dem Wert "Euro in meiner Geldbörse"
 +New-Variable -Name c_euro -Value "Euro in meiner Geldbörse" -Option Constant
 +
 +
 +
 +
 +#1d.  Ausgabe des Wertes mit der Konstanten
 +Write-Host "Ich habe $geld $c_euro."
 +Write-Host 'Ich habe $geld $c_euro.'
 +
 +
 +write-host ("Ich habe " + $geld + " " + $c_euro + ".")
 +
 +
 +
 +
 +
 +#2a. Variable prozesse anlegen die alle Namen der laufenden Prozesse erhalten soll
 +$prozesse = Get-Process | Select-Object -Property Name
 +
 +
 +
 +
 +#2b. Anzeige des 6. Prozesses aus der Liste
 +$prozesse[5]
 +
 +
 +
 +
 +
 +
 +
 +#3a. Vergleiche die Strings hans und Hans. Einmal CS einmal CI
 +"Hans" -eq "hans"
 +"Hans" -ceq "hans"
 +
 +
 +
 +
 +#3b. prüfe ob 74/3 größer als 24.6 ist
 +(74/3) -ge 24.6
 +
 +
 +
 +
 +#3c. hersausfinden ob in der Variablen $Home das Zeichen o enthalten ist
 +$HOME -match "o"
 +$HOME -like "*o*"
 +
 +
 +
 +
 +
 +#4a. in einer Variablen einen wert zwischen 1 und 10 speicher und prüfen ob der Wert größer 5 ist
 +#$wert = 6
 +
 +$wert = Read-Host -Prompt "Geben Sie eine Zahl ein"
 +if ($wert -gt 5)
 +{
 + Write-Host " Der Wert der Variablen ist $wert und ist größer als 5"
 +}
 +
 +
 +
 +
 +#4b. Beispiel 4a erweitern mit der Prüfung gleich 5
 +#$wert = 5
 +
 +$wert = Read-Host -Prompt "Geben Sie eine Zahl ein"
 +if ($wert -gt 5)
 +{
 + Write-Host " Der Wert der Variablen ist $wert und ist größer als 5"
 +}
 +elseif($wert -eq 5)
 +{
 +  Write-Host " Der Wert der Variablen ist $wert und ist gleich 5"
 +}
 +
 +
 +
 +
 +#4c. Beispiel aus 4b erweitern mit dem Fall $wert ist kleiner als 5 
 +#$wert = 3
 +
 +$wert = Read-Host -Prompt "Geben Sie eine Zahl ein"
 +if ($wert -gt 5)
 +{
 + Write-Host " Der Wert der Variablen ist $wert und ist größer als 5"
 +}
 +elseif($wert -eq 5)
 +{
 +  Write-Host " Der Wert der Variablen ist $wert und ist gleich 5"
 +}
 +else
 +{
 + Write-Host " Der Wert der Variablen ist $wert und kleiner als 5"
 +}
 +
 +
 +
 +
 +
 +#5. anlegen der Variablen Note und zuweisen eines Wertes von 1 bis 6. ausgabe der zahl als Text mit Switch
 +#$Note = 3
 +
 +$Note = Read-Host -Prompt "Geben Sie eine Schulnote ein"
 +switch($Note)
 +{
 + 1 {write-host "Note: Sehr gut"}
 + 2 {write-host "Note: Gut"}
 + 3 {write-host "Note: Befriedigend"}
 + 4 {write-host "Note: Ausreichend"}
 + 5 {write-host "Note: Mangelhaft"}
 + 6 {write-host "Note: Ungenügend"}
 + default {"Diese Note ist nicht bekannt!"}
 +}
 +
 +
 +
 +
 +
 +#6. Erstellung einer Schleife welche die Werte von 10 bis 100 in 10er Schritten ausgibt
 +$zaehler = 10
 +while($zaehler -le 100)
 +{
 + Write-Host $zaehler
 + $zaehler = $zaehler + 10
 +}
 +
 +
 +
 +
 +
 +#7. Alle Vielfachen der Zahl 5 bis 100 ausgeben mit einer For Schleife
 +for($zaehler = 5; $zaehler -le 100; $zaehler = $zaehler + 5)
 +{
 + Write-Host $zaehler
 +}
 +
 +</code>
 +==== Übung 8 (Von Michael als "Extra-Aufgabe") ====
 +
 +Noch nicht fertig...
 +
 +<code>
 +# Legen Sie ein Verzeichnis C:\TestVZ an wenn es noch nicht existiert!
 +# Falls das Verzeichnis existieren sollte dann löschen Sie den Inhalt vollständig.
 +$myPath="C:\Users\v.kalaschnikow\Desktop"
 +
 +cd $myPath
 +
 +If((Test-Path -Path "$myPath\TestVZ" ))
 +{
 +  "TestVZ existiert"
 +
 +  cd "$myPath\TestVZ"
 +  $children = (Get-ChildItem)
 +  ForEach($currentChild in $children) {
 +    Remove-Item $currentChild
 +  }
 +}
 +else
 +{
 +  "TestVZ existiert NICHT"
 +  
 +  mkdir TestVZ
 +  #New-Item -Name "TestVZ" -ItemType Directory
 +}
 +
 +
 +# Legen Sie 20 Dateien mit dem Namen "MeineDatei(x).txt" in dem Verzeichnis C:\TestVZ an
 +# wobei x durch die Zahlen 1 bis 20 ersetzt wird
 +
 +cd "$myPath\TestVZ"
 +
 +for($x=1;$a -le 20; $a++)
 +{
 +  Set-Content .\MeineDatei($x).txt
 +}
 +
 +# Prüfen Sie das aktuelle Datum Ihres Systems. 
 +# Falls das Datum in der ersten Hälfte des Monats befindet, (also zwischen dem 1 und 15), legen Sie eine 
 +# Datei mit dem Namen "MeineProzesse.txt" mit dem Inhalt der aktuellen Prozesse Ihres Systems an.
 +
 +Get-Date | Set-Content .\MeineProzesse.txt
 +
 +# Falls das Datum in der zweiten Hälfte des Monats befindet, (> 15), legen Sie eine 
 +# Datei mit dem Namen "MeineDienste.txt" mit dem Inhalt der aktuellen Dienste Ihres Systems an.
 +$day = Get-Date | Get-Member -MemberType day
 +if()
 +
 +# Ermitteln Sie den Wert des Attributes "LasAccessTime" aller Dateien im Verzeichnis TestVZ und ändern Sie 
 +# den Wert  gemäß der aktuellen Uhrzeit wie folgt:
 +# Vor 12 Uhr: heutiges Datum - 1 Tag
 +# Nach 12 Uhr: heutiges Datum - 2 Tage
 +
 +# Prüfen Sie die Angaben des Attributes "LastAccessTime" auf deren erfolgreiche Änderungen
 +</code>
 +
 +Muster-Lösung von Michael:
 +<code>
 +# Beispiel zu Kontrollstrukturen und Variablen
 +
 +
 +
 +
 +
 +$VerzeichnisVorhanden = Test-Path -Path c:\TestVZ
 +
 +
 +
 +if(-not $VerzeichnisVorhanden)
 +{
 +    New-Item -ItemType Directory -Path c:\TestVZ
 +}
 +
 +else
 +{
 +    Get-ChildItem -Path c:\TestVZ\*.* -Recurse | Remove-Item -Force
 +}
 +
 +
 +
 +
 +
 +
 +for($i=1; $i -le 20; $i++)
 +{
 +    New-Item -ItemType File -Path C:\TestVZ -name "MeineDatei$i.txt" 
 +}
 +
 +
 +
 +
 +
 +
 +
 +$Datum = (get-date).Day
 +if($Datum -lt 16)
 +{
 +    Get-Process | out-file -FilePath C:\TestVZ\MeineProzesse.txt
 +}
 +else
 +{
 +    Get-Service | Out-File -FilePath C:\TestVZ\MeineDienste.txt
 +}
 +
 +
 +
 +
 +
 +$Dateien = Get-ChildItem C:\TestVZ -File
 +
 +foreach ($Datei in $Dateien)
 +{
 +  If ((Get-date).Hour -lt 12)
 +  {
 +    $NeuesDatum = (get-date).AddDays(-1)
 +  }
 +  else
 +  {
 +    $NeuesDatum = (get-date).AddDays(-2)
 +  }
 +
 +    ($Datei).LastAccessTime = $NeuesDatum
 +  
 +}
 +
 +
 +
 +Get-ChildItem C:\TestVZ -File | select -Property Name, LastAccessTime
 +</code>
 +
 +==== Übung 9 ====
 +Musterlösung von Michael:
 +
 +<code>
 +$VerzeichnisVorhanden = Test-Path -Path c:\testVZ
 +
 +if(-not $VerzeichnisVorhanden)
 +{
 +New-Item -ItemType Directory -Path c:\testVZ
 +}
 +else
 +{
 +Get-ChildItem -Path c:\testVZ\*.* | Remove-Item -Force
 +}
 +
 +$FreeSpace = (get-psdrive -Name c).free
 +$DiskSize = $FreeSpace + (get-psdrive -Name c).used
 +
 +
 +# $FreeSpace = (Get-CimInstance -ClassName Win32_LogicalDisk).freespace
 +# $DiskSize = (Get-CimInstance -ClassName Win32_LogicalDisk).size
 +
 +if((100 / $DiskSize * $FreeSpace) -gt 5 )
 +{
 +    for($i=1; $i -le 20; $i++)
 +    {
 +        if (($i + 2) % 3 -ne 0)
 +        {
 +            continue
 +        }
 +    New-Item -ItemType File -Path C:\TestVZ -name "MeineNeueDatei$i.txt" 
 +    }
 +}
 +
 +else
 +{
 +  Write-Host "Platz auf dem Datenträger nicht ausreichend"
 +}
 +</code>