Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
coding:powershell [2025/02/27 13:03] jango [Links] |
coding:powershell [2025/04/14 12:55] (aktuell) jango [Postfach] |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | Powershell5 -> Net-Framework | ||
+ | Powershell7 -> .NET | ||
+ | |||
<code powershell> | <code powershell> | ||
$command = ' | $command = ' | ||
Zeile 149: | Zeile 152: | ||
// | // | ||
Import-Module ActiveDirectory | Import-Module ActiveDirectory | ||
+ | |||
+ | // Domäne abrufen | ||
+ | Get-ADDomain | ||
// | // | ||
Zeile 182: | Zeile 188: | ||
</ | </ | ||
- | __false__ | + | ====Gruppen==== |
+ | <code powershell> | ||
+ | # Benutzergruppe erstellen: | ||
+ | New-ADGroup -Name "RODC Admins" | ||
+ | |||
+ | # Benutzerkonto löschen: | ||
+ | Remove-ADGroup -Identity RODCAdmins | ||
+ | </ | ||
==== Organisationseinheiten (OU) ==== | ==== Organisationseinheiten (OU) ==== | ||
Zeile 358: | Zeile 371: | ||
Verwaltung einer [[: | Verwaltung einer [[: | ||
- | <code powershell> | + | ====Inbox Rules==== |
- | Start-ExchangeManagementConsole | + | |
+ | < | ||
+ | Get-InboxRule -Mailbox " | ||
+ | |||
+ | Name Enabled Priority RuleIdentity | ||
+ | ---- ------- -------- ------------ | ||
+ | Mails an Walter Friedrich und I True 1 17352165469276078081 | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | Remove-InboxRule -Mailbox " | ||
+ | </ | ||
+ | ====Postfach==== | ||
+ | <code powershell> | ||
// Postfach erstellen | // Postfach erstellen | ||
New-Mailbox -UserPrincipalName user@domain.com -Alias user -Name " | New-Mailbox -UserPrincipalName user@domain.com -Alias user -Name " | ||
- | // | + | // Berechtigungen für ein Postfach |
- | Add-MailboxPermission -Identity user -User manager | + | Get-MailboxPermission -Identity user |
+ | Get-MailboxPermission -Identity user -User manager | ||
- | //Verteilergruppe erstellen: | + | //Berechtigungen für ein Postfach festlegen: nur ein accessright auf einmal |
- | New-DistributionGroup | + | Add-MailboxPermission |
- | //Sicherheitsgruppe erstellen: | + | // Berechtigungen für einen Postfach Kalender anzeigen: (auf engl. Server Calendar) |
- | New-DistributionGroup | + | Get-MailboxFolderPermission |
+ | Get-MailboxFolderPermission -Identity user: | ||
+ | |||
+ | // | ||
+ | Add-MailboxFolderPermission -Identity user: | ||
// | // | ||
Zeile 378: | Zeile 408: | ||
// | // | ||
New-MailboxImportRequest -Mailbox user -FilePath " | New-MailboxImportRequest -Mailbox user -FilePath " | ||
- | |||
// | // | ||
Set-Mailbox -Identity user -EmailAddresses @{add=" | Set-Mailbox -Identity user -EmailAddresses @{add=" | ||
Zeile 385: | Zeile 414: | ||
Set-Mailbox -Identity user -EmailAddresses @{remove=" | Set-Mailbox -Identity user -EmailAddresses @{remove=" | ||
+ | // AutoReply | ||
+ | Set-MailboxAutoReplyConfiguration -Identity User1 -AutoReplyState Enabled -InternalMessage < | ||
+ | |||
+ | Set-MailboxAutoReplyConfiguration -Identity User1 -AutoReplyState Scheduled -StartTime " | ||
+ | |||
+ | // Mailbox in PST exportieren | ||
+ | New-MailboxExportRequest -Mailbox < | ||
+ | |||
+ | // Datenbank Speicherort | ||
+ | Get-Mailbox -Identity User1 | Get-MailboxStatistics | Select DisplayName, | ||
+ | Get-Mailbox | Get-MailboxStatistics | Select DisplayName, | ||
+ | |||
+ | |||
+ | // Mailbox verschieben | ||
+ | New-MoveRequest -Identity < | ||
+ | Get-MoveRequest | Get-MoveRequestStatistics | Select DisplayName, | ||
+ | Remove-MoveRequest -Identity < | ||
+ | Get-RemoveRequest | Remove-MoveRequest | ||
+ | |||
+ | |||
+ | // Message Tracking | ||
+ | Get-MessageTrackingLog -sender User1 | ||
+ | Get-MessageTrackingLog -Recipients User1 | ||
+ | Get-MessageTrackingLog -sender User1 -Recipients User2 | ||
+ | Get-MessageTrackingLog -sender User1 -Start < | ||
+ | </ | ||
+ | |||
+ | ====Verteiler==== | ||
+ | <code powershell> | ||
+ | // | ||
+ | New-DistributionGroup -Name " | ||
+ | |||
+ | // | ||
+ | New-DistributionGroup -Name " | ||
+ | </ | ||
+ | |||
+ | ====Datenbank==== | ||
+ | |||
+ | <code powershell> | ||
// | // | ||
Get-MailboxDatabase | Get-MailboxDatabase | ||
Zeile 1621: | Zeile 1689: | ||
} | } | ||
+ | </ | ||
+ | |||
+ | =====Powershell Wissen===== | ||
+ | |||
+ | <code powershell> | ||
+ | #region VS Code | ||
+ | |||
+ | <# | ||
+ | |||
+ | Install-Module -Name PSScriptAnalyzer -Force -Confirm: | ||
+ | |||
+ | Erweiterungen | ||
+ | - PowerShell | ||
+ | - XML Tools | ||
+ | - Material Icon Theme | ||
+ | - Code Spell Checker | ||
+ | - German - Code Spell Checker | ||
+ | - OPTIONAL German Language Pack for Visual Studio Code | ||
+ | - OPTIONAL Markdown All in One | ||
+ | |||
+ | * Type ? into the input field to get a list of available commands you can execute from here | ||
+ | |||
+ | * F1 > settings.json | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | #> | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Hotkeys (VS Code) | ||
+ | |||
+ | # CTRL + 1 Wechsel vom Terminal zum Editor | ||
+ | # CTRL + + Zoom in | ||
+ | # CTRL + - Zoom out | ||
+ | # F1 Kommandozeile | ||
+ | # CTRL + Space Autovervollständigung öffnen | ||
+ | # F8 Akt. Zeile oder Selektion ausführen | ||
+ | # CTRL + S Akt. Datei speichern | ||
+ | # CTRL + K + 0 region einklappen | ||
+ | # CTRL + P Quickly open files. | ||
+ | # CTRL + F1 Online-Hilfe zum akt. CmdLet | ||
+ | # SHIFT + ALT + UP Copy line up | ||
+ | # SHIFT + ALT + DOWN Copy line down | ||
+ | # CTRL + T Go to Symbol in Workspace | ||
+ | # CTRL + ALT + J Snipping einfügen | ||
+ | # F5 PS1-Datei ausführen | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region TOP 10 CmdLets | ||
+ | |||
+ | Get-Member | ||
+ | Get-Help | ||
+ | Get-Command | ||
+ | Compare-Object | ||
+ | ForEach-Object | ||
+ | Group-Object | ||
+ | Measure-Object | ||
+ | New-Object | ||
+ | Select-Object | ||
+ | Skip-Object | ||
+ | Sort-Object | ||
+ | Where-Object | ||
+ | Show-Command | ||
+ | Out-GridView | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region GRUNDLAGEN | ||
+ | #region > > > AGENDA < < < | ||
+ | |||
+ | # PowerShell - Grundlagen | ||
+ | |||
+ | Start-Process " | ||
+ | |||
+ | # SCHULUNGSKERNZEIT: | ||
+ | # PAUSEN: 10:30, 12: | ||
+ | # | ||
+ | |||
+ | ## Grundlagen | ||
+ | # Was ist PowerShell? [x] | ||
+ | # Befehlskonzepte und Terminologie [x] | ||
+ | # Parsing und cmdlets [x] | ||
+ | # Pipelines und Befehle [x] | ||
+ | # Formatierung und Ausgabe [x] | ||
+ | # PowerShell Provider und Drives [x] | ||
+ | # PowerShell Remote einsetzen [x] | ||
+ | | ||
+ | ## Arbeiten mit Variablen | ||
+ | # Was sind Variablen? [x] | ||
+ | # Variablenmanagement [x] | ||
+ | # Basistypen [x] | ||
+ | # Schreibschutz und Konstanten [x] | ||
+ | | ||
+ | ## Operatoren und Ausdrücke | ||
+ | # Arithmetische Operatoren [x] | ||
+ | # Die Zuweisungsoperatoren [x] | ||
+ | # Vergleichsoperatoren [x] | ||
+ | # Operatoren zum Musterabgleich [x] | ||
+ | # Logische Operatoren [x] | ||
+ | | ||
+ | ## Erweiterte Operatoren und Variablen | ||
+ | # Array-Operatoren [x] | ||
+ | # Hashtables - Assoziative Arrays [x] | ||
+ | # Der PowerShell Format-Operator -F [x] | ||
+ | | ||
+ | ## Windows Objekte: COM und WMI | ||
+ | # COM in PowerShell verwenden [x] | ||
+ | # WMI und PowerShell [x] | ||
+ | | ||
+ | ## Verarbeitung von Texten, Dateien und XML | ||
+ | # Verarbeiten von unstrukturiertem Text [x] | ||
+ | # Dateiverarbeitung [x] | ||
+ | # XML-Verarbeitung [x] | ||
+ | |||
+ | #endregion | ||
+ | #region Was ist PowerShell? | ||
+ | |||
+ | # Die Windows PowerShell ist ein KOMMANDOZEILENINTERPRETER von Microsoft | ||
+ | C: | ||
+ | |||
+ | # Die auf dem Microsoft .NET-Framework basierende PowerShell verbindet die aus Unix-Shells bekannte | ||
+ | # Philosophie von Pipes und Filtern mit dem Paradigma der objektorientierten Programmierung. | ||
+ | Get-Service | where Status -EQ Running | Get-Member | ||
+ | |||
+ | # Objektorientiert und mit .NET erweiterbar | ||
+ | $file = Get-ChildItem C: | ||
+ | $file.LastAccessTime | ||
+ | $file.Length | ||
+ | $file.CopyTo(" | ||
+ | $file | Add-Member -MemberType ScriptProperty -Name LengthKb -Value {$this.Length / 1KB} | ||
+ | $file.LengthKb | ||
+ | |||
+ | # Unterstützt 32/64bit | ||
+ | C: | ||
+ | C: | ||
+ | |||
+ | # Enthält eine grafische Entwicklungsumgebung PowerShell ISE (Integrated Scripting Environment) | ||
+ | C: | ||
+ | C: | ||
+ | |||
+ | # Ab Windows 7 ist die PowerShell bereits vorinstalliert | ||
+ | |||
+ | #region PowerShell 1.0 | ||
+ | |||
+ | # Markteinführung | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region PowerShell 2.0 | ||
+ | |||
+ | # Remoting via RPC | ||
+ | Get-Help -Name * -Parameter ComputerName # Nur diese CmdLets können remote zugreifen | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region PowerShell 3.0 | ||
+ | |||
+ | # Default in: Windows7 | ||
+ | # Windows Server 2008 R2 | ||
+ | |||
+ | # Min. OS: >XP, >VISTA | ||
+ | |||
+ | # Remoting via WinRM | ||
+ | # Workflows | ||
+ | # Scheduled[Jobs] | ||
+ | # Windows PowerShell Web Access | ||
+ | # Netzlaufwerke verbinden (New-PSDrive) | ||
+ | # Aktualisierbare Hilfe | ||
+ | # Web Cmdlet' | ||
+ | # ZZGL. Vereinfachte Syntax | ||
+ | Get-Process | where {$_.Handles -gt 500} | ||
+ | Get-Process | ? | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region PowerShell 4.0 | ||
+ | |||
+ | # DEFAULT: Windows 8, Windows Server 2012 | ||
+ | |||
+ | # Desired State of Configuration (DSC) | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region PowerShell 5.0 | ||
+ | |||
+ | # Default OS: Windows 10, Windows Server 2016 | ||
+ | |||
+ | # Softwarepakete installieren | ||
+ | # Switch-Verwaltung | ||
+ | # OOP | ||
+ | #region Beispiele zu den Neuerungen der PowerShell Version 5.0 | ||
+ | |||
+ | # Alle Details zur 5.0 Version unter: | ||
+ | Get-Help about_Windows_PowerShell_5.0 -ShowWindow | ||
+ | Start-Process http:// | ||
+ | |||
+ | #region Get-ItemPropertyValue | ||
+ | |||
+ | #NEU: Get-ItemPropertyValue | ||
+ | #FRÜHER: | ||
+ | (Get-ItemProperty -Path HKLM: | ||
+ | #JETZT: | ||
+ | Get-ItemPropertyValue -Path HKLM: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Einfache String-Operationen | ||
+ | "Hallo Welt" | ConvertFrom-String | ||
+ | "Hallo Welt" | ConvertFrom-String -Delimiter " | ||
+ | "Hallo Welt" | ConvertFrom-String -PropertyNames FirstWord, SecondWord | ||
+ | |||
+ | "Lee Holmes", | ||
+ | |||
+ | "Hallo Welt" | Format-Hex | ||
+ | #endregion | ||
+ | |||
+ | #region ZIP-Archive | ||
+ | |||
+ | # | ||
+ | #Test-Daten erzeugen | ||
+ | # | ||
+ | New-Item -Path C: | ||
+ | 1..1MB -join ";" | ||
+ | 1..1MB -join ";" | ||
+ | |||
+ | # | ||
+ | # Compress-Archive | ||
+ | # | ||
+ | " | ||
+ | Get-Help Compress-Archive -ShowWindow | ||
+ | |||
+ | # | ||
+ | # Expand-Archive | ||
+ | # | ||
+ | " | ||
+ | Get-Help Expand-Archive -Full | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Software-Installation | ||
+ | |||
+ | Set-ExecutionPolicy -ExecutionPolicy AllSigned | ||
+ | |||
+ | Get-Command -Module PowerShellGet, | ||
+ | |||
+ | Find-Package | Out-GridView | ||
+ | Install-Package -Name AKPT -Force | ||
+ | Get-Module -ListAvailable | ||
+ | Get-Command * -Module AKPT | ||
+ | Get-AKAbout | ||
+ | Uninstall-Package -Name AKPT | ||
+ | |||
+ | Register-PSRepository -Name " | ||
+ | Get-PSRepository | ||
+ | Unregister-PSRepository -Name " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Kryptographie | ||
+ | |||
+ | Get-Command -Module Microsoft.PowerShell.Security | ||
+ | |||
+ | $MyCertInf = @" | ||
+ | [Version] | ||
+ | Signature = " | ||
+ | |||
+ | [Strings] | ||
+ | szOID_ENHANCED_KEY_USAGE = " | ||
+ | szOID_DOCUMENT_ENCRYPTION = " | ||
+ | |||
+ | [NewRequest] | ||
+ | Subject = " | ||
+ | MachineKeySet = false | ||
+ | KeyLength = 2048 | ||
+ | KeySpec = AT_KEYEXCHANGE | ||
+ | HashAlgorithm = Sha1 | ||
+ | Exportable = true | ||
+ | RequestType = Cert | ||
+ | |||
+ | KeyUsage = " | ||
+ | ValidityPeriod = " | ||
+ | ValidityPeriodUnits = " | ||
+ | |||
+ | [Extensions] | ||
+ | 2.5.29.37=" | ||
+ | "@ | ||
+ | Set-Content -Path C: | ||
+ | CertReq -new C: | ||
+ | $cert = gci Cert: | ||
+ | |||
+ | $crypt = "Hallo Welt" | Protect-CmsMessage -To $cert | ||
+ | Unprotect-CmsMessage -Content $crypt -To $cert | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region OOP | ||
+ | |||
+ | Get-Help about_Classes -ShowWindow | ||
+ | |||
+ | enum Farbe | ||
+ | { | ||
+ | Blau | ||
+ | Grün | ||
+ | Rot | ||
+ | } | ||
+ | $meineFarbe = [Farbe]:: | ||
+ | $meineFarbe | ||
+ | |||
+ | class Auto | ||
+ | { | ||
+ | [Farbe]$Farbe | ||
+ | $PS | ||
+ | } | ||
+ | |||
+ | $meinAuto = New-Object -TypeName Auto | ||
+ | |||
+ | $meinAuto.Farbe = [Farbe]:: | ||
+ | $meinAuto.PS = 100 | ||
+ | $meinAuto | Get-Member | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Weitere neue CmdLetds | ||
+ | |||
+ | Set-Clipboard -Value "Hallo Köln!" | ||
+ | Get-Clipboard | ||
+ | |||
+ | Clear-RecycleBin -DriveLetter c: -Confirm: | ||
+ | |||
+ | New-TemporaryFile | ||
+ | |||
+ | New-Guid | ||
+ | |||
+ | # symbolischer Verknüpfungen | ||
+ | New-Item -ItemType SymbolicLink -Name MySymLinkDir -Target $pshome | ||
+ | |||
+ | # -Depth 2 | ||
+ | Get-ChildItem c:\ -Recurse -Depth 2 -Force | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region DataCenter Abstraction Layer (DAL) | ||
+ | |||
+ | <# | ||
+ | Mit dieser Technologie können Sie direkt auf bestimmte | ||
+ | Netzwerkkomponenten wie Switches und Router zugreifen. | ||
+ | |||
+ | Dazu muss die Hardware diese Technik aber auch unterstützen. | ||
+ | In diesem Bereich spielen vor allem | ||
+ | Cisco und Huawei eine wichtige Rolle. | ||
+ | #> | ||
+ | |||
+ | $Session = New-CimSession -ComputerName " | ||
+ | Get-NetworkSwitchFeature -CimSession $Session | ||
+ | |||
+ | <# | ||
+ | Name IsEnabled InstanceID PSComputerName | ||
+ | ---- --------- ---------- -------------- | ||
+ | SSH True Contoso: | ||
+ | Tacacs True Contoso: | ||
+ | BGP False Contoso: | ||
+ | VLAN True Contoso: | ||
+ | LACP True Contoso: | ||
+ | DHCP False Contoso: | ||
+ | LLDP True Contoso: | ||
+ | #> | ||
+ | |||
+ | Get-Help Get-NetworkSwitchFeature -Full | ||
+ | |||
+ | Get-Command -Module NetworkSwitchManager | Out-GridView | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Open Data Protocol | ||
+ | |||
+ | <# Das Open Data Protocol, kurz OData ist ein von Microsoft veröffentlichtes HTTP-basiertes Protokoll | ||
+ | für den Datenzugriff zwischen kompatiblen Softwaresystemen. Aufbauend auf älteren Protokollen wie | ||
+ | ODBC und JDBC kann OData u.a. innerhalb von Cloud-Diensten (Azure), MySQL, Java und Rails | ||
+ | | ||
+ | für den Datenaustausch zur Verfügung zu stellen. | ||
+ | #> | ||
+ | |||
+ | Export-ODataEndpointProxy -Uri ' | ||
+ | -MetadataUri ' | ||
+ | -AllowUnsecureConnection ` | ||
+ | -OutputModule C: | ||
+ | -ResourceNameMapping @{Products = ' | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Optimierte Unterstützung für' | ||
+ | |||
+ | <# | ||
+ | Weitere Neuerungen in der PowerShell betreffen die mit der | ||
+ | PowerShell 4.0 eingeführte Technologie Desired State Configuration (DSC). | ||
+ | |||
+ | Hauptsächlich gibt es neue Optionen um festzulegen auf wievielen Computern | ||
+ | gleichzeitig die Änderungen implementiert werden sollen. | ||
+ | | ||
+ | Mit dem Modul ' | ||
+ | ' | ||
+ | #> | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | # Welche Version ist installiert? | ||
+ | Get-Host | ||
+ | |||
+ | #endregion | ||
+ | #region Befehlskonzepte und Terminologie | ||
+ | |||
+ | #region CmdLets (Verb-Substantiv) | ||
+ | # CmdLets-Quellen können sein *.dll (CmdLet) oder Funktionen (function) | ||
+ | Test-NetConnection 192.168.50.10 | ||
+ | Get-Process | ||
+ | Get-Verb | ||
+ | Get-Command -Noun Process # Was kann ich mit Process machen? | ||
+ | Get-Command -Verb Get # Welche Informationen können noch ermittelt werden? | ||
+ | # CmdLets sind keine EXE-Dateien, | ||
+ | # Mögliche CmdLets werden durch PowerShell-Module hinzugefügt, | ||
+ | Get-Module -ListAvailable | ||
+ | Get-Command -Module ActiveDirectory | ||
+ | Get-ADUser | ||
+ | #endregion | ||
+ | #region Alias | ||
+ | |||
+ | ls *.txt # (Alias für Get-ChildItem) | ||
+ | dir *.txt # (Alias für Get-ChildItem) | ||
+ | gci *.txt # (Alias für Get-ChildItem) | ||
+ | |||
+ | Get-Command -Name dir | ||
+ | Get-Alias -Name ls # ls ist ein Alias für? | ||
+ | Get-Alias -Definition Get-ChildItem # Gibt es ein Alias für Get-ChildItem? | ||
+ | |||
+ | # Console => Alias nutzen ! | ||
+ | # PS-Skripte => Alias NICHT nutzen ! | ||
+ | |||
+ | #endregion | ||
+ | #region Pipelining | ||
+ | |||
+ | Get-Service | Out-GridView | ||
+ | ls | Out-GridView | ||
+ | Get-Process *notepad* | Out-GridView -OutputMode Single | Stop-Process | ||
+ | |||
+ | #endregion | ||
+ | #region Filtering | ||
+ | |||
+ | ls -Path *.txt # Nicht alle Parameter unterstützen Wildcard! | ||
+ | ls | Where-Object Name -Like " | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell-Providers/ | ||
+ | |||
+ | ls c: # C: => PowerShell-Drive (C: d:, etc. => PowerShell-Provider FileSystem) | ||
+ | ls hkcu: # hkcu: => PowerShell-Drive (hkcu:, hklm:, etc. => PowerShell-Provider Registry) | ||
+ | ls env: | ||
+ | # Weitere PS-Provider: | ||
+ | Get-PSProvider | ||
+ | Get-PSDrive | ||
+ | |||
+ | #endregion | ||
+ | #region Remoting | ||
+ | |||
+ | Get-Process -ComputerName 192.168.50.41 | ||
+ | |||
+ | # .NET Framework | ||
+ | $sw = New-Object -TypeName System.Diagnostics.Stopwatch | ||
+ | $sw.Start() | ||
+ | $sw.Stop() | ||
+ | $sw | ||
+ | |||
+ | #endregion | ||
+ | #region Zugriff auf WMI | ||
+ | |||
+ | Get-WmiObject -Class Win32_Product | ||
+ | Get-WmiObject -Class Win32_Processor | ||
+ | Get-WmiObject -List | Measure-Object | ||
+ | |||
+ | #endregion | ||
+ | #region Erweiterbar durch Module | ||
+ | |||
+ | Get-Module -ListAvailable | ||
+ | Get-Command -Module ActiveDirectory # Informationen zu einem AD-Computer über: Get-ADComputer ... | ||
+ | Find-Module * # Ab PowerShell 5.0 | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell Parsing | ||
+ | |||
+ | # Ein PowerShell Kommando wird bei parsen in token aufgeteillt und analysiert: | ||
+ | Write-Host Buch # Token Write-Host und Token Buch | ||
+ | |||
+ | # Token werden wie folgt analysiert: | ||
+ | # Example Mode Result | ||
+ | # ------------------ ---------- ---------------- | ||
+ | 2+2 # Expression 4 (integer) | ||
+ | Write-Output 2+2 # Argument " | ||
+ | Write-Output (2+2) # Expression 4 (integer) | ||
+ | $a = 2+2 # Expression $a = 4 (integer) | ||
+ | Write-Output $a # Expression 4 (integer) | ||
+ | Write-Output $a/H # Argument " | ||
+ | Write-Output !1 # Argument " | ||
+ | Write-Output (!1) # expression False (Boolean) | ||
+ | Write-Output (2) # expression 2 (integer) | ||
+ | |||
+ | # STOP PARSING Möglichkeiten: | ||
+ | icacls X:\VMS /grant Dom\HVAdmin: | ||
+ | icacls X:\VMS /grant Dom\HVAdmin: | ||
+ | # Lösung 2: Stop das parsing nach --% => | ||
+ | icacls X:\VMS --% /grant Dom\HVAdmin: | ||
+ | |||
+ | # | ||
+ | # Weitere Schreibweisen: | ||
+ | # | ||
+ | |||
+ | $true # Boolean | ||
+ | $false | ||
+ | 10 # Integer | ||
+ | 10.5 # Double | ||
+ | 'Hallo Köln $PSCulture' | ||
+ | " | ||
+ | " | ||
+ | (ping.exe 127.0.0.1)[8] | ||
+ | (tnc 192.168.50.10).PingSucceeded | ||
+ | (Get-Process -Name notepad).Kill() | ||
+ | Get-Process; | ||
+ | [datetime]" | ||
+ | [DateTime]:: | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell Console | ||
+ | |||
+ | # -> Mehrzeilig schreiben = Ausdrücke in Klammern " | ||
+ | | ||
+ | # Tastaturbefehle (<= 4.0) | ||
+ | # TAB ...................... Befehlszeilenergänzung | ||
+ | # STRG + C ................. Abbruch | ||
+ | # PFEIL-OBEN/ | ||
+ | # MARKIERUNG + ENTER ....... Kopiert die Markierung in die Zwischenablage | ||
+ | # RECHTS-KLICK ............. Fügt dir Zwischenablage ein | ||
+ | |||
+ | # Tastaturbefehle (>= 5.0) | ||
+ | # STRG + C ................. Kopieren | ||
+ | # STRG + V ................. Einfügen | ||
+ | |||
+ | Get-History | ||
+ | $MaximumHistoryCount = 50 # Default: 4096 | ||
+ | |||
+ | #region Konsolen-Ein-/ | ||
+ | |||
+ | Start-Transcript -Path C: | ||
+ | Get-Process | Stop-Process -Force -WhatIf | ||
+ | Remove-Item c:\ -Recurse -Force -WhatIf | ||
+ | Stop-Transcript | ||
+ | Get-Content -Path C: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region max. Anzeige von Enumerationen (-1 ohne Grenze, Default: 4) | ||
+ | Get-Command -Name ForEach-Object | select -First 1 | fl * # Siehe Eigenschaft: | ||
+ | $FormatEnumerationLimit = 4 | ||
+ | Get-Command -Name ForEach-Object | select -First 1 | fl * # Siehe Eigenschaft: | ||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Integrated Scripting Environment (ISE) | ||
+ | |||
+ | # * = Noch nicht gespeichert | ||
+ | # STRG + S = Speichern | ||
+ | # F8 = Führt die aktuelle Auswahl aus bzw. die Course-Zeile | ||
+ | # F5 = Führt das ganze Skript aus | ||
+ | # TAB = Auswahl aus IntelliScense bestätigen | ||
+ | # STRG + LEER = öffnet IntelliScense | ||
+ | # STRG + M = Auf-/ | ||
+ | # STRG + J = Snippets ausfüllen | ||
+ | |||
+ | # Siehe auch: | ||
+ | # ISE-Menü " | ||
+ | Get-Help about_PowerShell_Ise.exe | ||
+ | Get-Help about_Windows_PowerShell_ISE | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell-Hilfe (Get-Help) | ||
+ | |||
+ | #region Hilfe installieren und aktuallisieren | ||
+ | |||
+ | Update-Help -Module * -UICulture en-US, de-DE -Force | ||
+ | |||
+ | # Für Computer ohne Internet-Zugang | ||
+ | |||
+ | Save-Help -DestinationPath C: | ||
+ | Update-Help -Module * -SourcePath C: | ||
+ | |||
+ | #endregion | ||
+ | #region Hilfe zu CmdLet' | ||
+ | |||
+ | Get-Process -? | ||
+ | Get-Help Get-Process | ||
+ | Get-Help Get-Process -Full | ||
+ | Get-Help Get-Process -ShowWindow # oder F1 in der ISE | ||
+ | Get-Help Get-Process -Online | ||
+ | |||
+ | # SYNTAX-Block: | ||
+ | # -Name < | ||
+ | # < | ||
+ | # [] => Optional | ||
+ | # [-FileVersionInfo] => Switch-Parameter | ||
+ | # | ||
+ | # Parameter-Beschreibung (z.B. Id): | ||
+ | # Erforderlich? | ||
+ | # Position? named oder: 1, 2, 3, 4, 5, etc. | ||
+ | # Standardwert none oder: ...... | ||
+ | # Pipelineeingaben akzeptieren? | ||
+ | # Platzhalterzeichen akzeptieren? | ||
+ | |||
+ | #endregion | ||
+ | #region Hilfe zur/um die PowerShell (about-Seiten) | ||
+ | |||
+ | Get-Help about_* | ||
+ | Get-Help about_wildcards -ShowWindow | ||
+ | Get-Help about_if -ShowWindow | ||
+ | Get-Help about_CommonParameters -ShowWindow # Enthält infos von Parameter die für alle CmdLet' | ||
+ | |||
+ | Get-Process | Stop-Process -WhatIf | ||
+ | Get-Process -FileVersionInfo -ErrorAction SilentlyContinue | ||
+ | Get-Process -FileVersionInfo -ErrorAction Stop | ||
+ | Get-Process | Stop-Process -Confirm | ||
+ | |||
+ | #endregion | ||
+ | #region Hilfe erstellen | ||
+ | |||
+ | |||
+ | # HILFE-ARTEN | ||
+ | # Cmdlet => The Help topics that describe cmdlets in a module are XML files that use the command help schema | ||
+ | # Provider => The Help topics that describe providers in a module are XML files that use the provider help schema. | ||
+ | # Function => The Help topics that describe functions in a module can be XML files that use the command help schema or comment-based Help topics within the function, or the script or script module | ||
+ | # Script => The Help topics that describe scripts in a module can be XML files that use the command help schema or comment-based Help topics in the script or script module. | ||
+ | # Conceptual (" | ||
+ | |||
+ | # < | ||
+ | # \Mymodule | ||
+ | # \en-US | ||
+ | # \about_SampleModule.help.txt | ||
+ | # \SampleModule.dll-help.xml | ||
+ | # \fr-FR | ||
+ | # \about_SampleModule.help.txt | ||
+ | # \SampleModule.dll-help.xml | ||
+ | |||
+ | # Supporting Updatable Help | ||
+ | Start-Process " | ||
+ | |||
+ | # Supporting Online Help | ||
+ | Start-Process " | ||
+ | |||
+ | # PowerShell Cmdlet Help Editor | ||
+ | Start-Process " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | # WICHTIG Get-Help intensiv nutzen | ||
+ | # WICHTIG about-Seiten (wiedeholt) lesen | ||
+ | |||
+ | #endregion | ||
+ | #region Mögliche PowerShell-Kommandos (Get-Command, | ||
+ | |||
+ | # => Get-Command ruf eine Übersicht der möglichen PS-Kommandos ab. | ||
+ | # => Dieser Funktionsumfang hängt von den installierten Modulen ab. | ||
+ | # => Default-Anzeige von: CmdLets, Alias, Funktionen, PSDrives, Anwendungen (*.exe) | ||
+ | # => Vor PS3.0 werden nur CmdLets angezeigt von geladen Modulen | ||
+ | |||
+ | Get-Command * -CommandType All | ||
+ | Get-Command * -CommandType Cmdlet | ||
+ | Get-Command -Name *computer* -CommandType All | ||
+ | |||
+ | # | ||
+ | # Verb-Substantiv | ||
+ | # | ||
+ | |||
+ | Get-Command -Noun Computer | ||
+ | Get-Verb | ||
+ | Get-Command -Verb Stop | ||
+ | Get-Command -Verb Optimize | ||
+ | |||
+ | # ÜBUNG: Wie lautet das CmdLet um eine Netzwerk-Karte einzuschalten/ | ||
+ | # Und wie haben Sie das CmdLet gefunden? | ||
+ | |||
+ | # | ||
+ | # Kommandos nach Modulen finden | ||
+ | # | ||
+ | |||
+ | Get-Module -ListAvailable | ||
+ | Get-Command -Module NetTCPIP | ||
+ | Get-Help Test-NetConnection -ShowWindow | ||
+ | Test-NetConnection 192.168.50.10 | ||
+ | |||
+ | # ÜBUNG: Wie heißt das CmdLet um eine IP-Adresse zu ändern? | ||
+ | # Und wie haben Sie das CmdLet gefunden? | ||
+ | |||
+ | #endregion | ||
+ | #region Aliase für CmdLet' | ||
+ | |||
+ | Get-Alias | ||
+ | Get-Alias ls | ||
+ | Get-Alias -Definition Get-ChildItem | ||
+ | Get-Command -CommandType Alias | ||
+ | Get-Alias -Definition Test-NetConnection | ||
+ | Get-Alias tc | ||
+ | Get-Command -Noun alias | ||
+ | Get-Help New-Alias -ShowWindow | ||
+ | New-Alias ping Test-NetConnection | ||
+ | ping | ||
+ | |||
+ | # Nutzen | ||
+ | Get-Process | Where-Object Company -like " | ||
+ | gp | ? Company -like " | ||
+ | |||
+ | #endregion | ||
+ | #region Pipeline (|) | ||
+ | |||
+ | # => Windows PowerShell überträgt über die Pipeline KEINE TEXTE zwischen den Befehlen, | ||
+ | # es werden immer OBJEKT über die Pipeline übertragen. | ||
+ | # => 1. CmdLet liefert das erste Objekt just-in-time an das 2. CmdLet | ||
+ | # => Pipeline-Objekte werden an den Parameter des 2. CmdLet' | ||
+ | # dass Pipeline-Eingabe (byValue) zulässt (Siehe Get-Help) | ||
+ | |||
+ | # Zum vertiefen & verstehen: | ||
+ | Trace-Command -PSHost -Name ParameterBinding -Expression {Get-Process winlogon | Format-Wide} | ||
+ | |||
+ | # | ||
+ | # Voarb analysieren (Wo bin ich & wo will ich hin?) | ||
+ | # | ||
+ | |||
+ | Get-Process | ||
+ | Get-Process | Get-Member | ||
+ | Get-Process | Format-Table -Property * | ||
+ | Get-Process | Format-Table -pro Name, Company | ||
+ | Get-Process | Format-List * | ||
+ | |||
+ | Get-Process | Where-Object Company -like " | ||
+ | Get-Process | Where-Object Company -like " | ||
+ | |||
+ | Get-Process | # Nach der P. sind Umbrüche erlaubt | ||
+ | Where-Object Company -like " | ||
+ | Sort-Object Name | # Nach der P. sind Umbrüche erlaubt | ||
+ | Select-Object Name, | ||
+ | Out-File c: | ||
+ | |||
+ | |||
+ | Get-Process | Where-Object Company -like ` | ||
+ | " | ||
+ | |||
+ | (Get-Process | Where-Object Company -like " | ||
+ | |||
+ | # | ||
+ | # Weitere Beispiele: | ||
+ | # | ||
+ | |||
+ | Get-ChildItem C:\ -Recurse | more # Besser nicht benutzten, lieber so: | ||
+ | Get-ChildItem C:\ -Recurse | Out-Host -Paging | ||
+ | |||
+ | " | ||
+ | |||
+ | |||
+ | ((ping.exe 127.0.0.1) | Select-String -Pattern ' | ||
+ | |||
+ | |||
+ | # ÜBUNG (Pipeline1): | ||
+ | |||
+ | # ÜBUNG (Pipeline2): | ||
+ | # ls, Get-Member, Format-List *, Sort-Object, | ||
+ | |||
+ | #endregion | ||
+ | #region Rückgabe-Objekte managen (*-Object) | ||
+ | |||
+ | # | ||
+ | # Übersicht | ||
+ | # | ||
+ | |||
+ | Get-Command -Noun Object -Module Microsoft.PowerShell.* | Out-GridView | ||
+ | |||
+ | Where-Object | ||
+ | Select-Object | ||
+ | Sort-Object | ||
+ | Group-Object | ||
+ | Measure-Object # Messen | ||
+ | Compare-Object # Vergleichen | ||
+ | ForEach-Object # Schleife | ||
+ | New-Object | ||
+ | Tee-Object | ||
+ | |||
+ | #region Where-Object (Siehe auch region Operatoren (Vergleichso.)) | ||
+ | |||
+ | # Einfache Schreibweise erst seit PS3.0 | ||
+ | Get-Process | Where-Object -Property Company -Like -Value " | ||
+ | Get-Process | where -Property Company -Like -Value " | ||
+ | Get-Process | ? -Property Company -Like -Value " | ||
+ | Get-Process | ? Company -Like " | ||
+ | |||
+ | # UND | ||
+ | Get-Process | ? Company -Like " | ||
+ | |||
+ | # ODER: Ausführliche Schreibweise seit PS1.0 | ||
+ | Get-Process | ? -FilterScript {$_.Company -like " | ||
+ | Get-Process | ? | ||
+ | |||
+ | # Die Variable $_ ist die Laufzeit-Variabe in der Pipeline und stellt das übergebene Objekt dar! | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region ForEach-Object | ||
+ | |||
+ | 31, | ||
+ | 31, | ||
+ | 31, | ||
+ | 31, | ||
+ | |||
+ | 31, | ||
+ | 31, | ||
+ | " | ||
+ | 31, | ||
+ | "TNC ausführen für" | ||
+ | " | ||
+ | } | ||
+ | |||
+ | |||
+ | Get-ChildItem C: | ||
+ | ? Extension -EQ " | ||
+ | Get-Content -ea SilentlyContinue | | ||
+ | Select-String -Pattern " | ||
+ | |||
+ | # Problem: Es fehlt die Information des Dateinamens :-( | ||
+ | # LÖSUNG: ForEach-Object | ||
+ | |||
+ | Get-ChildItem C: | ||
+ | | ||
+ | | ||
+ | "#####################################" | ||
+ | $_ | Get-Content | Select-String -Pattern " | ||
+ | } | ||
+ | |||
+ | # Beispiele: | ||
+ | |||
+ | Get-EventLog -LogName System -Newest 1000 | | ||
+ | ForEach-Object -Begin {Get-Date} ` | ||
+ | | ||
+ | -End {Get-Date} | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region New-Object | ||
+ | |||
+ | $o1 = New-Object -TypeName System.Windows.Forms.Form # Erstellt ein Objekt aus der .NET-Framework-Klasse ' | ||
+ | $o1.ShowDialog() # .NET Wissen | ||
+ | |||
+ | $o2 = New-Object -ComObject " | ||
+ | $o2.Visible = $true # VBA for Application | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Tee-Object | ||
+ | |||
+ | Get-Process | Stop-Process -WhatIf | ||
+ | Get-Process | Tee-Object -FilePath c: | ||
+ | Get-Process | Stop-Process -WhatIf | Tee-Object -FilePath c: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Compare-Object | ||
+ | |||
+ | Compare-Object -DifferenceObject 1 -ReferenceObject 2 | ||
+ | Compare-Object -DifferenceObject 1 -ReferenceObject 1 | ||
+ | |||
+ | $a = "Hallo Köln", | ||
+ | $b = "Hallo Köln", | ||
+ | Compare-Object -DifferenceObject $b -ReferenceObject $a | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Group-Object (Gruppiert zu Objektgruppen) | ||
+ | |||
+ | Get-Service | Group-Object -Property Status | Get-Member | ||
+ | (Get-Service | Group-Object -Property Status -AsHashTable -AsString).Running | ||
+ | (Get-Service | Group-Object -Property Status).Group | ||
+ | |||
+ | Get-Service | Sort-Object Status | Format-Table -GroupBy Status # Gruppiert die Ausgabe | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Mit PowerShell-Objekten umgehen (Get-Member) | ||
+ | |||
+ | # Alle CmdLets liefern Objekte zurück die intensiv ausgewertet werden können / müssen | ||
+ | # ' | ||
+ | |||
+ | # Am Unterschied zwischen ping.exe (DOS-Welt) und Test-NetConnection (PowerShell-Welt) | ||
+ | # den Mehrwert von Objekten schätzen lernen. Hier eine Prüfung ob ein Zeilhost erreichbar ist: | ||
+ | |||
+ | ping.exe | ||
+ | | ||
+ | | ||
+ | | ||
+ | ((ping.exe | ||
+ | |||
+ | | ||
+ | (Test-NetConnection -ComputerName 127.0.0.1).PingSucceeded | ||
+ | |||
+ | # | ||
+ | # Rückgabe-Objekte analysieren mit Get-Member | ||
+ | # | ||
+ | |||
+ | ping.exe 127.0.0.1 | Get-Member | ||
+ | Test-NetConnection -ComputerName 127.0.0.1 | Get-Member | ||
+ | |||
+ | # Get-Member analysiert jedes Objete in der Pipeline und liefert gruppiert die Antwort auf: | ||
+ | # Vom welchen Typ ist das Objekt | ||
+ | # Welche Eigenschaften, | ||
+ | |||
+ | Get-ChildItem c:\ -Force | Get-Member # z.B. 2 unterschiedliche Objekt-Typen | ||
+ | Get-Process -Name notepad | Get-Member | ||
+ | |||
+ | # Erklährung zum Ergebnis von Get-Member: | ||
+ | # | ||
+ | # TypeName <= Vollständige Typ-Name, z.B.: System .IO .FileInfo | ||
+ | # NAMESPACE.NAMESPACE.TYPENAME | ||
+ | # siehe google, bing, etc. | ||
+ | # Name <= Name des Member' | ||
+ | # MemberType <= Art des Members | ||
+ | # *Property TypeName PropertyName {get; set;} | ||
+ | # Methode void => Ohne Rückgabe | ||
+ | # ... MethodName(EingabeTyp' | ||
+ | # Definition <= Beschreibung | ||
+ | |||
+ | Set-Content -Path c: | ||
+ | $datei = Get-ChildItem -Path C: | ||
+ | $datei.Length # long Length {get;} | ||
+ | $datei.Length = 99 | ||
+ | $datei.CreationTime | ||
+ | $datei.CreationTime = " | ||
+ | $datei | Get-Member | ||
+ | |||
+ | $datei | Add-Member -MemberType NoteProperty -Name Bemerkung -Value "Eine Eigenschaft die diesem O. hinzugefügt wurde" | ||
+ | $datei | Get-Member | ||
+ | $datei.Bemerkung | ||
+ | $datei.VersionInfo | ||
+ | # z.B. Enthält Length die größe der Datei? Bzw. wenn ja, was KB, MB, ...? | ||
+ | # Evtl. im Internet nachlesen über den Typenname! | ||
+ | |||
+ | $datei.Delete() # void Delete() | ||
+ | (Get-ChildItem -Path C:\temp -File).Delete() | ||
+ | |||
+ | Get-Process -Name notepad | Get-Member | ||
+ | (Get-Process -Name notepad).WaitForExit(5000) | ||
+ | (Get-Process -Name notepad).WaitForExit() | ||
+ | |||
+ | # ÜBUNG Köln in "Hallo Köln!" | ||
+ | # ÜBUNG Alle Dateien finden die älter sind als 180 Tage (OPTIONAL vom 1.1.2015 gerechnet) | ||
+ | |||
+ | #endregion | ||
+ | #region Formatierung & Ausgabe (Format-*, ConvertTo-* Write-*, Out-*) | ||
+ | |||
+ | # | ||
+ | # Übersicht | ||
+ | # | ||
+ | |||
+ | Get-Command -Verb Format, ConvertTo, Out, Write -Module Microsoft.PowerShell.* | ||
+ | |||
+ | #region Format-* | ||
+ | |||
+ | # | ||
+ | # Format-Table | ||
+ | # | ||
+ | |||
+ | Get-Process | ||
+ | Get-Process | Format-Table * # Alle Spalten | ||
+ | Get-Process | ft Name, Company, CPU # Spezielle Spalten | ||
+ | Get-Process | ft Name, Company, CPU -AutoSize # Performance !? | ||
+ | Get-Process | Format-Table Name, WorkingSet64 | ||
+ | Get-Process | ft Name, @{Label=" | ||
+ | Get-Process | ft Name, @{Name=" | ||
+ | |||
+ | Get-EventLog -LogName System -Newest 10 | ||
+ | Get-EventLog -LogName System -Newest 10 | ft -Wrap # Lange Text in Zeilen umbrechen | ||
+ | Get-EventLog -LogName System -Newest 10 | Get-Member | ft -Wrap | ||
+ | |||
+ | Get-EventLog -LogName System -Newest 50 | ft -GroupBy EntryType | ||
+ | Get-EventLog -LogName System -Newest 50 | Sort-Object EntryType | ft -GroupBy EntryType | ||
+ | |||
+ | Get-EventLog -LogName System -Newest 50 | Sort-Object EntryType | ft -GroupBy EntryType | Out-File -FilePath c: | ||
+ | |||
+ | # | ||
+ | # Format-List | ||
+ | # | ||
+ | |||
+ | Get-Process | fl Name, Company, CPU # Spezielle Spalten | ||
+ | Get-Process | fl * | ||
+ | Get-Process | Select-Object -First 1 | fl * | ||
+ | (Get-Process)[0] | fl * | ||
+ | |||
+ | # | ||
+ | # Format-Wide | ||
+ | # | ||
+ | |||
+ | Get-Alias | fw Name -Column 8 | ||
+ | |||
+ | # WICHTIG | ||
+ | # Die CmdLet' | ||
+ | # nicht weiter verwertet werden !!!!!!! | ||
+ | # ------------------------------------- | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Write-* | ||
+ | |||
+ | "Hallo Köln!" | ||
+ | "Hallo Köln!" | ||
+ | "Hallo Köln!" | ||
+ | Write-Host " | ||
+ | "Hallo Köln!" | ||
+ | Write-Error " | ||
+ | Write-Warning "und ich bin eine Warnung" | ||
+ | Write-Debug "und ich eine Debug-Meldung" | ||
+ | |||
+ | # | ||
+ | # Beispiel I: | ||
+ | # | ||
+ | |||
+ | for ($i = 1 ; $i -lt 10 ; $i++) # $i++ => $i = $i + 1 | ||
+ | { | ||
+ | [System.Threading.Thread]:: | ||
+ | Write-Host " | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # Beispiel II: | ||
+ | # | ||
+ | |||
+ | $guthaben = 12345.98 | ||
+ | $konto = 47110815 | ||
+ | Write-Host "Auf ihrem Konto `" | ||
+ | Write-Host 'Auf ihrem Konto $konto ist ein Guthaben von $guthaben!' | ||
+ | . " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region OUT-* | ||
+ | |||
+ | Get-Command -Verb Out -Module Microsoft.PowerShell.* | ||
+ | |||
+ | "Jetzt ist " + (Get-Date) | Out-File C: | ||
+ | Get-Content C: | ||
+ | |||
+ | "Jetzt ist " + (Get-Date) | Out-File C: | ||
+ | Get-Content C: | ||
+ | |||
+ | Get-Process | ft * | Out-String -Width 500 | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region ConvertTo- | ||
+ | |||
+ | Get-Command -Verb ConvertTo -Module Microsoft.PowerShell.* | ||
+ | |||
+ | Get-Process | ConvertTo-Csv | out-File C: | ||
+ | Get-Process | Select-Object Name, Company, WorkingSet64 | ConvertTo-Csv -NoTypeInformation -Delimiter ";" | ||
+ | . C: | ||
+ | |||
+ | Get-Process | Select-Object Name, Company, WorkingSet64 | ConvertTo-Html | out-File C: | ||
+ | . C: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | # Übung: Eine Liste der laufenden Processes für | ||
+ | # Excel (csv) aufbereiten mit den Spalten | ||
+ | # Name, Arbeitsspeicher, | ||
+ | |||
+ | # ÜBUNG: CSV-Datei aller laufenden Dienste für die spätere analyse! (import/ | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell-Provider und -Laufwerke als standadisierte Schnittstellen | ||
+ | |||
+ | # Mit PowerShell-Provider werden div. ' | ||
+ | # - Dateisystem | ||
+ | # - Umgebungsvariablen | ||
+ | # - PowerShell-Variablen | ||
+ | # - PowerShell-Funktionen | ||
+ | # - Registrierungsdatenbank | ||
+ | # - X.509-Zertifikatsspeicher | ||
+ | # - [OPTIONAL] ActiveDirectory | ||
+ | # - [OPTIONAL] Exchange-Postfächer/ | ||
+ | # - [OPTIONAL] MS SQL-Server | ||
+ | # - u.v.m. | ||
+ | |||
+ | Get-PSProvider # Durch das Laden eines Modules können weitere PS-Provider hinzukommen | ||
+ | Import-Module -Name ActiveDirectory | ||
+ | Get-PSProvider | ||
+ | |||
+ | # Für die Interaktion mit den PS-Provider' | ||
+ | |||
+ | Get-PSDrive | ||
+ | |||
+ | # Releative und absolute Pfade: | ||
+ | # . = Aktueller Ordner | ||
+ | # .. = Übergeordneter | ||
+ | # \ = Stamm | ||
+ | # ~ = Basis (Home-Verzeichnis) | ||
+ | |||
+ | gci . | ||
+ | gci .. | ||
+ | gci \ | ||
+ | gci ~ | ||
+ | |||
+ | gci c:\ | ||
+ | gci variable:\ | ||
+ | gci cert:\ | ||
+ | gci env:\ | ||
+ | gci hkcu:\ | ||
+ | |||
+ | |||
+ | Set-Location C: | ||
+ | Resolve-Path -Path .\msinfo32.exe | ||
+ | Test-Path | ||
+ | Test-Path | ||
+ | Split-Path | ||
+ | Split-Path | ||
+ | Join-Path | ||
+ | |||
+ | # Kennt man einen kennt man alle :-) | ||
+ | # Befehle in einem PSProvider sind zu 100% übertragbar auf andere PSProvider | ||
+ | |||
+ | Get-Command rm | ||
+ | Get-Command del | ||
+ | Get-Alias -Definition Remove-Item | ||
+ | ri C: | ||
+ | ri HKCU: | ||
+ | |||
+ | # | ||
+ | # ÜBERSICHT | ||
+ | # | ||
+ | |||
+ | Get-Command -Name *item*, Set-Location -Module Microsoft.PowerShell.Management | Out-GridView | ||
+ | |||
+ | Set-Location c: | ||
+ | Get-ChildItem | ||
+ | cd C: | ||
+ | |||
+ | Set-Location env: | ||
+ | Get-ChildItem | ||
+ | |||
+ | Set-Location hkcu: | ||
+ | Set-Location Software | ||
+ | Set-Location .. | ||
+ | |||
+ | # Exemplarisches Handling für den PSProvider " | ||
+ | |||
+ | # Schlüssel ' | ||
+ | New-Item -Path HKCU: | ||
+ | New-Item -Path c: | ||
+ | New-Item -Path c: | ||
+ | |||
+ | # Default-Wert für ' | ||
+ | New-Item -Path HKCU: | ||
+ | |||
+ | # Eine NEUE Eigenschaft für den Schlüssel " | ||
+ | New-ItemProperty -Path HKCU: | ||
+ | New-ItemProperty -Path HKCU: | ||
+ | |||
+ | # Eine VORHANDENE Eigenschaft geändert | ||
+ | Set-ItemProperty -Path HKCU: | ||
+ | |||
+ | # Den Schlüssel ' | ||
+ | Get-Item -Path HKCU: | ||
+ | |||
+ | # BTW: Achtung | ||
+ | Get-Item | ||
+ | Get-ChildItem -Path C:\Windows | ||
+ | Get-ChildItem -Path HKCU: | ||
+ | Get-ChildItem -Path HKCU: | ||
+ | Get-ChildItem -Path HKCU: | ||
+ | |||
+ | # Den Wert von Heute des Schlüssels ' | ||
+ | Get-ItemProperty -Path HKCU: | ||
+ | $heute = Get-ItemProperty -Path HKCU: | ||
+ | $heute.Heute | ||
+ | (Get-ItemProperty -Path HKCU: | ||
+ | (Get-ItemProperty -Path HKCU: | ||
+ | [datetime](gp HKCU: | ||
+ | |||
+ | # Den Default-Wert des Schlüssels ' | ||
+ | (Get-ItemProperty -Path HKCU: | ||
+ | |||
+ | # Die Eigenschaft ' | ||
+ | Remove-ItemProperty -Path HKCU: | ||
+ | |||
+ | # Den Default-Wert des Schlüssels ' | ||
+ | Set-ItemProperty -Path HKCU: | ||
+ | |||
+ | # Den Schlüssel ' | ||
+ | Remove-Item -Path HKCU: | ||
+ | |||
+ | # | ||
+ | # Zum Beispiel PSProvider " | ||
+ | # | ||
+ | |||
+ | Get-ChildItem function: | Out-GridView | ||
+ | Get-ChildItem Function: | ||
+ | function hkcu: { Set-Location hkcu: } | ||
+ | hkcu: | ||
+ | Get-ChildItem Function: | ||
+ | |||
+ | # | ||
+ | # Weitere Beispiele: | ||
+ | # | ||
+ | New-Item -Path C: | ||
+ | New-PSDrive -Name Skripts -PSProvider FileSystem -Root C: | ||
+ | Set-Location skripts: | ||
+ | New-Item -Path .\test.txt -ItemType ' | ||
+ | Get-PSDrive | ||
+ | |||
+ | Get-ChildItem -Path HKLM:, HKCU: -Include ' | ||
+ | |||
+ | Get-ChildItem $HOME -Force | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell und Remoting | ||
+ | |||
+ | # WICHTIG: Das Netzwerk muss sicg im Domänen- bzw. Privaten-Netzwerkprofil befinden | ||
+ | Set-NetConnectionProfile -NetworkCategory Private | ||
+ | Get-NetConnectionProfile | ||
+ | |||
+ | # Version 1: RPC (ab PowerShell 2.0) | ||
+ | # + Das geht immer, muss nicht aktiviert oder eingerichtet werden | ||
+ | # + Seit PowerShell 2.0 | ||
+ | # - Nur möglich mit ausgewählten CmdLets | ||
+ | |||
+ | Get-NetFirewallProfile | ||
+ | Set-NetFirewallProfile -Profile Domain, Public, Private -Enabled False | ||
+ | |||
+ | Get-Help * -Parameter " | ||
+ | Get-Service -ComputerName 192.168.50.41, | ||
+ | |||
+ | # Version 2: WinRM (ab PowerShell 3.0) | ||
+ | # - Muss aktiviert und eingerichtet (Client / Server) | ||
+ | # + Geht mit allen CmdLets/ | ||
+ | # Wichtig: Firewall TCP 5985 | ||
+ | |||
+ | # Einmal WinRM aktivieren (Für Quell- und Zielsystem auch gerne über eine GPO) | ||
+ | Enable-PSRemoting -Force | ||
+ | |||
+ | # Einmal eine Client- und Zielsystem-Vertrauensstellung einrichten | ||
+ | $value = (gci -Path WSMan: | ||
+ | Set-Item -Path wsman: | ||
+ | # Möglich Werte sind auch: SqlServer01, | ||
+ | Set-Item -Path WSMan: | ||
+ | gci -Path wsman: | ||
+ | |||
+ | # | ||
+ | # Nutzen | ||
+ | # | ||
+ | |||
+ | # OPTIONAL wenn anderen Credential benötigt werden als der aktuelle Context | ||
+ | $cred = Get-Credential -Message "Bitte anmelden für ..." -UserName " | ||
+ | |||
+ | # EINE Session zum Zielsystem öffnen | ||
+ | $session1 = New-PSSession -ComputerName 192.168.50.50 -Credential $cred | ||
+ | |||
+ | # Informationen über aktuelle Sessions | ||
+ | Get-PSSession | ||
+ | |||
+ | # Eine offene Session nutzen | ||
+ | Enter-PSSession -Session $session1 | ||
+ | Enter-PSSession -Id 1 | ||
+ | Enter-PSSession -ComputerName 192.168.50.50 -Credential (Get-Credential) | ||
+ | |||
+ | # TEST | ||
+ | New-Item c: | ||
+ | |||
+ | # Zurück zur eigenen lokalen Session | ||
+ | Exit-PSSession | ||
+ | Get-PSSession # Session bleiben offen und aktiv | ||
+ | |||
+ | # Aktive Sessions löschen | ||
+ | Remove-PSSession -Session $session1 | ||
+ | Remove-PSSession -Id 1 | ||
+ | Get-PSSession | ||
+ | |||
+ | # ------------------------------------------------------------------------- | ||
+ | |||
+ | # | ||
+ | # Ein Script/ | ||
+ | # | ||
+ | |||
+ | # Mehrere Session erstellen | ||
+ | $sessions = New-PSSession -ComputerName 192.168.50.41, | ||
+ | $Session1 = New-PSSession -ComputerName 192.168.50.41 -Credential $cred # Single Session | ||
+ | $Session2 = New-PSSession -ComputerName 192.168.50.41 -Credential $cred # Single Session | ||
+ | |||
+ | # Offene Sessions nutzen | ||
+ | Invoke-Command -Session $sessions | ||
+ | Invoke-Command -Session $session1, $session1 -ScriptBlock {Get-Process} | ||
+ | |||
+ | # Sessions beenden | ||
+ | Remove-PSSession -Session $sessions | ||
+ | |||
+ | # ------------------------------------------------------------------------- | ||
+ | |||
+ | # Was passiert beim starten einer UI-App? | ||
+ | Invoke-Command -Session $sessions -ScriptBlock {Start-Process calc.exe} | ||
+ | |||
+ | # Siehe auch | ||
+ | Get-Command -Noun PSSession | Out-GridView | ||
+ | Get-Help about_*remote_* | Out-GridView | ||
+ | |||
+ | # ------------------------------------------------------------------------- | ||
+ | |||
+ | # -> 6. PSRemoting deaktivieren | ||
+ | |||
+ | Set-Item wsman: | ||
+ | Disable-PSRemoting -Force | ||
+ | Set-NetConnectionProfile -NetworkCategory Public | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell-Funktionen erweitern (Module) | ||
+ | |||
+ | # -> 1. Welche Module sind z.Zt. installiert? | ||
+ | |||
+ | Get-Module -ListAvailable # Übersicht installierte Module, gruppiert nach Modul-Ordner | ||
+ | |||
+ | <# | ||
+ | Module die PC-Weit gelten: | ||
+ | C: | ||
+ | |||
+ | Module die nur für den entsprechenden User gelten: | ||
+ | C: | ||
+ | |||
+ | Expliziet eingebundene Module-Ordner, | ||
+ | #> | ||
+ | $env: | ||
+ | |||
+ | # -> 2. Benötigte Module installieren: | ||
+ | |||
+ | <# | ||
+ | Zum Beispiele: | ||
+ | Microsoft | ||
+ | Exchange Server | ||
+ | Windows Server (WS2K8=Features, | ||
+ | SQL Server | ||
+ | SharePoint | ||
+ | System Center Operations Manager | ||
+ | System Center Virtual Machine Manager | ||
+ | System Center Data Protection Manager | ||
+ | Windows Compute Cluster Server | ||
+ | PowerTools for Open XML (Office2007+) | ||
+ | Internet Information Services | ||
+ | Windows 7 Troubleshooting Center | ||
+ | Deployment Toolkit LOGINventory | ||
+ | IBM | ||
+ | Transporter Suite for Lotus Domino | ||
+ | WebSphere MQ | ||
+ | VMware | ||
+ | Infrastructure Toolkit | ||
+ | Quest | ||
+ | Management Shell for Active Directory | ||
+ | DIVERS | ||
+ | Special Operations Software Specops Command | ||
+ | U.V.M. | ||
+ | #> | ||
+ | Start-Process -FilePath " | ||
+ | |||
+ | |||
+ | # | ||
+ | # 1. SCHRITT: Modul installieren | ||
+ | # Durch eine setup.exe, *.msi oder über Eweitertete Installation eines Server-Produkts | ||
+ | # | ||
+ | |||
+ | # | ||
+ | # z.B.: PowerShell Community Extensions (PSCX auf http:// | ||
+ | # | ||
+ | |||
+ | . " | ||
+ | gci -Path " | ||
+ | $env: | ||
+ | Get-Module -Name PSCX -ListAvailable # Installiert? | ||
+ | |||
+ | # | ||
+ | # z.B.: Attila Krick PowerShell Tools (AKPT) | ||
+ | # manuell in einen der Modul-ORdner kopieren | ||
+ | # | ||
+ | |||
+ | Copy-Item -Path C: | ||
+ | Get-Module -Name AKPT -ListAvailable # Installiert? | ||
+ | |||
+ | Find-Module | ||
+ | Install-Module -Name AKPT # AB PS5.0 direkt aus dem Intenet- oder Firmenspeicher installieren | ||
+ | |||
+ | # | ||
+ | # 2. SCHRITT: Modul nutzbar machen | ||
+ | # | ||
+ | |||
+ | Get-Module | ||
+ | Import-Module -Name AKPT # Bei starten einer PS-Sitzung erneut ausführen | ||
+ | Get-Module | ||
+ | Remove-Module -Name AKPT # Entläd ein Modul (Nicht mehr nutzbar) | ||
+ | Get-Module | ||
+ | |||
+ | # Seit der PowerShell 3.0 wird Import-Module automatisch ausgeführt | ||
+ | Get-HotKeys | ||
+ | Get-Module | ||
+ | |||
+ | Get-Command -Module AKPT | ||
+ | Read-Window -Title " | ||
+ | |||
+ | Get-Command -Module PSCX | Out-GridView | ||
+ | gci function: | ||
+ | |||
+ | #endregion | ||
+ | #region Variablen (*-Variable) | ||
+ | |||
+ | # | ||
+ | # Übersicht | ||
+ | # | ||
+ | |||
+ | Get-Help about_Variables | ||
+ | Get-Help about_Scopes | ||
+ | Get-Help about_Automatic_Variables | ||
+ | Get-Help about_Hash_Tables | ||
+ | |||
+ | Get-Help about_Objects | ||
+ | Get-Help about_Object_Creation | ||
+ | |||
+ | Get-Help about_Special_Characters | ||
+ | |||
+ | # CmdLets um das Thema Variable | ||
+ | Get-Command -Name *variable* -Module Microsoft.PowerShell.Utility | Out-GridView | ||
+ | |||
+ | # PowerShell-Provider für Variable | ||
+ | Get-ChildItem -Path variable: -Force | Out-GridView | ||
+ | |||
+ | # Der Inhalt einer V. bleibt über die komplette Sitzung erhalten! (Nicht nur zur Laufzeit eines Skriptes) | ||
+ | |||
+ | $einfach = 12 # In Variablen können einfache atomare Objekte gespeichert werden... | ||
+ | $komplex = (Get-Service)[0] # ... aber auch KOMPLEXE Objekte. | ||
+ | |||
+ | # | ||
+ | # Zuweisungen | ||
+ | # | ||
+ | |||
+ | $PI = 99.9 # Variablen werden autom. mit der ersten Benutzung deklariert... | ||
+ | New-Variable -Name PI -Value 3.14 -Description " | ||
+ | |||
+ | $var1 = "Hallo Köln" | ||
+ | $var2 = Get-Process | ||
+ | $var3 = (Get-Process)[0] | ||
+ | $var4 = $var2[0] | ||
+ | $var5 = {Get-Process} | ||
+ | $array1 = 1, 2, 3, 4 # eindimenmsionals Array | ||
+ | $array2 = (11,12,13), (21,22,23), (31, | ||
+ | $array3 = " | ||
+ | $pc1 = [ordered]@{" | ||
+ | $array4 = " | ||
+ | $env: | ||
+ | $Function: | ||
+ | ${c: | ||
+ | |||
+ | # | ||
+ | # Lesen / Nutzen | ||
+ | # | ||
+ | |||
+ | $var1 | ||
+ | Write-Host -Object $var1 | ||
+ | $var5 # Anzeige Inhalt Script-Block | ||
+ | . $var5 # Script-Block ausführen (BTW: Datei werden so auch ausgeführt) | ||
+ | $array2[0] | ||
+ | $array2[1][1] | ||
+ | $array3 | select -Last 1 | ||
+ | $array3.Length | ||
+ | $pc1[" | ||
+ | $pc1[" | ||
+ | $pc1[" | ||
+ | |||
+ | # | ||
+ | # Variablen auch gerne als Temp-Note nutzen, z.B.: | ||
+ | # | ||
+ | |||
+ | $var4 = gci c:\ -File -Recurse -ErrorAction SilentlyContinue | ||
+ | $var4.Length | ||
+ | $var4 | ||
+ | $var5 = $var4 | ? Name -Like " | ||
+ | $var5.Length | ||
+ | $var5 | ||
+ | |||
+ | # | ||
+ | # Prüfen ob eine Variable (PSProvider) vorhanden ist | ||
+ | # | ||
+ | |||
+ | Test-Path -Path variable: | ||
+ | Test-Path -Path variable: | ||
+ | |||
+ | # | ||
+ | # Eine Variable muss immer von einem Typ sein | ||
+ | # | ||
+ | |||
+ | $text = "Hallo Köln!" | ||
+ | $zahl1 | ||
+ | $zahl2 | ||
+ | $istWahr = $true # System.Boolean | ||
+ | $objekt1 = (Get-Process)[0] # System.Diagnostics.Process | ||
+ | $objekt2 = Get-Process | ||
+ | |||
+ | # Typ der Variablen ermitteln | ||
+ | $objekt1.GetType() | ft Name, FullName, BaseType | ||
+ | $objekt2.GetType() | ft Name, FullName, BaseType | ||
+ | $objekt1 | Get-Member | ||
+ | $objekt2 | Get-Member # ACHTUNG: richtet sich immer an Array-Elemente | ||
+ | |||
+ | $IchBinEineDateiOderOrdner -is [System.IO.FileInfo] | ||
+ | $zahl1 -is [System.Int64] | ||
+ | |||
+ | |||
+ | # TIP: i.d.R. den Typen fest angeben | ||
+ | [Int32]$alter = 12 | ||
+ | $alter = "Hallo Köln!" | ||
+ | |||
+ | # z.B. | ||
+ | |||
+ | [datetime]$eingabe = Read-Host -Prompt "Alte Dateien finden vor welchen Datum (yyyy-MM-dd z.B. 2015-12-31)?" | ||
+ | gci C:\ -Recurse | ? LastAccessTime -le $eingabe | ||
+ | |||
+ | $deDE = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList " | ||
+ | $eingabe2 = Read-Host -Prompt "Alte Dateien finden vor welchen Datum?" | ||
+ | gci C:\ -Recurse | ? LastAccessTime -le $eingabe2.ToDateTime($deDE) | ||
+ | |||
+ | # | ||
+ | # Variablen evtl. aufräumen | ||
+ | # | ||
+ | |||
+ | Remove-Variable -Name alter | ||
+ | Remove-Variable -Name PI -Force | ||
+ | Remove-Variable -Name * -Force -ErrorAction SilentlyContinue | ||
+ | |||
+ | # | ||
+ | # Beispiele mit Variablen | ||
+ | # | ||
+ | |||
+ | $geld = 123456.78 | ||
+ | $geldSchön = $geld.ToString("#,## | ||
+ | "Ihr Guthaben ist: $geldSchön" | ||
+ | |||
+ | $heute = Get-Date -DisplayHint Date | ||
+ | $heute.ToString(" | ||
+ | $heute = Get-Date | ||
+ | $heute.ToString(" | ||
+ | |||
+ | # Datum des letzten Tages im akt. Monat? | ||
+ | $letzterTagImMonat = Get-Date -Year (Get-Date).Year -Month (Get-Date).Month -Day 1 -Hour 0 -Minute 0 -Second 0 -Millisecond 0 | ||
+ | $letzterTagImMonat = $letzterTagImMonat.AddMonths(1).AddDays(-1) | ||
+ | $letzterTagImMonat | ||
+ | |||
+ | # Anzahl Tage bis Neujahr | ||
+ | [datetime]$neuJahr = " | ||
+ | $dauer = $neuJahr - (Get-Date) # [System.DateTime] MINUS [System.DateTime] GLEICH [System.TimeSpan] | ||
+ | $dauer | Get-Member | ||
+ | $dauer | fl * | ||
+ | $dauer.Days | ||
+ | |||
+ | # | ||
+ | # Gültigkeitsbereichen | ||
+ | # | ||
+ | |||
+ | $wert = 23 | ||
+ | function TestBereich | ||
+ | { | ||
+ | "Wert in der Funktion: $wert" | ||
+ | $wert = 43 | ||
+ | "Neuer Wert in der Funktion: $wert" | ||
+ | } | ||
+ | |||
+ | TestBereich | ||
+ | "Wert außerhalb der Funktion: $wert" | ||
+ | |||
+ | . TestBereich # . Abschirmung deaktiviert ehr NOGO! | ||
+ | "Wert außerhalb der Funktion: $wert" | ||
+ | |||
+ | $global: | ||
+ | $private: | ||
+ | $script: | ||
+ | |||
+ | #endregion | ||
+ | #region Operatoren | ||
+ | |||
+ | # | ||
+ | # ÜBERSICHT | ||
+ | # | ||
+ | |||
+ | Get-Help about_Operators | ||
+ | Get-Help about_Operator_Precedence | ||
+ | Get-Help about_Arithmetic_Operators -ShowWindow # Arithmetische Operatoren | ||
+ | Get-Help about_Assignment_Operators -ShowWindow # Zuweisungs- Operatoren | ||
+ | Get-Help about_Logical_Operators | ||
+ | Get-Help about_Comparison_Operators -ShowWindow # Vergleichs- Operatoren | ||
+ | Get-Help about_Type_Operators | ||
+ | Get-Help about_Split | ||
+ | Get-Help about_Join | ||
+ | |||
+ | #region about_Assignment_Operators | ||
+ | |||
+ | $zahl=1 | ||
+ | $zahl++ | ||
+ | $zahl-- | ||
+ | $zahl+=2 # $zahl = $zahl + 2 | ||
+ | $zahl-=3 # $zahl = $zahl - 3 | ||
+ | $zahl++ | ||
+ | $zahl # Ergebnis: 1 | ||
+ | |||
+ | $zahl=-10 # Ergebnis: ??? | ||
+ | $zahl | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_Arithmetic_Operators | ||
+ | |||
+ | # Siehe About-Seite! | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_Logical_Operators | ||
+ | |||
+ | $true -and $true | ||
+ | $true -or $false | ||
+ | ($true -and $true) -or ($true -or $false) | ||
+ | !$true -and $true | ||
+ | -not $true -and $true | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_Comparison_Operators | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | # ACHTUNG | ||
+ | " | ||
+ | 010 -eq " | ||
+ | [Int32]" | ||
+ | |||
+ | # | ||
+ | # -like | ||
+ | # | ||
+ | |||
+ | " | ||
+ | |||
+ | # -match (Reguläre Ausdrücke, kurz " | ||
+ | |||
+ | <# | ||
+ | REGEX = TARGET | ||
+ | a = a | ||
+ | [abc] = a b c | ||
+ | a{2,5} = aa aaa aaaa aaaaa | ||
+ | . = Alle Zeichen außer Zeilenumbrüche | ||
+ | \ = Maskieren | ||
+ | ^ = Vom ersten Zeichen | ||
+ | $ = Bis zum lezten Zeichen | ||
+ | + = {1,} | ||
+ | * = {0,} | ||
+ | |||
+ | #> | ||
+ | |||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | " | ||
+ | |||
+ | # | ||
+ | # Array-Vergleich | ||
+ | # | ||
+ | |||
+ | 10, | ||
+ | 10, | ||
+ | 10, | ||
+ | |||
+ | # | ||
+ | # Vergleichsoperatoren z.B. nutzen in: Where-Object, | ||
+ | # | ||
+ | if(10 -gt 5) | ||
+ | { | ||
+ | # CmdLet | ||
+ | } | ||
+ | else # Optional | ||
+ | { | ||
+ | # CmdLet | ||
+ | } | ||
+ | |||
+ | 10,11,12,13 -contains 10 | ||
+ | (10, | ||
+ | (10, | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_Type_Operators | ||
+ | | ||
+ | (Get-Process)[0] -is [System.Diagnostics.Process] # Ist ein Objekt von einem bestimmten Typen | ||
+ | (Get-Process) | ||
+ | |||
+ | " | ||
+ | [DateTime]" | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region -f (Format-Operator) s. about_operators | ||
+ | |||
+ | # " | ||
+ | |||
+ | "Wert 1 ist {0}, der letzte Wert ist {3} und die anderen sind: {1}, {2}" -f 10, | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | |||
+ | "Heute ist {0}" | ||
+ | "Heute ist {0} und wir haben {1} Uhr" | ||
+ | "Heute ist {0} und wir haben {0} Uhr" | ||
+ | "Heute ist {0: | ||
+ | "Heute ist {0:dddd.} der {0:d. MMMM} anno {0:yyyy HH:mm} und {0: | ||
+ | |||
+ | " | ||
+ | "{0, 10:0.0} | {1, 10:0.0} | {2, 10: | ||
+ | "{0, 10:0.0} | {1, 10:0.0} | {2, 10: | ||
+ | "{0, 10:0.0} | {1, 10:0.0} | {2, 10: | ||
+ | |||
+ | Write-Host "{0, 10:0.0} | {1, 10:0.0} | {2, 10: | ||
+ | |||
+ | # | ||
+ | # Beispiele | ||
+ | # | ||
+ | |||
+ | $pcs = (1..99 | ForEach-Object -Process {" | ||
+ | $session = New-PSSession -ComputerName $pcs | ||
+ | Invoke-Command -Session $session -ScriptBlock {Restart-Computer} | ||
+ | |||
+ | " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_Split | ||
+ | |||
+ | $result = " | ||
+ | $result[1] | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region about_join | ||
+ | |||
+ | $result = "Hallo Köln!", | ||
+ | $result -join ";" | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region replace | ||
+ | |||
+ | "Hallo Köln!" | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region WMI | ||
+ | |||
+ | Get-WmiObject -List Win32_ | ||
+ | |||
+ | $FormatEnumerationLimit = -1 | ||
+ | Get-WmiObject -List Win32_Product | fl Methods, Properties, Events | ||
+ | |||
+ | Get-WmiObject -Class Win32_Product # Software-Inventarisierung | ||
+ | Get-WmiObject -Class Win32_Product | select -First 1 | fl * | ||
+ | Get-WmiObject -List Win32_printer | ||
+ | |||
+ | |||
+ | #region Ein MSI-Paket installieren | ||
+ | |||
+ | $msi = " | ||
+ | $produkte = Get-WmiObject -Class Win32_Product -List | ||
+ | " | ||
+ | $ergebnis = $produkte.Install($msi) | ||
+ | "... Installation fertig mit dem Ergebnis {0}" -f $ergebnis.ReturnValue | ||
+ | Get-WmiObject -Class Win32_Product | where Name -like " | ||
+ | # ReturnValue siehe http:// | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | # | ||
+ | # Invoke-CimMethod | ||
+ | # | ||
+ | $inst = Get-CimInstance -Query " | ||
+ | Invoke-CimMethod -InputObject $inst -MethodName GetOwner | ||
+ | |||
+ | # | ||
+ | # s. Register-WmiEvent | ||
+ | # | ||
+ | |||
+ | #endregion | ||
+ | #region COM-Objekte | ||
+ | |||
+ | # | ||
+ | # BEISPIEL Excel | ||
+ | # | ||
+ | |||
+ | # (Excel bzw. Office muss installiert sein, Office PIA 2010 downloaden) | ||
+ | # BESSER: CSV, ' | ||
+ | |||
+ | $xls = New-Object -ComObject " | ||
+ | $xls.Visible = $true # Debugging | ||
+ | $wb = $xls.Workbooks.Add() | ||
+ | $ws = $wb.Worksheets.Add() | ||
+ | $a1 = $ws.Range(" | ||
+ | $a1.Value2 = " | ||
+ | $wb.SaveAs(" | ||
+ | $xls.Quit() | ||
+ | |||
+ | # | ||
+ | # BEISPIEL Word | ||
+ | # | ||
+ | |||
+ | $word=New-Object -ComObject " | ||
+ | $word.Visible=$true | ||
+ | |||
+ | $doc=$word.Documents.Add() | ||
+ | |||
+ | $win=$doc.Windows.Item(1) | ||
+ | $win.View.ShowAll=$true | ||
+ | |||
+ | $objAbs=$doc.Paragraphs.Item(1) | ||
+ | $objAbs.Range.Text=" | ||
+ | $objAbs.Range.Text=($objAbs.Range.Text + " | ||
+ | $objAbs=$doc.Paragraphs.Item(1) | ||
+ | $objAbs.Style=" | ||
+ | |||
+ | $erg=$doc.PrintOut([ref]$false) | ||
+ | $erg=$doc.prin | ||
+ | |||
+ | $doc.SaveAs([ref]" | ||
+ | $doc.Close([ref]$false) | ||
+ | $word.Quit() | ||
+ | $word=$null | ||
+ | |||
+ | Get-WmiObject Win32_COMClass # Davon können COM-Objekte erzeugt werden | ||
+ | |||
+ | #endregion | ||
+ | #region Registry | ||
+ | |||
+ | #s. region ' | ||
+ | |||
+ | #endregion | ||
+ | #region Verarbeiten von TXT | ||
+ | |||
+ | # | ||
+ | # ÜBERSICHT | ||
+ | # | ||
+ | |||
+ | Get-Command -Noun Content -Module Microsoft.PowerShell.* | ||
+ | |||
+ | gci C: | ||
+ | ? Extension -EQ " | ||
+ | Get-Content -ea SilentlyContinue | | ||
+ | Select-String -Pattern " | ||
+ | Add-Content -Path C: | ||
+ | |||
+ | Send-MailMessage ` | ||
+ | -To " | ||
+ | -From " | ||
+ | -Subject " | ||
+ | -Body ([String]:: | ||
+ | -Attachments " | ||
+ | -SmtpServer 192.168.50.10 ` | ||
+ | -Port 25 ` | ||
+ | -ErrorAction Stop | ||
+ | |||
+ | Remove-Item -Path c: | ||
+ | |||
+ | # Was machen Sie so mit *.txt-Dateien? | ||
+ | |||
+ | #endregion | ||
+ | #region Verarbeiten von CSV | ||
+ | |||
+ | # Schreiben | ||
+ | Get-Process | | ||
+ | Select-Object -Property Name, Company | | ||
+ | ConvertTo-Csv -NoTypeInformation -Delimiter ";" | ||
+ | Add-Content -Path c: | ||
+ | |||
+ | # Lesen | ||
+ | $result = Get-Content -Path c: | ||
+ | foreach($item in $result) { | ||
+ | "NAME {0} FIRMA {1}" -f ($item -split ";" | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region Verarbeiten von XML | ||
+ | |||
+ | # | ||
+ | # Auswerten | ||
+ | # | ||
+ | |||
+ | Invoke-WebRequest -Uri " | ||
+ | Select-Object -ExpandProperty Content | | ||
+ | Set-Content " | ||
+ | |||
+ | $xmlDokument = [xml](Get-Content -Path " | ||
+ | $xmlDokument.Envelope.Cube.Cube.Cube | ? currency -EQ " | ||
+ | $xmlDokument.Envelope.Cube.Cube.Cube | Out-GridView -OutputMode Single | ||
+ | |||
+ | $xmlDokument | ||
+ | $xmlDokument.Envelope | ||
+ | $xmlDokument.Envelope.Cube | ||
+ | $xmlDokument.Envelope.Cube.Cube | ||
+ | $xmlDokument.Envelope.Cube.Cube.Cube | Get-Member -MemberType Properties | ||
+ | $xmlDokument.Envelope.Cube.Cube.Cube.currency | ||
+ | $xmlDokument.Envelope.Cube.Cube.Cube.rate | ||
+ | |||
+ | # | ||
+ | # Schreiben | ||
+ | # | ||
+ | |||
+ | # z.B. Konfigurationsdatei | ||
+ | |||
+ | $config = [xml]@" | ||
+ | <?xml version=" | ||
+ | < | ||
+ | <Server Name=" | ||
+ | <Server Name=" | ||
+ | </ | ||
+ | "@ | ||
+ | $config.Einstellungen.Server | ||
+ | $config.Einstellungen.Server | ||
+ | ($config.Einstellungen.Server | ? Name -Like " | ||
+ | $config.Einstellungen.Server | ||
+ | |||
+ | $config.Save(" | ||
+ | |||
+ | $result = [xml](Get-Content " | ||
+ | $result.Einstellungen.Server | ||
+ | |||
+ | #endregion | ||
+ | #region Verarbeiten von Ordner & Dateien | ||
+ | |||
+ | # Siehe | ||
+ | |||
+ | Move-Item | ||
+ | Copy-Item | ||
+ | Remove-Item | ||
+ | New-Item | ||
+ | Get-Item | ||
+ | |||
+ | # | ||
+ | # Rechte | ||
+ | # | ||
+ | |||
+ | Get-Acl -Path C:\temp | fl * | ||
+ | |||
+ | $DogACL = Get-Acl C: | ||
+ | $DogACL | Get-Member | ||
+ | $DogACL.SetAccessRuleProtection($true, | ||
+ | Set-Acl -Path C:\Cat.txt -AclObject $DogACL | ||
+ | |||
+ | # Etwas auf allen Laufwerken suchen | ||
+ | |||
+ | Get-PSDrive -PSProvider FileSystem | | ||
+ | Select-Object -ExpandProperty Root | | ||
+ | gci -Force -File -ea SilentlyContinue | ||
+ | |||
+ | # Pfad und Besitzer anzeigen | ||
+ | |||
+ | " | ||
+ | " | ||
+ | |||
+ | " | ||
+ | $ht = @{" | ||
+ | " | ||
+ | New-Object PSObject -Property $ht | ||
+ | } | Out-GridView | ||
+ | |||
+ | # Oder so | ||
+ | |||
+ | " | ||
+ | $_ | Add-Member -MemberType NoteProperty -Name Owner ` | ||
+ | -Value ($_ | Get-Acl | Select-Object -ExpandProperty Owner) | ||
+ | $_ | ||
+ | } | Select-Object FullName, Owner | Out-GridView | ||
+ | |||
+ | # Belegter / Freier Speicher auf Festplatten | ||
+ | Get-PSDrive -PSProvider FileSystem | ||
+ | |||
+ | # Doppelte Dateien finden | ||
+ | Get-FileHash C: | ||
+ | |||
+ | # Dateien- / Ordner überwachen | ||
+ | $fsw = New-Object System.IO.FileSystemWatcher | ||
+ | $fsw.Path = " | ||
+ | $fsw.Filter=" | ||
+ | $action = { | ||
+ | Write-Warning (" | ||
+ | } | ||
+ | Register-ObjectEvent -InputObject $fsw -EventName Created -Action $action | ||
+ | Register-ObjectEvent -InputObject $fsw -EventName Deleted -Action $action | ||
+ | Get-EventSubscriber | ||
+ | Unregister-Event -SubscriptionId 3 | ||
+ | Unregister-Event -SubscriptionId 4 | ||
+ | |||
+ | #region Netzwerk-Freigabe erstellen | ||
+ | |||
+ | New-SmbShare -Name Data -Path C:\Windows | ||
+ | Remove-SmbShare -Name Data -Confirm: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region AUFBAU (Scripting) | ||
+ | |||
+ | #region > > > AGENDA < < < | ||
+ | |||
+ | #PowerShell - Aufbau | ||
+ | |||
+ | Start-Process " | ||
+ | |||
+ | ## FLUSSKONTROLLE IN SKRIPTEN | ||
+ | ### Das if/ | ||
+ | ### Das switch Statement [X] | ||
+ | ### Die while Schleife [X] | ||
+ | ### Die do ... while/until Schleife [X] | ||
+ | ### Die for Schleife [X] | ||
+ | ### foreach Schleife [X] | ||
+ | ### break & continue Klausel [X] | ||
+ | |||
+ | ## BENUTZERDEFINIERTE FUNKTIONEN & SKRIPTE | ||
+ | ### Grundlagen von Funktionen [X] | ||
+ | ### Der Dot Operator [X] | ||
+ | ### Formale Parameter und das param-Statement [X] | ||
+ | ### Rückgabewerte von Funktionen [X] | ||
+ | ### Function vs. Filter [X] | ||
+ | |||
+ | ## OBJEKTHANDLING | ||
+ | ### SkriptBlock - Grundlagen [x] | ||
+ | ### Erzeugen & Manipulieren von Objekten [x] | ||
+ | ### Arbeiten am Typsystem [x] | ||
+ | ### Typerweiterung [x] | ||
+ | |||
+ | ## FEHLER-MANAGEMENT | ||
+ | ### Was-wäre-wenn Szenarien [x] | ||
+ | ### Fehlertoleranz festlegen [x] | ||
+ | ### Fehler erkennen und darauf reagieren [x] | ||
+ | ### Error Records - Details zum Fehler [x] | ||
+ | ### Exceptions verstehen [x] | ||
+ | ### Code schrittweise ausführen: Haltepunkte [x] | ||
+ | |||
+ | ## SICHERHEIT | ||
+ | ### Absichern der PowerShell-Umgebung [x] | ||
+ | ### Signieren von Skripten [x] | ||
+ | |||
+ | ## .NET, C# UND VB.NET | ||
+ | ### PowerShell & .NET-OOP Einblick [x] | ||
+ | ### GUI mit .NET (WinForms, WPF) Einblick [X] | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Kontrollstrukturen (if, switch, while, do, for & foreach) | ||
+ | |||
+ | # TIP: STRG + J (Snippets) | ||
+ | |||
+ | # | ||
+ | # if | ||
+ | # | ||
+ | |||
+ | get-help about_if -ShowWindow | ||
+ | |||
+ | if (10 -lt 11) | ||
+ | { | ||
+ | "10 ist kleiner 11" | ||
+ | } | ||
+ | |||
+ | $x = 12 | ||
+ | if ($x -lt 20) | ||
+ | { | ||
+ | "$x ist kleiner 20" | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | "$x ist größer 20" | ||
+ | } | ||
+ | |||
+ | $x = 16 | ||
+ | if ($x -lt 15) | ||
+ | { | ||
+ | "$x ist kleiner 15" | ||
+ | } | ||
+ | elseif ($x -lt 20) | ||
+ | { | ||
+ | "$x ist kleiner 20 und größer 15" | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | "$x ist größer 20" | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # switch | ||
+ | # | ||
+ | |||
+ | get-help about_switch -ShowWindow | ||
+ | |||
+ | $x = " | ||
+ | switch -casesensitive ($x) | ||
+ | { | ||
+ | ' | ||
+ | { | ||
+ | # ... Code | ||
+ | break # Option: Und Fertig | ||
+ | } | ||
+ | | ||
+ | {$_ -in ' | ||
+ | { | ||
+ | } | ||
+ | |||
+ | ' | ||
+ | | ||
+ | Default # Optional, Wenn keine Prüfung passt | ||
+ | { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # do / while | ||
+ | # | ||
+ | |||
+ | get-help about_do -ShowWindow | ||
+ | |||
+ | do | ||
+ | { | ||
+ | # Code | ||
+ | } | ||
+ | until ($x -gt 0) # Fußgesteuerte Schleife, Solange eine Be. nicht zutrifft | ||
+ | |||
+ | do | ||
+ | { | ||
+ | # Code | ||
+ | } | ||
+ | while ($x -gt 0) # Solange die Be. zutrifft | ||
+ | |||
+ | while ($x -gt 0) # Kopfgesteuerte Schleife | ||
+ | { | ||
+ | # Code | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # for | ||
+ | # | ||
+ | |||
+ | get-help about_if -ShowWindow | ||
+ | |||
+ | for ($i = 1 ; $i -lt 99 ; $i++) # $i = $i + 1 | ||
+ | { | ||
+ | # Code | ||
+ | $i | ||
+ | #break | ||
+ | } | ||
+ | |||
+ | $prozesse = Get-Process | ||
+ | for ($i = 0; $i -lt $prozesse.length; | ||
+ | { | ||
+ | $prozesse[$i] | ||
+ | if($prozesse[$i].Company -eq "Virus Inc.") | ||
+ | { | ||
+ | $prozesse[$i].Kill() | ||
+ | } | ||
+ | } | ||
+ | Get-Process | ? Company -eq "Virus Inc." | Stop-Process | ||
+ | |||
+ | # | ||
+ | # foreach | ||
+ | # | ||
+ | |||
+ | get-help about_foreach -ShowWindow | ||
+ | |||
+ | foreach ($item in $collection) { } | ||
+ | |||
+ | foreach ($item in (Get-Process)) | ||
+ | { | ||
+ | if($item.Company -eq "Virus Inc.") | ||
+ | { | ||
+ | $item.Kill() | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # Alle Syntax-Blöcke können per CTRL + J als Vorlage erzeugt werden | ||
+ | # | ||
+ | |||
+ | #endregion | ||
+ | #region Bentuzerdefnierte Funktionen (eigene CmdLet' | ||
+ | |||
+ | # | ||
+ | # CmdLets können auf zwei Arten definiert werden: | ||
+ | # 1. per C# oder VisualBasic.NET-Code über VisualStudio => MeineCmdLets.DLL | ||
+ | # 2. per PowerShell-Funktion mit dem Namen VERB-NOUN => MeineCmdLets.PS1 | ||
+ | # WICHTIG: Diese CmdLets können erst genutzt werden, wenn sie im PSDrive function: etnhalten sind. | ||
+ | # => Durch AUSFÜHREN der Definition | ||
+ | # | ||
+ | |||
+ | # | ||
+ | # ÜBERSICHT | ||
+ | # | ||
+ | |||
+ | Get-Help about_Comment_Based_Help | ||
+ | Get-Help about_Functions | ||
+ | Get-Help about_Functions_Advanced | ||
+ | Get-Help about_Functions_Advanced_Methods | ||
+ | Get-Help about_Functions_Advanced_Parameters | ||
+ | Get-Help about_Functions_CmdletBindingAttribute | ||
+ | Get-Help about_Functions_OutputTypeAttribute | ||
+ | |||
+ | # | ||
+ | # Lernen von vorhanden CmdLets: | ||
+ | # | ||
+ | |||
+ | Get-Command -CommandType Function | measure | ||
+ | gci Function: | ||
+ | [GUID]:: | ||
+ | |||
+ | # BTW ACHTUNG: Passwörter haben im Code nichts verloren!!!!! | ||
+ | |||
+ | #region Einführungsbeispiel Get-About um die tägliche Arbeit mit der Hilfe zu erleichtern | ||
+ | |||
+ | Get-Help about_* | ||
+ | Get-Help about_* | Out-GridView | ||
+ | Get-Help about_remote_disconnnnected_Sessssions | ||
+ | Get-Help about_remote_disconnected_Sessions -ShowWindow | ||
+ | Get-Help about_* | Out-GridView -OutputMode Multiple | Get-Help -ShowWindow # Schon besser, aber immer noch zuviel zu tippen | ||
+ | |||
+ | # | ||
+ | # Lösung: Eigenes CmdLet | ||
+ | # | ||
+ | |||
+ | function Get-About | ||
+ | { | ||
+ | Get-Help about_* | Out-GridView -OutputMode Multiple | Get-Help -ShowWindow | ||
+ | } | ||
+ | |||
+ | Get-About | ||
+ | |||
+ | # | ||
+ | # o.a. Lösung verfeinern: | ||
+ | # | ||
+ | |||
+ | function Get-About | ||
+ | { | ||
+ | param([string]$Filter) | ||
+ | |||
+ | $result = Get-Help -Name " | ||
+ | if($result -is [array]) | ||
+ | { | ||
+ | $result | Out-GridView -OutputMode Multiple | Get-Help -ShowWindow | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Get-Help -Name " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Get-About -Filter if | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Unterschied Funktion vs. CmdLet-Funktion | ||
+ | |||
+ | function Fläche([int]$Breite, | ||
+ | { | ||
+ | $fläche = $Breite * $Länge | ||
+ | return $fläche | ||
+ | } | ||
+ | |||
+ | # Um eine Funktion benutzen zu können muss diese in den | ||
+ | # PowerShell-Provider function abgelegt werden | ||
+ | # durch das Ausführen der Definition | ||
+ | |||
+ | gci Function: | ||
+ | Fläche 10 10 | ||
+ | |||
+ | # wird die Session beendet wird die Funktion wieder gelöscht | ||
+ | |||
+ | Remove-Item Function: | ||
+ | Fläche 10 10 | ||
+ | |||
+ | # Nachteile Funktion ' | ||
+ | # Keine Parameter-Prüfung | ||
+ | # Keine Interaktion mit Get-Help | ||
+ | # Keine Interaktion Pipline-Verarbeitung | ||
+ | |||
+ | # LÖSUNG: die Funktion als CmdLet ausbauen, | ||
+ | # möglich könnte sein: | ||
+ | |||
+ | Get-Help Get-Fläche -ShowWindow | ||
+ | Get-Fläche -Breit 10 -Länge 15.5 | ||
+ | Get-Fläche 10 15.5 | ||
+ | Get-Fläche 10 15.5 | Out-GridView | ||
+ | " | ||
+ | Get-Fläche 10 # Fehler | ||
+ | Get-Fläche -10 15.5 # Fehler | ||
+ | Get-Fläche 101 101 # Fehler | ||
+ | Get-Fläche zehn zwölf # Fehler | ||
+ | |||
+ | # | ||
+ | # Umsetzung: | ||
+ | # Wichtig: in einer eigenständigen *.ps1 entwickeln um mit F5 den Funktionsspeicher zu aktualisieren | ||
+ | # | ||
+ | |||
+ | function Get-Fläche | ||
+ | { | ||
+ | <# | ||
+ | .Synopsis | ||
+ | Flächenberechnung | ||
+ | |||
+ | .DESCRIPTION | ||
+ | Berechnet die Fläche aus Breit und Länge. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Fläche -Breit 10 -Länge 15.5 | ||
+ | Berechnet die Fläche aus Breit 10 mal Länge 15,5 | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Help Get-Fläche -Full | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Fläche -Breit 10 -Länge 15.5 | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Help Get-Fläche -Full | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Fläche 10 15.5 -Verbose | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-Fläche 10 15.5 | Out-GridView | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | #> | ||
+ | |||
+ | [CmdletBinding()] | ||
+ | [Alias(' | ||
+ | [OutputType([PSObject])] | ||
+ | Param | ||
+ | ( | ||
+ | # Breite der Fläche | ||
+ | [Parameter(ParameterSetName = ' | ||
+ | | ||
+ | | ||
+ | [ValidateRange(0.1, | ||
+ | [double]$Breite = 1, | ||
+ | |||
+ | # Länge der Fläche | ||
+ | [Parameter(ParameterSetName = ' | ||
+ | | ||
+ | | ||
+ | [ValidateRange(0.1, | ||
+ | [double]$Länge = 1, | ||
+ | |||
+ | [Parameter(ParameterSetName | ||
+ | | ||
+ | | ||
+ | [ValidatePattern(' | ||
+ | [string]$InputObject = [string]:: | ||
+ | ) | ||
+ | |||
+ | Begin | ||
+ | { | ||
+ | Write-Verbose -Message " | ||
+ | } | ||
+ | |||
+ | Process | ||
+ | { | ||
+ | if($PSCmdLet.ParameterSetName -eq ' | ||
+ | { | ||
+ | $splits = $InputObject.Split(' | ||
+ | $Breite = [double]$splits[0] | ||
+ | $Länge | ||
+ | } | ||
+ | |||
+ | $definition = ' | ||
+ | $fläche = $Breite * $Länge | ||
+ | $result = New-Object -TypeName PSObject -Property ([ordered]@{Definition=$definition; | ||
+ | return $result | ||
+ | } | ||
+ | |||
+ | End | ||
+ | { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | # | ||
+ | # Weitere Beispiele siehe ' | ||
+ | # | ||
+ | |||
+ | #endregion | ||
+ | #region Benutzer-Interaktion (Einfach UI) | ||
+ | |||
+ | # | ||
+ | # Read-Host | ||
+ | # - Ließt die Eingabe über die Tastatur bis zu einem ' | ||
+ | # - Rückgabe ist immer ein ' | ||
+ | # | ||
+ | |||
+ | Read-Host -Prompt " | ||
+ | # i.d.R. in eine Variable speichern oder über die | weiter geben | ||
+ | $userInput = Read-Host -Prompt " | ||
+ | |||
+ | # | ||
+ | # Einmal Perfekt: | ||
+ | # | ||
+ | |||
+ | $deDE = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList ' | ||
+ | $userInput = Read-Host -Prompt " | ||
+ | [decimal]$betrag = $userInput.ToDecimal($deDE) | ||
+ | $betrag | ||
+ | $betrag.GetType() | ||
+ | [decimal]1000 - $betrag | ||
+ | |||
+ | # z.B. auch bei einem Datum: | ||
+ | $userInput = Read-Host -Prompt " | ||
+ | [datetime]$datum = $userInput.ToDateTime($deDE) | ||
+ | $datum | ||
+ | |||
+ | # | ||
+ | # Nicht so gut ist: | ||
+ | # | ||
+ | |||
+ | # Keinen Einfluss auf die Konvertierung, | ||
+ | [decimal]$eingabe = Read-Host -Prompt " | ||
+ | |||
+ | # Eine falsche Zuweisung ist später immer noch möglich | ||
+ | $eingabe = [decimal](Read-Host -Prompt " | ||
+ | $eingabe = Get-Process | ||
+ | |||
+ | # | ||
+ | # Out-GridView | ||
+ | # | ||
+ | |||
+ | $processes = Get-Process -IncludeUserName | ? UserName -Match ' | ||
+ | $killMe = $processes | Out-GridView -Title ' | ||
+ | $killMe | Stop-Process -Force -WhatIf | ||
+ | |||
+ | # Als Einzeiler | ||
+ | Get-Process -IncludeUserName | | ||
+ | ? UserName -Match ' | ||
+ | Out-GridView -Title ' | ||
+ | Stop-Process -Force -WhatIf | ||
+ | # | ||
+ | # Weitere Beispiele für Out-GridView und Interaktion mit einem User | ||
+ | # | ||
+ | |||
+ | $betrag = 10, 25, 50, 100, 250 | Out-GridView -OutputMode Single | ||
+ | |||
+ | $antwort = "JA, Dateien archivieren", | ||
+ | $antwort.StartsWith(' | ||
+ | |||
+ | # | ||
+ | # ' | ||
+ | # | ||
+ | |||
+ | [System.Windows.Forms.MessageBox]:: | ||
+ | |||
+ | $title | ||
+ | $message | ||
+ | $buttons | ||
+ | $icon = [System.Windows.Forms.MessageBoxIcon]:: | ||
+ | $defaultButton = [System.Windows.Forms.MessageBoxDefaultButton]:: | ||
+ | $antwort | ||
+ | if($antwort -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | "OK, die Dateien werden archiviert..." | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region Debug- und Ausnahme-Management | ||
+ | |||
+ | <# | ||
+ | Errors sind OUT Exceptions sind IN | ||
+ | |||
+ | Reagieren auf Ex. per " | ||
+ | |||
+ | WICHTIG: Ex. nur behandeln wenn eine Lösung vorhanden ist (Meldungen sind keine Lösungen) | ||
+ | #> | ||
+ | |||
+ | $ErrorActionPreference = [System.Management.Automation.ActionPreference]:: | ||
+ | $WarningPreference | ||
+ | $VerbosePreference | ||
+ | $InformationPreference = [System.Management.Automation.ActionPreference]:: | ||
+ | $DebugPreference | ||
+ | $ConfirmPreference | ||
+ | |||
+ | # | ||
+ | # 1. Ausnahme analysieren (d.h. Ausnahme reproduzieren) | ||
+ | # | ||
+ | |||
+ | 1/0 # Div durch 0 | ||
+ | $error.Count | ||
+ | $error[0] # Die letzte Ausnahme | ||
+ | $error[0] -is [System.Management.Automation.RuntimeException] | ||
+ | $error[0] -is [System.Management.Automation.ErrorRecord] | ||
+ | $error[0].Exception -is [Exception] | ||
+ | |||
+ | # 1. Ebene | ||
+ | $error[0].Exception | fl * -Force | ||
+ | $error[0].Exception.Message | ||
+ | $error[0].Exception.GetType() | ||
+ | $error[0].Exception.StackTrace | ||
+ | $error[0].Exception.InnerException -eq $null | ||
+ | |||
+ | # 2. Ebene | ||
+ | $error[0].Exception.InnerException | fl * -Force | ||
+ | $error[0].Exception.InnerException.Message | ||
+ | $error[0].Exception.InnerException.GetType() | ||
+ | $error[0].Exception.InnerException.StackTrace | ||
+ | $error[0].Exception.InnerException.InnerException -eq $null | ||
+ | |||
+ | # Wenn ' | ||
+ | |||
+ | |||
+ | # TRAP | ||
+ | # Muss vor der Ex aufgestellt werden | ||
+ | |||
+ | trap # Alle | ||
+ | { | ||
+ | } | ||
+ | # Code mit Fehler | ||
+ | |||
+ | trap [DivideByZeroException] | ||
+ | { | ||
+ | # Was soll bei Ex passieren: | ||
+ | " | ||
+ | | ||
+ | # | ||
+ | #exit | ||
+ | } | ||
+ | |||
+ | $Erg = (100 / 0) | ||
+ | echo $Erg | ||
+ | Write-Output " | ||
+ | |||
+ | # | ||
+ | # TRY-CATCH-Block | ||
+ | # WICHTIG Nur nutzen wenn eine LÖSUNG vorhanden ist! | ||
+ | # MsgBox SIND KEINE LÖSUNG!!!! | ||
+ | # | ||
+ | |||
+ | try | ||
+ | { | ||
+ | # Codezeil(en) die evtl. eine Ex. auslösen | ||
+ | $xmlFile = " | ||
+ | $xmlDokument = New-Object -TypeName xml | ||
+ | $xmlDokument.Load($xmlFile) | ||
+ | Write-Host "Alles OK!" # Die letzte Zeile wird nur erreicht wenn keine Ex aufgetreten ist! | ||
+ | } | ||
+ | catch [System.Net.WebException] | ||
+ | { | ||
+ | # Code für WebException | ||
+ | } | ||
+ | catch # Dieser Catch-Block fängt ALLE Ex ab (ideal für Ex-Analyse, Protokollieren) | ||
+ | { | ||
+ | # Die Lösung: In eine Datei loggen... | ||
+ | $_.Exception.GetType() | ||
+ | $_.Exception.InnerException.GetType() | ||
+ | $_.Exception.InnerException.Message | ||
+ | #throw # Ex erneut werfen | ||
+ | } | ||
+ | |||
+ | # Eigene Ex werfen | ||
+ | Write-Error -Message " | ||
+ | |||
+ | |||
+ | # | ||
+ | # DEBUGGING | ||
+ | # | ||
+ | # 1. Nur *.ps1-Dateien können vom DEBUG profitieren | ||
+ | # 2. *.ps1-Datei muss vorher gespeichert sein | ||
+ | # | ||
+ | # F9 => Haltepunkt setzen | ||
+ | # F5 => Debugger wird gestartet | ||
+ | # Bleibt beim ersten HP stehen | ||
+ | # F11 => Führt die nächste Code-Zeile aus (gelbe Zeile wurde NOCH NICHT ausgeführt) | ||
+ | # s. ToolTip Variablen | ||
+ | # SHIFT + F5 = DEBUG beenden | ||
+ | # | ||
+ | |||
+ | Get-Command -Noun PSBreakPoint -Module Microsoft.PowerShell.* | ||
+ | |||
+ | Write-Debug | ||
+ | Write-Verbose -Message " | ||
+ | Write-Warning -Message " | ||
+ | |||
+ | # | ||
+ | # Analyse zwischen CmdLets | ||
+ | # | ||
+ | |||
+ | Trace-Command ParameterBinding | ||
+ | |||
+ | #endregion | ||
+ | #region PowerShell-Dateiendungen | ||
+ | |||
+ | # *.ps1 = Windows PowerShell Shell-Skript Version 1.0 -Datei (Beachte Ausführungsrichtlinien) | ||
+ | |||
+ | # *.ps1xml = Windows PowerShell Format- und Typdefinitionen -Datei, z.B.: | ||
+ | gci C: | ||
+ | . C: | ||
+ | |||
+ | # *.psc1 = Windows PowerShell Console -Datei | ||
+ | Export-Console -Path c: | ||
+ | powershell.exe -PSConsoleFile c: | ||
+ | |||
+ | # *.psd1 = Windows PowerShell Modul-Manifest -Datei | ||
+ | # *.psm1 = Windows PowerShell Modul -Datei (Beachte Ausführungsrichtlinien) | ||
+ | # psd1 definiert die Eckdaten eines Modules und psdm1 den Inhalt des Modules, z.B. siehe: | ||
+ | gci C: | ||
+ | |||
+ | #endregion | ||
+ | #region Ausführungsrichtlinien für Script-Dateien (*.ps1, *.psm1) | ||
+ | |||
+ | # In das Thema einlesen | ||
+ | Get-Help about_Execution_Ploicys -ShowWindow | ||
+ | Get-Help about_Signing | ||
+ | |||
+ | # Default Restricted | ||
+ | Get-ExecutionPolicy | ||
+ | |||
+ | # Für Test-/ | ||
+ | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned | ||
+ | |||
+ | # Produktivsysteme (Alle *.ps1-Dateien müssen signiert werden) | ||
+ | Set-ExecutionPolicy -ExecutionPolicy AllSigned | ||
+ | |||
+ | # Einstellung bleiben dauerhaft erhalten | ||
+ | # Einstellung kann auch per GPO vergenommen werden | ||
+ | # Einstellung kann nur mit Admin-Rechten vorgenommen werden | ||
+ | |||
+ | Set-ExecutionPolicy -ExecutionPolicy Unrestricted | ||
+ | Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process | ||
+ | Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser | ||
+ | |||
+ | # | ||
+ | # Möglichkeiten *.ps1-Datei auszuführen: | ||
+ | # | ||
+ | |||
+ | # - GPO | ||
+ | # - Aufruf in der Console, z.B. . " | ||
+ | # - Per Rechtsklick / Mit PowerShell ausführen | ||
+ | # - Per Verknüpfung auf => powershell.exe -File " | ||
+ | # powershell.exe -File " | ||
+ | # - Per MyPSScript.exe => z.B. über das Tool PowerGui oder VisualStudio und C# | ||
+ | # - Aufruf der *.ps1-Datei in einer der möglichen Autostart-Dateien | ||
+ | # - Aufgabenplanung, | ||
+ | |||
+ | #endregion | ||
+ | #region Auto-Start-Script-Dateien | ||
+ | |||
+ | # Default-Dateien | ||
+ | |||
+ | # WICHTIG: Ordner und Dateien evtl. erstellen | ||
+ | |||
+ | # Auswirkung für: LocalMachine | ||
+ | $env: | ||
+ | $env: | ||
+ | $env: | ||
+ | |||
+ | # Auswirkung für: CurrentUser | ||
+ | $env: | ||
+ | $env: | ||
+ | $env: | ||
+ | |||
+ | # z.B. das ständige Ausführen einer *.ps1-Datei | ||
+ | Add-Content -Force ` | ||
+ | -Path " | ||
+ | -Value ". "" | ||
+ | |||
+ | #endregion | ||
+ | #region Dynamischer Aufruf von *.ps1-Dateien | ||
+ | |||
+ | # Test immer in einer ps1-Datei in der Console, nicht in der ISE | ||
+ | |||
+ | $aktuellerPfad = $MyInvocation.MyCommand.Definition | ||
+ | $aktuellerPfad # C: | ||
+ | |||
+ | $aktuellerOrdner = Split-Path -Path $aktuellerPfad -Parent | ||
+ | $aktuellerOrdner # C:\Temp | ||
+ | |||
+ | $pfadNeu = Join-Path -Path $aktuellerOrdner -ChildPath " | ||
+ | $pfadNeu # C: | ||
+ | . $pfadNeu | ||
+ | |||
+ | #endregion | ||
+ | #region Ein- / Ausgabe-Parameter von " | ||
+ | |||
+ | # -> Einfach einen Param-Block einfügen (siehe Function) | ||
+ | |||
+ | #endregion | ||
+ | #region Scripte (*.ps*1) signieren | ||
+ | |||
+ | # | ||
+ | # 0. VORBEREITUNG | ||
+ | # | ||
+ | |||
+ | Set-Location C:\Temp | ||
+ | Copy-Item -Path " | ||
+ | Test-Path -Path .\Get-EuroExchange.ps1 | ||
+ | Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser -Force | ||
+ | Get-ExecutionPolicy -List # Check? | ||
+ | $CAName | ||
+ | $PSDeveloperName = " | ||
+ | $PS1Name | ||
+ | |||
+ | # WARUM? | ||
+ | # a) Schutz gegen Manipulation von PS-Scriptdateien (ps1, psm1, ps1xml, ...) | ||
+ | # b) Ausführungsrichtlien auf " | ||
+ | # 1. o.a. Dateien X.509 signiert sind. | ||
+ | # 2. o.a. X.509 von einer " | ||
+ | # 3. o.a. X.509 im Zertifikatspeicher für " | ||
+ | |||
+ | # Problem ... | ||
+ | & " | ||
+ | #Lösung ... Lösung => Signieren! | ||
+ | |||
+ | |||
+ | # 1. Vielleicht besitzen Sie schon so ein x.509 Zertifikat mit Verwendungszweck " | ||
+ | Get-ChildItem -Path Cert: | ||
+ | # ... Wenn vorhanden dan weiter mit Punkt 5. | ||
+ | |||
+ | |||
+ | # 2. ROOT-CA erstellen | ||
+ | .\MakeCert.exe -n " | ||
+ | gci .\ | ? Extension -IN ' | ||
+ | . " | ||
+ | |||
+ | # 3. Öffentlich Root-CA verteilen (z.B. über GPO) in den Speicher für vertrauenswürdige Stammzertifizierungsstellen (Root) | ||
+ | $CACert = Import-Certificate -FilePath " | ||
+ | gci Cert:\ -Recurse | ? Thumbprint -EQ $CACert.Thumbprint | ||
+ | . " | ||
+ | |||
+ | # 4. Signierungszertifikate pro Benutzer in " | ||
+ | .\MakeCert.exe -n " | ||
+ | $PSDeveloperCert = gci Cert: | ||
+ | gci Cert: | ||
+ | . " | ||
+ | |||
+ | # 5. Jetzt Können *.ps1-Dateien signiert werden | ||
+ | Set-AuthenticodeSignature -FilePath " | ||
+ | . " | ||
+ | |||
+ | # 6. OPTIONAL Das öffentliche Benutzer-Zertifikat von 3. muss z.B. per GPO auf alle betroffenen Host's verteillt | ||
+ | Import-Certificate -FilePath " | ||
+ | gci Cert: | ||
+ | . " | ||
+ | |||
+ | # 7. Kontrollieren (Mit / Ohne eine Änderung an der signierten Datei) | ||
+ | Get-Content " | ||
+ | Get-AuthenticodeSignature -FilePath " | ||
+ | Start-Process -FilePath " | ||
+ | Get-AuthenticodeSignature -FilePath " | ||
+ | . " | ||
+ | |||
+ | # 8. Empfohlene Einstellung für den Entwicklungs-Rechner | ||
+ | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force | ||
+ | |||
+ | # -------------------------------------------------------- AUFRÄUMEN --------------------------------------------- | ||
+ | |||
+ | gci Cert: | ||
+ | gci Cert: | ||
+ | gci Cert: | ||
+ | gci C: | ||
+ | Set-ExecutionPolicy -ExecutionPolicy Bypass -Force -Scope CurrentUser | ||
+ | |||
+ | #endregion | ||
+ | #region eigene Module erstellen (Module) | ||
+ | |||
+ | Get-Help about_modules -ShowWindow | ||
+ | |||
+ | # | ||
+ | # 0. Vorbereitung | ||
+ | # | ||
+ | |||
+ | $moduleName | ||
+ | $moduleGuid | ||
+ | $destinationModulePath = " | ||
+ | |||
+ | # | ||
+ | # 1. Modul-Ordner erstellen | ||
+ | # | ||
+ | |||
+ | $destinationModulePath = Join-Path -Path $destinationModulePath -ChildPath $moduleName | ||
+ | New-Item -Path $destinationModulePath -ItemType Directory -Force | ||
+ | Set-Location -Path $destinationModulePath | ||
+ | |||
+ | # | ||
+ | # 2. PSM1-Datei erstellen (Diese Datei wird ausgeführt, | ||
+ | # | ||
+ | |||
+ | New-Item -Path .\$moduleName.psm1 -ItemType File -Force | ||
+ | Get-Content -Path ' | ||
+ | Get-Content -Path ' | ||
+ | Get-Content -Path ' | ||
+ | " | ||
+ | |||
+ | # | ||
+ | # 3. PSD1-Datei erstellen (Manifest-Informationen über unser Module) | ||
+ | # | ||
+ | |||
+ | New-ModuleManifest -Path .\$moduleName.psd1 ` | ||
+ | | ||
+ | -Guid $moduleGuid ` | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | # Bzgl. ModuleVersion: | ||
+ | Start-Process -FilePath .\$moduleName.psd1 | ||
+ | |||
+ | # | ||
+ | # 4. Check! | ||
+ | # | ||
+ | |||
+ | Get-ChildItem -Path . -Force -Recurse | ||
+ | Start-Process -FilePath .\$moduleName.psd1 | ||
+ | Start-Process -FilePath .\$moduleName.psm1 | ||
+ | |||
+ | Get-ExecutionPolicy -List # Process, CurrentUser, | ||
+ | Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force | ||
+ | |||
+ | Get-Module -Name GFU -ListAvailable | ||
+ | Import-Module -Name GFU # Fehlerfrei? | ||
+ | Get-Module -Name GFU # Vorhanden ? | ||
+ | Remove-Module -Name GFU # Fehlerfrei ? | ||
+ | Get-Module -Name GFU # Nicht Vorhanden ? | ||
+ | gee -Currency USD # Fehlerfrei ? | ||
+ | Get-Module -Name GFU # Vorhanden ? | ||
+ | |||
+ | # | ||
+ | # siehe auch | ||
+ | # | ||
+ | |||
+ | Show-Command | ||
+ | |||
+ | Get-Command *module* -Module PowerShellGet | ||
+ | Publish-Module # => PowerShellGallery | ||
+ | |||
+ | #endregion | ||
+ | #region UI (ohne G und nur mit PowerShell) | ||
+ | |||
+ | # Siehe Thema " | ||
+ | |||
+ | $eingabe = Read-Host -Prompt "Bitte Datum eingeben" | ||
+ | $eingabe | Get-Member # System.String | ||
+ | $eingabe | ||
+ | |||
+ | |||
+ | " | ||
+ | |||
+ | |||
+ | Show-Command -Name Get-EuroExchange -NoCommonParameter -ErrorPopup | Out-GridView | ||
+ | |||
+ | |||
+ | 1..100 | % {Start-Sleep -Milliseconds 200 ; Write-Progress -Activity "Bitte warten" | ||
+ | |||
+ | |||
+ | $title | ||
+ | $message = "Do you want to delete the remaining files in the folder?" | ||
+ | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "& | ||
+ | $no = New-Object System.Management.Automation.Host.ChoiceDescription "& | ||
+ | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, | ||
+ | $result | ||
+ | switch ($result) | ||
+ | { | ||
+ | 0 {"You selected Yes."} | ||
+ | 1 {"You selected No."} | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region .NET-Code direkt nutzen | ||
+ | |||
+ | # Siehe auch Tipps und Tricks | ||
+ | |||
+ | # | ||
+ | # z.B. .NET Framework (eine Art Library) nutzen | ||
+ | # | ||
+ | |||
+ | [System.Reflection.Assembly]:: | ||
+ | |||
+ | $sw = New-Object -TypeName System.Diagnostics.Stopwatch # " | ||
+ | $sw.Start() | ||
+ | [System.Threading.Thread]:: | ||
+ | $sw.Stop() | ||
+ | $sw | ||
+ | |||
+ | |||
+ | # | ||
+ | # z.B. .NET nutzen => OOP (C# oder VisualBasic) | ||
+ | # | ||
+ | |||
+ | $source = @" | ||
+ | public class Rechner | ||
+ | { | ||
+ | public static int Addiere(int a, int b) | ||
+ | { | ||
+ | return (a + b); | ||
+ | } | ||
+ | |||
+ | public int Multipliziere(int a, int b) | ||
+ | { | ||
+ | return (a * b); | ||
+ | } | ||
+ | } | ||
+ | "@ | ||
+ | |||
+ | Add-Type -TypeDefinition $source -Language CSharp # ACHTUNG bis PS5.0 war die Klasse Rechner unveränderbar | ||
+ | |||
+ | [Rechner]:: | ||
+ | |||
+ | $obj = New-Object -TypeName Rechner | ||
+ | $obj.Multipliziere(10, | ||
+ | |||
+ | # | ||
+ | # AB PowerShell 5.0 auch so: | ||
+ | # | ||
+ | |||
+ | enum Color | ||
+ | { | ||
+ | Blue | ||
+ | Green | ||
+ | Red | ||
+ | } | ||
+ | $myColor = [Color]:: | ||
+ | $myColor | ||
+ | |||
+ | class Car | ||
+ | { | ||
+ | [Color]$Color | ||
+ | [int]$HP | ||
+ | } | ||
+ | |||
+ | $myCar = New-Object -TypeName Car | ||
+ | |||
+ | $myCar.Color = [Color]:: | ||
+ | $myCar.HP = 100 | ||
+ | $myCar | Get-Member | ||
+ | |||
+ | Get-Help -Name about_Class -ShowWindow | ||
+ | |||
+ | #endregion | ||
+ | #region GUI | ||
+ | |||
+ | # Siehe auch TIPPS, TRICKS und BEISPIELE | ||
+ | |||
+ | #region GUI ALT (WinForms) nach dem Namespace System.Windows.Forms | ||
+ | |||
+ | $url = " | ||
+ | $xml = [xml](Invoke-WebRequest -Uri $url | select -exp Content) | ||
+ | $cubes = $xml.Envelope.Cube.Cube.Cube | ||
+ | $currencys = $cubes | sort currency | select -exp currency | ||
+ | |||
+ | function EuroRateRechnen() | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | $aktWährung = $währungComboBox.SelectedItem | ||
+ | [decimal]$rate = $cubes | ? currency -eq $aktWährung | select -exp rate | ||
+ | $euro = $euroTextBox.Text | ||
+ | $ergebnis = $rate * $euro | ||
+ | } | ||
+ | catch | ||
+ | { | ||
+ | $rate = 0 | ||
+ | $ergebnis = 0 | ||
+ | } | ||
+ | |||
+ | $eregbnisTextBox.Text = $ergebnis | ||
+ | $rateTextBox.Text = $rate | ||
+ | } | ||
+ | |||
+ | $währungLabel = New-Object -TypeName System.Windows.Forms.Label | ||
+ | $währungLabel.Text = "& | ||
+ | $währungLabel.Top | ||
+ | $währungLabel.Left = 15 | ||
+ | |||
+ | |||
+ | $währungComboBox = New-Object -TypeName System.Windows.Forms.ComboBox | ||
+ | $währungComboBox.Top | ||
+ | $währungComboBox.Left | ||
+ | $währungComboBox.AutoCompleteSource = [System.Windows.Forms.AutoCompleteSource]:: | ||
+ | $währungComboBox.AutoCompleteMode | ||
+ | $währungComboBox.Items.AddRange($currencys) | ||
+ | $währungComboBox.Add_TextChanged({EuroRateRechnen}) | ||
+ | $währungComboBox.SelectedIndex | ||
+ | |||
+ | $rateLabel = New-Object -TypeName System.Windows.Forms.Label | ||
+ | $rateLabel.Text = "& | ||
+ | $rateLabel.Top | ||
+ | $rateLabel.Left = 15 | ||
+ | |||
+ | $rateTextBox = New-Object -TypeName System.Windows.Forms.TextBox | ||
+ | $rateTextBox.TextAlign = [System.Windows.Forms.HorizontalAlignment]:: | ||
+ | $rateTextBox.ReadOnly | ||
+ | $rateTextBox.Top | ||
+ | $rateTextBox.Left | ||
+ | $rateTextBox.Text | ||
+ | |||
+ | $euroLabel = New-Object -TypeName System.Windows.Forms.Label | ||
+ | $euroLabel.Text = "& | ||
+ | $euroLabel.Top | ||
+ | $euroLabel.Left = 15 | ||
+ | |||
+ | $euroTextBox = New-Object -TypeName System.Windows.Forms.TextBox | ||
+ | $euroTextBox.TextAlign = [System.Windows.Forms.HorizontalAlignment]:: | ||
+ | $euroTextBox.Top | ||
+ | $euroTextBox.Left | ||
+ | $euroTextBox.Add_TextChanged({EuroRateRechnen}) | ||
+ | |||
+ | $ergebnisLabel = New-Object -TypeName System.Windows.Forms.Label | ||
+ | $ergebnisLabel.Text = "& | ||
+ | $ergebnisLabel.Top | ||
+ | $ergebnisLabel.Left = 15 | ||
+ | |||
+ | $eregbnisTextBox = New-Object -TypeName System.Windows.Forms.TextBox | ||
+ | $eregbnisTextBox.TextAlign = [System.Windows.Forms.HorizontalAlignment]:: | ||
+ | $eregbnisTextBox.ReadOnly | ||
+ | $eregbnisTextBox.Top | ||
+ | $eregbnisTextBox.Left | ||
+ | |||
+ | $HauptForm = New-Object -TypeName System.Windows.Forms.Form | ||
+ | $HauptForm.Text | ||
+ | $HauptForm.StartPosition = [System.Windows.Forms.FormStartPosition]:: | ||
+ | $HauptForm.Height | ||
+ | $HauptForm.Controls.AddRange(( ` | ||
+ | $währungLabel, | ||
+ | $rateLabel, | ||
+ | $euroLabel, | ||
+ | $ergebnisLabel, | ||
+ | |||
+ | $euroTextBox.Text | ||
+ | $HauptForm.ShowDialog() | ||
+ | |||
+ | #endregion | ||
+ | #region GUI NEU (WPF) nach dem Namespace System.Presentation | ||
+ | $url = " | ||
+ | $xml = [xml](Invoke-WebRequest -Uri $url | select -exp Content) | ||
+ | $cubes = $xml.Envelope.Cube.Cube.Cube | ||
+ | $currencys = $cubes | sort currency | select -exp currency | ||
+ | |||
+ | function EuroRateRechnen() | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | $aktWährung | ||
+ | [decimal]$rate = $cubes | ? currency -eq $aktWährung | select -exp rate | ||
+ | $euro = $eurosCtrl.Text | ||
+ | $ergebnis | ||
+ | } | ||
+ | catch | ||
+ | { | ||
+ | $rate = 0 | ||
+ | $ergebnis = 0 | ||
+ | } | ||
+ | |||
+ | $RateCtrl.Text | ||
+ | $ErgebnisCtrl.Text = $ergebnis | ||
+ | } | ||
+ | |||
+ | Add-Type -AssemblyName PresentationFramework | ||
+ | Add-Type -AssemblyName System | ||
+ | |||
+ | [XML]$xaml = @" | ||
+ | <Window | ||
+ | xmlns=" | ||
+ | xmlns: | ||
+ | Title=" | ||
+ | Width=" | ||
+ | Height=" | ||
+ | WindowStartupLocation=" | ||
+ | <Grid Margin=" | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <TextBox x: | ||
+ | < | ||
+ | <TextBox x: | ||
+ | < | ||
+ | <TextBox x: | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | "@ | ||
+ | |||
+ | $reader = New-Object System.Xml.XmlNodeReader $xaml | ||
+ | $window = [Windows.Markup.XamlReader]:: | ||
+ | |||
+ | $WährungenCtrl = $window.FindName(' | ||
+ | $RateCtrl | ||
+ | $EurosCtrl | ||
+ | $ErgebnisCtrl | ||
+ | |||
+ | $currencys | % { $WährungenCtrl.Items.Add($_) | Out-Null } | ||
+ | $WährungenCtrl.Add_SelectionChanged({EuroRateRechnen}) | ||
+ | $WährungenCtrl.SelectedIndex = 0 | ||
+ | |||
+ | $EurosCtrl.Add_TextChanged({EuroRateRechnen}) | ||
+ | $EurosCtrl.Text = " | ||
+ | |||
+ | $window.ShowDialog() | ||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region ADS | ||
+ | |||
+ | #region AGENDA PowerShell für Active Directory-Administratoren | ||
+ | |||
+ | Start-Process " | ||
+ | |||
+ | # Grundlagen der PowerShell | ||
+ | # Was ist PowerShell? | ||
+ | # Parsing und PowerShell | ||
+ | # Pipelines und Befehle | ||
+ | # | ||
+ | # Active Directory Verwaltung mit der Powershell | ||
+ | # Verwaltung von Active Directory Objekten (OU, User, Computer, Group) | ||
+ | # Gruppenrichtlinien in der PowerShell | ||
+ | # Anlegen und Verwalten von Password Settings Objects | ||
+ | # Anlegen und Verwendung des Active Directory Papierkorbs | ||
+ | # Active Directory-Verwaltungscenter | ||
+ | # Verwaltung von Active Directory Standorten | ||
+ | # ADSI und die Powershell | ||
+ | # | ||
+ | # Arbeiten mit Typen, Operatoren und Ausdrücke | ||
+ | # Array-Operatoren | ||
+ | # Flusskontrolle und Funktionen | ||
+ | # .NET und WinForms | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region 1. ADS Forest aufsetzen | ||
+ | |||
+ | Add-WindowsFeature -Name AD-Domain-Services -IncludeAllSubFeature -IncludeManagementTools -LogPath C: | ||
+ | |||
+ | Import-Module ADDSDeployment | ||
+ | Install-ADDSForest -CreateDnsDelegation: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | #endregion | ||
+ | #region 2. AD & PS Vorbereitung | ||
+ | |||
+ | Update-Help -Module * -UICulture de-DE, en-US -Force | ||
+ | |||
+ | #evtl. dcpromo | ||
+ | |||
+ | $cred = Get-Credential | ||
+ | Add-Computer -DomainName " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Module | ||
+ | |||
+ | Get-Module -ListAvailable # Installiert Module? | ||
+ | Get-Module | ||
+ | |||
+ | Get-WindowsFeature RSAT* | ||
+ | Add-WindowsFeature -Name RSAT-AD-PowerShell, | ||
+ | |||
+ | # 1. Für Windows-Client RSAT-Packet (*.msu) installieren | ||
+ | # 3. Add-WindowsFeature -Name RSAT-AD-PowerShell | ||
+ | |||
+ | Get-Module -Name ActiveDirectory -ListAvailable | ||
+ | Import-Module -Name ActiveDirectory | ||
+ | Get-Module | ||
+ | Get-PSDrive -PSProvider ActiveDirectory # Grund für das manuelle Laden | ||
+ | Remove-Module -Name ActiveDirectory | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Active Directory-Objekte | ||
+ | |||
+ | Get-Command -Module ActiveDirectory | Out-GridView | ||
+ | |||
+ | New-ADOrganizationalUnit -Name " | ||
+ | |||
+ | Show-Command New-ADUser | ||
+ | New-ADUser -Name sauer2 -Path " | ||
+ | $ms = New-ADUser -Name mittelsauer -Path " | ||
+ | $ms | Get-Member | ||
+ | |||
+ | New-ADUser -Name sauer5 -Path " | ||
+ | |||
+ | # 1. Anmeldung Pwd ändern | ||
+ | # 2. Anmeldename fehlt | ||
+ | # 3. Job-Titel fehlt | ||
+ | |||
+ | New-ADUser -Name sauer6 -UserPrincipalName " | ||
+ | -ChangePasswordAtLogon $true ` | ||
+ | -Title " | ||
+ | -Path " | ||
+ | |||
+ | # | ||
+ | # Benutzer über CSV hinzufügen | ||
+ | # | ||
+ | |||
+ | $csv = @" | ||
+ | UserName; | ||
+ | Uwe; | ||
+ | Inge; | ||
+ | Horst; | ||
+ | "@ | ||
+ | Set-Content -Path c: | ||
+ | |||
+ | Import-Csv -Path C: | ||
+ | New-ADUser -Name $_.UserName ` | ||
+ | | ||
+ | -Path " | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | $FormatEnumerationLimit = -1 | ||
+ | |||
+ | Get-ADUser -Identity " | ||
+ | (Get-ADUser -Identity " | ||
+ | |||
+ | |||
+ | $Identity = " | ||
+ | $InitPassword = [System.IO.Path]:: | ||
+ | $bx = Get-ADUser -Identity $Identity | Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString $InitPassword -A -f) -PassThru | ||
+ | $bx | Set-ADUser -ChangePasswordAtLogon $true -AccountExpirationDate (Get-Date).AddMinutes(3) | ||
+ | |||
+ | function Reset-ADUserPassword | ||
+ | { | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | bla bla bla | ||
+ | |||
+ | .DESCRIPTION | ||
+ | hmmm hmmm hmm | ||
+ | |||
+ | .EXAMPLE | ||
+ | Reset-ADUserPassword -Identity " | ||
+ | bla bla bla | ||
+ | |||
+ | #> | ||
+ | param | ||
+ | ( | ||
+ | # Geben Sie ..... | ||
+ | [Parameter(Mandatory=$true)] | ||
+ | [string]$Identity | ||
+ | ) | ||
+ | $InitPassword = [System.IO.Path]:: | ||
+ | $bx = Get-ADUser -Identity $Identity | Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString $InitPassword -A -f) -PassThru | ||
+ | $bx | Set-ADUser -ChangePasswordAtLogon $true -AccountExpirationDate (Get-Date).AddMinutes(3) | ||
+ | [pscustomobject]@{" | ||
+ | } | ||
+ | |||
+ | Reset-ADUserPassword -Identity " | ||
+ | Show-Command Reset-ADUserPassword | ||
+ | |||
+ | # | ||
+ | # AD Gruppen | ||
+ | # | ||
+ | |||
+ | Get-ADGroup -Identity administratoren | ||
+ | |||
+ | $a = Get-ADGroup -Identity S-1-5-32-544 -Properties member | ||
+ | $a.member | Get-Member | ||
+ | $a.member[0] | ||
+ | $a.member | Get-ADObject | ||
+ | Get-ADGroup -Filter ' | ||
+ | Get-ADGroup -Server localhost | ||
+ | |||
+ | $zeroGrps = @() | ||
+ | $a = Get-ADGroup -Properties member -Filter * | ||
+ | foreach ($item in $a) | ||
+ | { | ||
+ | if($item.member.Count -eq 0) | ||
+ | { | ||
+ | $zeroGrps += $item | ||
+ | } | ||
+ | } | ||
+ | $filename = " | ||
+ | $zeroGrps | ConvertTo-Html -Property Name -PreContent "Leere AD-Gruppen vom $(Get-Date)" | ||
+ | |||
+ | # vs. | ||
+ | |||
+ | Get-ADGroup -Properties member -Filter * | | ||
+ | where {$_.member.Count -eq 0} | | ||
+ | ConvertTo-Html -Property Name -PreContent "Leere AD-Gruppen vom $(Get-Date)" | ||
+ | |||
+ | Get-ADUser -Identity Administrator | ||
+ | |||
+ | Get-Command -Name *group* -Module ActiveDirectory | ||
+ | |||
+ | # Wo ist der Administrator mitglied? | ||
+ | Get-ADPrincipalGroupMembership -Identity Administrator | ft Name | ||
+ | |||
+ | # Wo ist Wer mitglied? | ||
+ | Get-ADUser -Filter * | ForEach-Object { | ||
+ | $user = $_ | ||
+ | $_ | Get-ADPrincipalGroupMembership | ForEach-Object { | ||
+ | [pscustomobject]@{Username=$user.Name; | ||
+ | } | ||
+ | } | ConvertTo-Html | Out-File .\UsersGroups.html | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | Get-ADForest | ||
+ | [System.DirectoryServices.ActiveDirectory.Forest]:: | ||
+ | |||
+ | #region ADSI & LDAP | ||
+ | |||
+ | Start-Process http:// | ||
+ | |||
+ | $rootDSE = [ADSI]" | ||
+ | $adRootPath = $rootDSE.defaultNamingContext | ||
+ | $ad = [ADSI]" | ||
+ | |||
+ | $adComputer = [ADSI]' | ||
+ | $adComputer.Children | ||
+ | |||
+ | $User = [ADSI]" | ||
+ | $UAC = $User.UserAccountControl[0] -bor 65536 # Password never expire | ||
+ | $User.Put(" | ||
+ | $User.SetInfo() | ||
+ | |||
+ | |||
+ | $admin = [ADSI]" | ||
+ | $admin.class | ||
+ | $admin.objectclass | ||
+ | |||
+ | $admin = [ADSI]" | ||
+ | $groups = $admin.MemberOf | ForEach-Object {[ADSI]" | ||
+ | $groups | ||
+ | |||
+ | ([ADSI]' | ||
+ | ([ADSI]' | ||
+ | ([ADSI]' | ||
+ | |||
+ | $a=([ADSI]' | ||
+ | $a.UserFlags=2; | ||
+ | $a.CommitChanges() | ||
+ | |||
+ | $a=([ADSI]' | ||
+ | $a.UserFlags=512; | ||
+ | $a.CommitChanges() | ||
+ | |||
+ | Start-Process https:// | ||
+ | |||
+ | Get-ADObject -LDAPFilter " | ||
+ | Search-ADAccount -PasswordExpired -UsersOnly -SearchBase " | ||
+ | |||
+ | $adSearcher = New-Object -TypeName DirectoryServices.DirectorySearcher | ||
+ | $adSearcher.Filter = " | ||
+ | $adSearcher.SearchRoot = " | ||
+ | $result = $adSearcher.FindAll() | ||
+ | $result | Get-Member | ||
+ | $result | fl * | ||
+ | |||
+ | $ACCOUNTDISABLE | ||
+ | $DONT_EXPIRE_PASSWORD = 0x010000 | ||
+ | $PASSWORD_EXPIRED | ||
+ | $searcher = [adsisearcher]" | ||
+ | $searcher.FindAll() | ForEach-Object { | ||
+ | $user = [adsi]$_.Properties.adspath[0] | ||
+ | [PSCustomObject]@{ | ||
+ | SamAccountName | ||
+ | Name = $user.name[0] | ||
+ | Mail = $user.mail[0] | ||
+ | PasswordLastSet | ||
+ | Enabled | ||
+ | PasswordNeverExpires = [bool]($user.userAccountControl[0] -band $DONT_EXPIRE_PASSWORD) | ||
+ | PasswordExpired | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # | ||
+ | # ODER per ActiveDirectory-Module: | ||
+ | # | ||
+ | |||
+ | Import-Module ActiveDirectory | ||
+ | $attributes = ' | ||
+ | Get-ADUser -Filter * -Properties $attributes | select $attributes | ||
+ | |||
+ | #endregion | ||
+ | #region GPO | ||
+ | |||
+ | Import-Module GroupPolicy -Verbose | ||
+ | Get-Command -Module GroupPolicy | ||
+ | |||
+ | Backup-GPO | ||
+ | Restore-GPO | ||
+ | Get-GPO | ||
+ | Copy-GPO | ||
+ | New-GPO | ||
+ | Remove-GPO | ||
+ | Import-GPO | ||
+ | Rename-GPO | ||
+ | Get-GPInheritance | ||
+ | Get-GPOReport | ||
+ | Get-GPPermissions | ||
+ | Get-GPPrefRegistryValue | ||
+ | Get-GPRegistryValue | ||
+ | Get-GPResultantSetOfPolicy # Mit diesem Cmdlet kann man die Richtlinienergebnissatz-Informationen für einen Benutzer, einen Computer oder für beide in eine Datei im HTML- oder XML-Format ausgeben lassen. | ||
+ | Get-GPStarterGPO | ||
+ | New-GPLink | ||
+ | New-GPStarterGPO | ||
+ | Remove-GPLink | ||
+ | Remove-GPPrefRegistryValue # Eine oder mehrere Registrierungseinstellungen werden aus der Benutzerkonfiguration oder Computerkonfiguration innerhalb einer GPO mit diesem Cmdlet entfernt. | ||
+ | Remove-GPRegistryValue | ||
+ | Set-GPInheritance | ||
+ | Set-GPLink | ||
+ | Set-GPPermissions | ||
+ | Set-GPPrefRegistryValue | ||
+ | Set-GPRegistryValue | ||
+ | |||
+ | Get-GPO -Name " | ||
+ | Get-GPO -Name " | ||
+ | |||
+ | # Kennwort muss Komplexitätsvoraussetzungen entsprechen? | ||
+ | $xmlDoc = [xml](Get-GPO -Name " | ||
+ | $xmlDoc.GPO.Computer.ExtensionData.Extension.Account | ? Name -EQ PasswordComplexity | select -ExpandProperty SettingBoolean | ||
+ | |||
+ | # Oder nativ in den Richtlinien lesen | ||
+ | $gpo = Get-GPO -Name " | ||
+ | gci " | ||
+ | |||
+ | #endregion | ||
+ | #region Password Settings Objects | ||
+ | |||
+ | New-ADFineGrainedPasswordPolicy -Name " | ||
+ | Set-ADFineGrainedPasswordPolicy -Identity ‘DomainUsersPSO’ -Replace @{‘msDS-PSOAppliesTo’=’CN=PSOTest, | ||
+ | |||
+ | $allPSOUsers = Get-ADFineGrainedPasswordPolicySubject " | ||
+ | ? {$_.objectClass -eq " | ||
+ | % {Get-ADGroupMember $_.Name -Recursive} | | ||
+ | ? {$_.objectClass -eq " | ||
+ | | ||
+ | |||
+ | $allUsers = Get-AdUser -Filter * | ||
+ | |||
+ | $allUsersNotinPSO = Compare-Object -ReferenceObject $allUsers -DifferenceObject $allPSOUsers -PassThru | select Name | ||
+ | $allUsersNotinPSO | ||
+ | |||
+ | #endregion | ||
+ | #region Active Directory Papierkorbs | ||
+ | |||
+ | Get-Command -Noun ADOptionalFeature | ||
+ | |||
+ | Get-ADOptionalFeature -Filter * | ||
+ | |||
+ | Enable-ADOptionalFeature -Identity " | ||
+ | |||
+ | Get-ADObject -Filter {name -like " | ||
+ | Get-ADObject -Filter {name -like " | ||
+ | |||
+ | #endregion | ||
+ | #region Active Directory-Verwaltungscenter | ||
+ | |||
+ | # Siehe " | ||
+ | |||
+ | " | ||
+ | |||
+ | # siehe auch: https:// | ||
+ | |||
+ | #endregion | ||
+ | #region Active Directory Standorten | ||
+ | |||
+ | Get-Command " | ||
+ | |||
+ | New-ADReplicationSite -Name " | ||
+ | |||
+ | $Schedule = New-Object -TypeName System.DirectoryServices.ActiveDirectory.ActiveDirectorySchedule | ||
+ | $Schedule.ResetSchedule() | ||
+ | $Schedule.SetDailySchedule(" | ||
+ | New-ADReplicationSite -Name " | ||
+ | |||
+ | New-ADReplicationSiteLink -Name " | ||
+ | |||
+ | New-ADReplicationSubnet -Name " | ||
+ | New-ADReplicationSubnet -Name " | ||
+ | |||
+ | Get-ADReplicationSite -Filter * | ||
+ | Get-ADReplicationSiteLink -Filter * | ||
+ | Get-ADReplicationSubnet -Filter * | ||
+ | |||
+ | ## Alle DC-Server an einem Standort | ||
+ | $serverContainerDN = “CN=Servers, | ||
+ | Get-ADObject -SearchBase $serverContainerDN -SearchScope OneLevel -Filter " | ||
+ | |||
+ | # Get replication metadata for the attributes of a group | ||
+ | Get-ADReplicationAttributeMetadata -Object " | ||
+ | |||
+ | # Get filtered replication metadata for all groups | ||
+ | Get-ADObject -Filter ' | ||
+ | Get-ADReplicationAttributeMetadata -Server localhost | | ||
+ | Where-Object {$_.LastOriginatingChangeTime -like " | ||
+ | Format-Table object | ||
+ | |||
+ | Get-ADReplicationConnection -Filter * | ||
+ | |||
+ | Get-ADReplicationFailure -Target localhost | ||
+ | |||
+ | #endregion | ||
+ | #region Zeigt vereinfacht ob die Rechte-Vererbung aktiviert ist oder nicht: | ||
+ | |||
+ | $result = gci -Path ' | ||
+ | $acl = $_.FullName | Get-Acl | ||
+ | [PSCustomObject]@{ | ||
+ | IsInherited | ||
+ | Name = $_.Name; | ||
+ | FullName | ||
+ | DeleteMe | ||
+ | AccessToString = $acl.AccessToString; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $result | % { | ||
+ | if($_.IsInherited) | ||
+ | { | ||
+ | $parenPath = Split-Path -Path $_.FullName -Parent | ||
+ | $parent = $result | ? { $_.FullName -eq $parenPath -and $_.DeleteMe -eq $false} | ||
+ | if($parent.IsInherited) | ||
+ | { | ||
+ | $_.DeleteMe = $true | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $result | Out-GridView | ||
+ | $result | ? DeleteMe -EQ $false | Out-GridView | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Microsoft SQL Server | ||
+ | |||
+ | Set-Location -Path ' | ||
+ | Get-Service MSSQLSERVER, | ||
+ | |||
+ | Import-Module -Name SqlServer # früher SQLPS | ||
+ | Get-Command -Module SqlServer | ||
+ | |||
+ | Get-ChildItem SQLSERVER: | ||
+ | Invoke-Sqlcmd -Database AdventureWorks2014 -Query " | ||
+ | |||
+ | #endregion | ||
+ | #region TIPPS, TRICKS und BEISPIELE | ||
+ | |||
+ | #region BASICS: Datum & Zeit | ||
+ | #region Eine Dauer von einem Datum subtrahieren, | ||
+ | |||
+ | $dauer = New-TimeSpan -Days 100 -Hours 31 -Minutes 12 | ||
+ | $dauer | ||
+ | (Get-Date).Subtract($dauer) | ||
+ | |||
+ | #endregion | ||
+ | #endregion | ||
+ | #region PowerShell | ||
+ | #region Neuerungen der PowerShell 5.0 | ||
+ | |||
+ | # Alle Details zur 5.0 Version unter: | ||
+ | Get-Help about_Windows_PowerShell_5.0 -ShowWindow | ||
+ | Start-Process http:// | ||
+ | |||
+ | #region Get-ItemPropertyValue | ||
+ | |||
+ | #NEU: Get-ItemPropertyValue | ||
+ | #FRÜHER: | ||
+ | (Get-ItemProperty -Path HKLM: | ||
+ | #JETZT: | ||
+ | Get-ItemPropertyValue -Path HKLM: | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Einfache String-Operationen | ||
+ | "Hallo Welt" | ConvertFrom-String | ||
+ | "Hallo Welt" | ConvertFrom-String -Delimiter " | ||
+ | "Hallo Welt" | ConvertFrom-String -PropertyNames FirstWord, SecondWord | ||
+ | |||
+ | "Lee Holmes", | ||
+ | |||
+ | "Hallo Welt" | Format-Hex | ||
+ | #endregion | ||
+ | |||
+ | #region ZIP-Archive | ||
+ | |||
+ | # | ||
+ | #Test-Daten erzeugen | ||
+ | # | ||
+ | New-Item -Path C: | ||
+ | 1..1MB -join ";" | ||
+ | 1..1MB -join ";" | ||
+ | |||
+ | # | ||
+ | # Compress-Archive | ||
+ | # | ||
+ | " | ||
+ | Get-Help Compress-Archive -ShowWindow | ||
+ | |||
+ | # | ||
+ | # Expand-Archive | ||
+ | # | ||
+ | " | ||
+ | Get-Help Expand-Archive -Full | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Software-Installation | ||
+ | |||
+ | Set-ExecutionPolicy -ExecutionPolicy AllSigned | ||
+ | |||
+ | Get-Command -Module PowerShellGet, | ||
+ | |||
+ | Find-Package | Out-GridView | ||
+ | Install-Package -Name AKPT -Force | ||
+ | Get-Module -ListAvailable | ||
+ | Get-Command * -Module AKPT | ||
+ | Get-AKAbout | ||
+ | Uninstall-Package -Name AKPT | ||
+ | |||
+ | Register-PSRepository -Name " | ||
+ | Get-PSRepository | ||
+ | Unregister-PSRepository -Name " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Kryptographie | ||
+ | |||
+ | Get-Command -Module Microsoft.PowerShell.Security | ||
+ | |||
+ | $MyCertInf = @" | ||
+ | [Version] | ||
+ | Signature = " | ||
+ | |||
+ | [Strings] | ||
+ | szOID_ENHANCED_KEY_USAGE = " | ||
+ | szOID_DOCUMENT_ENCRYPTION = " | ||
+ | |||
+ | [NewRequest] | ||
+ | Subject = " | ||
+ | MachineKeySet = false | ||
+ | KeyLength = 2048 | ||
+ | KeySpec = AT_KEYEXCHANGE | ||
+ | HashAlgorithm = Sha1 | ||
+ | Exportable = true | ||
+ | RequestType = Cert | ||
+ | |||
+ | KeyUsage = " | ||
+ | ValidityPeriod = " | ||
+ | ValidityPeriodUnits = " | ||
+ | |||
+ | [Extensions] | ||
+ | 2.5.29.37=" | ||
+ | "@ | ||
+ | Set-Content -Path C: | ||
+ | CertReq -new C: | ||
+ | $cert = gci Cert: | ||
+ | |||
+ | $crypt = "Hallo Welt" | Protect-CmsMessage -To $cert | ||
+ | Unprotect-CmsMessage -Content $crypt -To $cert | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region OOP | ||
+ | |||
+ | Get-Help about_Classes -ShowWindow | ||
+ | |||
+ | enum Farbe | ||
+ | { | ||
+ | Blau | ||
+ | Grün | ||
+ | Rot | ||
+ | } | ||
+ | $meineFarbe = [Farbe]:: | ||
+ | $meineFarbe | ||
+ | |||
+ | class Auto | ||
+ | { | ||
+ | [Farbe]$Farbe | ||
+ | $PS | ||
+ | } | ||
+ | |||
+ | $meinAuto = New-Object -TypeName Auto | ||
+ | |||
+ | $meinAuto.Farbe = [Farbe]:: | ||
+ | $meinAuto.PS = 100 | ||
+ | $meinAuto | Get-Member | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Weitere neue CmdLetds | ||
+ | |||
+ | Set-Clipboard -Value "Hallo Köln!" | ||
+ | Get-Clipboard | ||
+ | |||
+ | Clear-RecycleBin -DriveLetter c: -Confirm: | ||
+ | |||
+ | New-TemporaryFile | ||
+ | |||
+ | New-Guid | ||
+ | |||
+ | # symbolischer Verknüpfungen | ||
+ | New-Item -ItemType SymbolicLink -Name MySymLinkDir -Target $pshome | ||
+ | |||
+ | # -Depth 2 | ||
+ | Get-ChildItem c:\ -Recurse -Depth 2 -Force | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region DataCenter Abstraction Layer (DAL) | ||
+ | |||
+ | <# | ||
+ | Mit dieser Technologie können Sie direkt auf bestimmte | ||
+ | Netzwerkkomponenten wie Switches und Router zugreifen. | ||
+ | |||
+ | Dazu muss die Hardware diese Technik aber auch unterstützen. | ||
+ | In diesem Bereich spielen vor allem | ||
+ | Cisco und Huawei eine wichtige Rolle. | ||
+ | #> | ||
+ | |||
+ | $Session = New-CimSession -ComputerName " | ||
+ | Get-NetworkSwitchFeature -CimSession $Session | ||
+ | |||
+ | <# | ||
+ | Name IsEnabled InstanceID PSComputerName | ||
+ | ---- --------- ---------- -------------- | ||
+ | SSH True Contoso: | ||
+ | Tacacs True Contoso: | ||
+ | BGP False Contoso: | ||
+ | VLAN True Contoso: | ||
+ | LACP True Contoso: | ||
+ | DHCP False Contoso: | ||
+ | LLDP True Contoso: | ||
+ | #> | ||
+ | |||
+ | Get-Help Get-NetworkSwitchFeature -Full | ||
+ | |||
+ | Get-Command -Module NetworkSwitchManager | Out-GridView | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Open Data Protocol | ||
+ | |||
+ | <# Das Open Data Protocol, kurz OData ist ein von Microsoft veröffentlichtes HTTP-basiertes Protokoll | ||
+ | für den Datenzugriff zwischen kompatiblen Softwaresystemen. Aufbauend auf älteren Protokollen wie | ||
+ | ODBC und JDBC kann OData u.a. innerhalb von Cloud-Diensten (Azure), MySQL, Java und Rails | ||
+ | | ||
+ | für den Datenaustausch zur Verfügung zu stellen. | ||
+ | #> | ||
+ | |||
+ | Export-ODataEndpointProxy -Uri ' | ||
+ | -MetadataUri ' | ||
+ | -AllowUnsecureConnection ` | ||
+ | -OutputModule C: | ||
+ | -ResourceNameMapping @{Products = ' | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #region Optimierte Unterstützung für' | ||
+ | |||
+ | <# | ||
+ | Weitere Neuerungen in der PowerShell betreffen die mit der | ||
+ | PowerShell 4.0 eingeführte Technologie Desired State Configuration (DSC). | ||
+ | |||
+ | Hauptsächlich gibt es neue Optionen um festzulegen auf wievielen Computern | ||
+ | gleichzeitig die Änderungen implementiert werden sollen. | ||
+ | | ||
+ | Mit dem Modul ' | ||
+ | ' | ||
+ | #> | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Escape characters, Delimiters and Quotes | ||
+ | |||
+ | http:// | ||
+ | |||
+ | "Hallo `n Köln!" | ||
+ | |||
+ | #endregion | ||
+ | #region Konsolen-Ein-/ | ||
+ | |||
+ | Start-Transcript -Path C: | ||
+ | Get-Process | Stop-Process -Force -WhatIf | ||
+ | Remove-Item c:\ -Recurse -Force -WhatIf | ||
+ | Stop-Transcript | ||
+ | Get-Content -Path C: | ||
+ | |||
+ | #endregion | ||
+ | #region Wartezeit visualisieren | ||
+ | for ($i = 1; $i -le 100; $i++) | ||
+ | { | ||
+ | [System.Threading.Thread]:: | ||
+ | Write-Progress -Activity "Bitte warten" | ||
+ | |||
+ | if($i -ge 20) | ||
+ | { | ||
+ | Write-Progress -Activity "Bitte warten" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region max. Anzeige von Enumerationen (-1 ohne Grenze, Default: 4) | ||
+ | Get-Command -Name ForEach-Object | select -First 1 | fl * # Siehe Eigenschaft: | ||
+ | $FormatEnumerationLimit = 4 | ||
+ | Get-Command -Name ForEach-Object | select -First 1 | fl * # Siehe Eigenschaft: | ||
+ | #endregion | ||
+ | #region PowerShell-Transaktion (*-Transaction) | ||
+ | |||
+ | Get-Command -Noun Transaction -Module Microsoft.PowerShell.* | ||
+ | |||
+ | # Gilt nur für CmdLets die den Parameter UseTransaction besitzen | ||
+ | Get-Help * -Parameter UseTransaction | ||
+ | |||
+ | # | ||
+ | # BEISPIELE | ||
+ | # | ||
+ | |||
+ | Set-Location -Path hkcu: | ||
+ | |||
+ | Start-Transaction | ||
+ | New-Item _ABC -UseTransaction | ||
+ | New-ItemProperty -Path _ABC -name Heute -value (Get-Date) -UseTransaction | ||
+ | Complete-Transaction | ||
+ | |||
+ | Get-ItemProperty -Path _ABC | ||
+ | Remove-Item -Path _ABC -Force | ||
+ | |||
+ | Start-Transaction | ||
+ | New-Item _ABC -UseTransaction | ||
+ | New-ItemProperty -Path _ABC -name Heute -value (Get-Date) -UseTransaction | ||
+ | Undo-Transaction | ||
+ | |||
+ | Get-ItemProperty -Path _ABC | ||
+ | |||
+ | #endregion | ||
+ | #region Job's | ||
+ | |||
+ | # Lang anhaltene Aufgaben in Jobs auslagern und Session schließen | ||
+ | |||
+ | Start-Job -Name MyJob -ScriptBlock {[System.Threading.Thread]:: | ||
+ | Get-Job | ||
+ | Receive-Job -Name MyJob | ||
+ | Stop-Job -Name MyJob | ||
+ | Wait-Job -Name MyJob | ||
+ | Remove-Job -Name MyJob | ||
+ | |||
+ | #endregion | ||
+ | #region ScriptBlock-Code in eine EXE kompelieren | ||
+ | |||
+ | Set-Location C:\temp | ||
+ | Remove-Item .\start.* -Force | ||
+ | $csharpCode = @" | ||
+ | using System; | ||
+ | using System.Diagnostics; | ||
+ | |||
+ | namespace WindowsFormsApplication1 | ||
+ | { | ||
+ | static class Program | ||
+ | { | ||
+ | [STAThread] | ||
+ | static void Main() | ||
+ | { | ||
+ | var filename = " | ||
+ | var parameter = " | ||
+ | Process.Start(filename, | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | "@ | ||
+ | Set-Content start.cs -Force -Value $csharpCode | ||
+ | C: | ||
+ | .\start.exe # Testen... | ||
+ | |||
+ | #endregion | ||
+ | #region Beep StarWars | ||
+ | |||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | [console]:: | ||
+ | |||
+ | #endregion | ||
+ | #region Die Anzahl von Gruppen-Elementen bestimmen | ||
+ | |||
+ | Get-ChildItem -Path C: | ||
+ | |||
+ | #endregion | ||
+ | #region Eine Anzahl an Sekunden warten | ||
+ | |||
+ | Start-Sleep -Seconds 3 | ||
+ | |||
+ | #endregion | ||
+ | #region Eine eindeutige Id erstellen | ||
+ | |||
+ | # z.B. für Dateinamen, Primärschlüssel, | ||
+ | |||
+ | New-Guid | select -ExpandProperty Guid | ||
+ | |||
+ | #endregion | ||
+ | #endregion | ||
+ | #region CmdLet Beispiele | ||
+ | #region CmdLet: Get-EuroExchangeRate | ||
+ | |||
+ | function Get-EuroExchangeRate | ||
+ | { | ||
+ | <# | ||
+ | .DESCRIPTION | ||
+ | Zeigt und rechnet Euros in Nicht-Euro-Währung um. | ||
+ | |||
+ | .PARAMETER Currency | ||
+ | Die Ziel-Währung in die Euro's umgerechnet werden soll | ||
+ | |||
+ | .PARAMETER Value | ||
+ | Der umzurechnende Euro-Betrag. | ||
+ | |||
+ | .PARAMETER ListCurrencys | ||
+ | Listet alle möglichen Nicht-Euro-Währungen auf. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-EuroExchangeRate -Currency usd | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-EuroExchangeRate -ListCurrencys | ||
+ | |||
+ | .NOTES | ||
+ | Folgende Aufrufe dürfen nicht laufen: | ||
+ | |||
+ | Get-EuroExchangeRate -ListCurrencys -Currency usd | ||
+ | #> | ||
+ | [CmdletBinding()] | ||
+ | Param | ||
+ | ([Parameter(Mandatory=$true, | ||
+ | | ||
+ | | ||
+ | | ||
+ | [string]$Currency, | ||
+ | [Parameter(Position=1, | ||
+ | | ||
+ | [PSDefaultValue(Help = ' | ||
+ | [int]$Value = 1, | ||
+ | |||
+ | [Parameter(Position=0, | ||
+ | | ||
+ | [Switch] | ||
+ | [bool]$ListCurrencys = $false | ||
+ | ) | ||
+ | Begin | ||
+ | { | ||
+ | [xml]$doc = New-Object Xml | ||
+ | $doc.Load(" | ||
+ | $cubes = $doc.Envelope.Cube.Cube.Cube | ||
+ | |||
+ | if($ListCurrencys) | ||
+ | { | ||
+ | return new-object PSObject -Property @{" | ||
+ | } | ||
+ | } | ||
+ | Process | ||
+ | { | ||
+ | if($ListCurrencys) | ||
+ | { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | if($cubes.currency -contains $Currency) | ||
+ | { | ||
+ | [decimal]$rate = ($cubes | where currency -eq $Currency).rate | ||
+ | | ||
+ | return new-object PSObject -Property @{ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Warning -Message "Das Währungssymbol ' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Get-News | ||
+ | |||
+ | function Get-News | ||
+ | { | ||
+ | <# | ||
+ | .Synopsis | ||
+ | Zeigt RSS-Feeds an. | ||
+ | |||
+ | .DESCRIPTION | ||
+ | Zeigt ATOM Version 1.0 RRS-Feeds aus dem Internet oder Dateisystem an. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri http:// | ||
+ | |||
+ | Liefert alle RSS-News-Feed von Golem.de. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri http:// | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri " | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri " | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri " | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-News -Uri " | ||
+ | #> | ||
+ | Param | ||
+ | ( | ||
+ | [Parameter( | ||
+ | Mandatory | ||
+ | ValueFromPipeLine = $true)] | ||
+ | [string] | ||
+ | $Uri, | ||
+ | | ||
+ | [uint32] | ||
+ | $First = [System.UInt32]:: | ||
+ | |||
+ | [switch] | ||
+ | [bool] | ||
+ | $OpenLinkInBrowser = $false | ||
+ | ) | ||
+ | |||
+ | Begin # Zum Beginn 1x | ||
+ | { | ||
+ | $enUS = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList " | ||
+ | $xmlDokument = New-Object -TypeName System.Xml.XmlDocument | ||
+ | } | ||
+ | Process # Je Objekt was über die Pip kommt | ||
+ | { | ||
+ | $FirstTemp = $First | ||
+ | $xmlDokument.Load($Uri) | ||
+ | foreach ($item in $xmlDokument.feed.entry) | ||
+ | { | ||
+ | if ($FirstTemp -gt 0) | ||
+ | { | ||
+ | $FirstTemp-- | ||
+ | $link = $item.link.href | ||
+ | if($OpenLinkInBrowser) | ||
+ | { | ||
+ | [System.Diagnostics.Process]:: | ||
+ | continue | ||
+ | } | ||
+ | |||
+ | $title | ||
+ | $published = [datetime]:: | ||
+ | $author | ||
+ | $summery | ||
+ | | ||
+ | $result = @{" | ||
+ | New-Object psobject -Property $result | Select-Object Titel, StandUTC, Autor, Link, Beschreibung | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | break | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | End # Zum Ende 1x | ||
+ | { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #endregion | ||
+ | #region Diagnose & Debugging | ||
+ | |||
+ | #region Die Dauer einer Ausführung messen | ||
+ | |||
+ | Measure-Command -Expression {gci C:\Users -File -Force -Recurse -ea SilentlyContinue} | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Windows PowerShell ISE | ||
+ | #region Eigene Snippets für die ISE erstellen (STRG + J) | ||
+ | |||
+ | New-Item -Path " | ||
+ | Set-Content -Path " | ||
+ | <?xml version=' | ||
+ | < | ||
+ | <Snippet Version=' | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | <Author /> | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | <Script Language=' | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | .DESCRIPTION | ||
+ | .PARAMETER < | ||
+ | .INPUTS | ||
+ | .OUTPUTS | ||
+ | .EXAMPLE | ||
+ | .LINK | ||
+ | #> | ||
+ | ]]></ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | "@ | ||
+ | |||
+ | # s. STRG + J | ||
+ | |||
+ | #endregion | ||
+ | #endregion | ||
+ | #region Windows | ||
+ | |||
+ | #region BitLocker-CmdLet' | ||
+ | |||
+ | Get-Command -Module BitLocker | ||
+ | |||
+ | #endregion | ||
+ | #region ADS | ||
+ | |||
+ | # Group Policy Cmdlets in Windows PowerShell | ||
+ | # https:// | ||
+ | |||
+ | # Managing Group Policy with PowerShell | ||
+ | # http:// | ||
+ | |||
+ | # Use PowerShell to Import Group Policy Objects | ||
+ | # http:// | ||
+ | |||
+ | # ADSI Scripting with Windows PowerShell | ||
+ | # http:// | ||
+ | # https:// | ||
+ | $objOU = [ADSI]" | ||
+ | $objGroup = $objOU.Create(" | ||
+ | $objGroup.Put(" | ||
+ | $objGroup.SetInfo() | ||
+ | |||
+ | # Active Directory Recycle Bin Step-by-Step Guide | ||
+ | # https:// | ||
+ | |||
+ | # PowerShell and Active Directory Recycle Bin | ||
+ | # http:// | ||
+ | # http:// | ||
+ | $oDomain = Get-ADDomain | ||
+ | $DeletedObjects = $oDomain.DeletedObjectsContainer | ||
+ | Restore-ADObject | ||
+ | |||
+ | # | ||
+ | # ActiveDirectory-Modul | ||
+ | # | ||
+ | |||
+ | Get-Module -ListAvailable ActiveDirectory | ||
+ | Start-Process ' | ||
+ | |||
+ | # z.B.: | ||
+ | |||
+ | Get-ADUser -Filter " | ||
+ | Get-ADUser -Filter " | ||
+ | Get-ADUser -Filter " | ||
+ | Get-ADUser -Filter " | ||
+ | Search-ADAccount -PasswordNeverExpires -UsersOnly | ||
+ | Get-ADUser -Filter " | ||
+ | Get-ADUser -Filter * -SearchBase " | ||
+ | Get-ADComputer -Filter "Name -like ' | ||
+ | |||
+ | Get-ADDomainController | ||
+ | |||
+ | #endregion | ||
+ | #region Ein MSI-Paket installieren | ||
+ | |||
+ | $msi = " | ||
+ | $produkte = Get-WmiObject -Class Win32_Product -List | ||
+ | " | ||
+ | $ergebnis = $produkte.Install($msi) | ||
+ | "... Installation fertig mit dem Ergebnis {0}" -f $ergebnis.ReturnValue | ||
+ | Get-WmiObject -Class Win32_Product | where Name -like " | ||
+ | # ReturnValue siehe http:// | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Get-Product | ||
+ | |||
+ | function Get-Product | ||
+ | { | ||
+ | <# | ||
+ | .Synopsis | ||
+ | | ||
+ | .DESCRIPTION | ||
+ | Lange Beschreibung | ||
+ | .EXAMPLE | ||
+ | | ||
+ | .EXAMPLE | ||
+ | Ein weiteres Beispiel für die Verwendung dieses Cmdlets | ||
+ | #> | ||
+ | [CmdletBinding()] | ||
+ | [OutputType([int])] | ||
+ | Param | ||
+ | ( | ||
+ | # Hilfebeschreibung zu Param1 | ||
+ | [Parameter(ValueFromPipeline=$true)] | ||
+ | [string[]]$ComputerName = " | ||
+ | ) | ||
+ | |||
+ | Begin | ||
+ | { | ||
+ | [datetime]$heute = Get-Date -Hour 0 -Minute 0 -Second 0 -Millisecond 0 | ||
+ | Write-Debug -Message (" | ||
+ | } | ||
+ | Process | ||
+ | { | ||
+ | $produkte = Get-WmiObject -ComputerName $ComputerName -Class Win32_Product | | ||
+ | Sort-Object -Property Name | ||
+ | | ||
+ | foreach ($item in $produkte) | ||
+ | { | ||
+ | if($item.Name -eq $null) {continue} | ||
+ | |||
+ | $installDate = Get-Date -Year $item.InstallDate.Substring(0, | ||
+ | -Month $item.InstallDate.Substring(4, | ||
+ | -Day | ||
+ | -Hour 0 -Minute 0 -Second 0 -Millisecond 0 | ||
+ | | ||
+ | $resultset = [ordered]@{ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | | ||
+ | New-Object -TypeName psobject -Property $resultset | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Get-Product -Debug | ft | ||
+ | # | ||
+ | # | ||
+ | #" | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | #Get-Help Get-Product -ShowWindow | ||
+ | |||
+ | #endregion | ||
+ | #region Control-Panel' | ||
+ | |||
+ | Get-ControlPanelItem | sort Name | ||
+ | Get-ControlPanelItem -Name " | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Office | ||
+ | |||
+ | #region Auf Outlook zugreifen | ||
+ | # Outlook muss installiert sein | ||
+ | # zzgl. Office PIA bis Office 2010 AB in Office-Installation | ||
+ | # ALTERNATIVE: | ||
+ | $outlook = new-object -ComObject Outlook.Application | ||
+ | $namespace = $outlook.GetNamespace(" | ||
+ | $inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]:: | ||
+ | Write-Host " | ||
+ | foreach($item in $inbox.Items) | ||
+ | { | ||
+ | Write-Host " SUBJECT:" | ||
+ | } | ||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region Netzwerk | ||
+ | |||
+ | #region Netzwerk-Freigabe erstellen | ||
+ | |||
+ | New-SmbShare -Name Data -Path C:\Windows | ||
+ | Remove-SmbShare -Name Data -Confirm: | ||
+ | |||
+ | #endregion | ||
+ | #region Netzwerk-Adapter neustarten | ||
+ | |||
+ | Get-NetAdapter -IncludeHidden | ||
+ | Restart-NetAdapter -Name WLAN # Einen | ||
+ | Restart-NetAdapter -Name * -PassThru -IncludeHidden # Alle | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region IO, FileSystem, OneDrive, Database, Web | ||
+ | |||
+ | #region Eine temporäre Datei erstellen | ||
+ | |||
+ | $temp = New-TemporaryFile | ||
+ | $temp | ||
+ | |||
+ | #endregion | ||
+ | #region Alle temporären Dateien löschen | ||
+ | |||
+ | $path = Join-Path -Path $env: | ||
+ | Remove-Item -Path $path -Recurse -Force -ea SilentlyContinue | ||
+ | |||
+ | #endregion | ||
+ | #region Hash einer Datei berechnen | ||
+ | |||
+ | # ... um identische Dateien zu finden, oder der Unversehrtheit z.B. beim übertragen zu gewehrleisten | ||
+ | |||
+ | Get-FileHash -Path C: | ||
+ | |||
+ | #endregion | ||
+ | #region Dateien in ein Archiv kompremieren | ||
+ | |||
+ | Get-ChildItem -Path C: | ||
+ | ? Extension -EQ " | ||
+ | Compress-Archive -DestinationPath C: | ||
+ | |||
+ | #endregion | ||
+ | #region Den tatsächlien Ort von Spezial-Ordner lokalisieren | ||
+ | |||
+ | [Environment]:: | ||
+ | " | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Datei beschreiben | ||
+ | |||
+ | $datei = New-Item -Path C: | ||
+ | $writer = $datei.CreateText() | ||
+ | for ($i = 1; $i -lt 99; $i++) | ||
+ | { | ||
+ | $logText = (" | ||
+ | $writer.WriteLine($logText) | ||
+ | } | ||
+ | $writer.Close() | ||
+ | Get-Content -Path C: | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Datei lesen | ||
+ | |||
+ | $datei = Get-Item -Path C: | ||
+ | $reader = $datei.OpenText() # | Get-Member # Siehe auch .OpenRead() für Byte-Datei | ||
+ | |||
+ | while (-not $reader.EndOfStream) | ||
+ | { | ||
+ | $zeile = $reader.ReadLine() | ||
+ | $zeile | ||
+ | } | ||
+ | |||
+ | $reader.Close() | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Get-BigFile | ||
+ | |||
+ | function Get-BigFile | ||
+ | { | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | Zeigt eine Übersicht von großen Dateien und deren Besitzer. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-BigFile -Path C:\ -GE 100MB | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | #> | ||
+ | [CmdletBinding( HelpUri = ' | ||
+ | [Alias(" | ||
+ | [OutputType([PSCustomObject])] | ||
+ | Param | ||
+ | ( | ||
+ | # Pfad an dem große Dateien gefunden werden sollen | ||
+ | [Parameter(ValueFromPipeLine = $true)] | ||
+ | [string] | ||
+ | $Path = " | ||
+ | |||
+ | # Eine Datei ist Groß wenn sie größer gleich diesem Wert ist | ||
+ | [Parameter(Mandatory = $true)] | ||
+ | [uint32] | ||
+ | $GE = 10MB, | ||
+ | | ||
+ | [switch] | ||
+ | [bool] | ||
+ | $Recurse = $false | ||
+ | ) | ||
+ | |||
+ | Process | ||
+ | { | ||
+ | Get-ChildItem -Path $Path -Recurse: | ||
+ | Where-Object -Property Length -GE -Value $GE | | ||
+ | ForEach-Object -Process { | ||
+ | [PSCustomObject]@{ | ||
+ | Name = $_.Name; | ||
+ | Length | ||
+ | Owner = $_ | Get-Acl -ea SilentlyContinue | select -exp Owner; | ||
+ | LastAccessTime = $_.LastAccessTime; | ||
+ | FullName | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | New-Alias -Name gbf -Value Get-BigFile -Force | ||
+ | |||
+ | #Get-Help Get-BigFile -ShowWindow | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | #" | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Get-OldFile | ||
+ | |||
+ | function Get-OldFile | ||
+ | { | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | Ermittelt alte Dateien. | ||
+ | | ||
+ | .DESCRIPTION | ||
+ | Ermittelt alte Dateien nach Anzahl Tage. | ||
+ | |||
+ | .INPUTS | ||
+ | |||
+ | .OUTPUTS | ||
+ | Liefert ein ein PSObject mit folgenden Eigenschaften..... | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-OldFile -Path C:\Windows -OlderThanDays 180 | ||
+ | Alle alte Datei aus c:\windows die älter sind als 180 Tage. | ||
+ | |||
+ | .EXAMPLE | ||
+ | Get-OldFile -Path C:\Windows -OlderThanDays 180 -Recurse | ||
+ | Alle alte Datei aus c:\windows und Unterordner die älter sind als 180 Tage. | ||
+ | #> | ||
+ | param( | ||
+ | [Parameter(ParameterSetName | ||
+ | | ||
+ | [Parameter(ParameterSetName | ||
+ | | ||
+ | [ValidateScript({Test-Path $_})] | ||
+ | [string]$Path = " | ||
+ | | ||
+ | # Gültige Werte für Tag sind 1 bis 4000 | ||
+ | [Parameter(Mandatory | ||
+ | | ||
+ | [ValidateRange(1, | ||
+ | [UInt32]$OlderThanDays, | ||
+ | | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [switch] | ||
+ | [bool]$Recurse, | ||
+ | |||
+ | [Parameter(Mandatory | ||
+ | | ||
+ | [ValidateScript({$_ -le (Get-Date)})] | ||
+ | [datetime]$OlderThan | ||
+ | ) | ||
+ | |||
+ | begin { # Inizialisierungs-Code | ||
+ | $lastAccessTime = $null | ||
+ | switch ($psCmdLet.ParameterSetName) | ||
+ | { | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | process | ||
+ | { | ||
+ | Get-ChildItem -Path $Path -Recurse: | ||
+ | Where-Object -Property LastAccessTime -lt $lastAccessTime | | ||
+ | ForEach-Object -Process { | ||
+ | $now = Get-Date | ||
+ | $owner = $_ | Get-Acl | Select-Object -ExpandProperty Owner | ||
+ | $result = [ordered]@{ | ||
+ | Name = $_.Name; | ||
+ | AgeInDays | ||
+ | Owner = $owner; | ||
+ | LastAccessTime = $_.LastAccessTime; | ||
+ | FullName | ||
+ | New-Object PSObject -Property $result | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | #Get-Help Get-OldFile -ShowWindow | ||
+ | # | ||
+ | Get-OldFile -Path c:\ -Recurse -OlderThanDays 1200 | Out-GridView | ||
+ | Get-OldFile -Path c:\ -Recurse -OlderThan " | ||
+ | |||
+ | # | ||
+ | # KOMPONENTENTEST | ||
+ | # | ||
+ | |||
+ | # | ||
+ | # | ||
+ | # | ||
+ | #Get-help Get-OldFiles -ShowWindow | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | #Get-Help Where-Object -Online | ||
+ | #" | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Get-XFile (Kombination aus Get-OldFile und Get-BigFile) | ||
+ | |||
+ | function Get-XFile | ||
+ | { | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | Ermittelt alte und oder große Dateien. | ||
+ | #> | ||
+ | param( | ||
+ | [Parameter(ParameterSetName | ||
+ | | ||
+ | [Parameter(ParameterSetName | ||
+ | | ||
+ | [ValidateScript({Test-Path $_})] | ||
+ | [string]$Path, | ||
+ | | ||
+ | # Gültige Werte für Tag sind 1 bis 4000 | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [ValidateRange(1, | ||
+ | [UInt32]$OlderThanDays, | ||
+ | |||
+ | [Parameter(ParameterSetName = " | ||
+ | [ValidateScript({$_ -le (Get-Date)})] | ||
+ | [datetime]$OlderThan, | ||
+ | |||
+ | |||
+ | # Eine Datei ist Groß wenn sie größer gleich diesem Wert ist | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [uint32] | ||
+ | $LengthGE = 0, | ||
+ | |||
+ | [Parameter(ParameterSetName = " | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [switch] | ||
+ | [bool]$AgeOrBig, | ||
+ | |||
+ | [Parameter(ParameterSetName = " | ||
+ | [Parameter(ParameterSetName = " | ||
+ | [switch] | ||
+ | [bool]$Recurse | ||
+ | ) | ||
+ | |||
+ | begin { # Inizialisierungs-Code | ||
+ | $lastAccessTime = $null | ||
+ | switch ($psCmdLet.ParameterSetName) | ||
+ | { | ||
+ | ' | ||
+ | ' | ||
+ | } | ||
+ | $filterScript = $null | ||
+ | if($AgeOrBig) | ||
+ | { | ||
+ | $filterScript = {$_.LastAccessTime -lt $lastAccessTime -or $_.Length -ge $LengthGE } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | $filterScript = {$_.LastAccessTime -lt $lastAccessTime -and $_.Length -ge $LengthGE } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | process | ||
+ | { | ||
+ | Get-ChildItem -Path $Path -Recurse: | ||
+ | Where-Object -FilterScript $filterScript | | ||
+ | ForEach-Object -Process { | ||
+ | $now = Get-Date | ||
+ | $owner = $_ | Get-Acl | Select-Object -ExpandProperty Owner | ||
+ | $result = [ordered]@{ | ||
+ | Name = $_.Name; | ||
+ | Length | ||
+ | AgeInDays | ||
+ | Owner = $owner; | ||
+ | LastAccessTime = $_.LastAccessTime; | ||
+ | FullName | ||
+ | New-Object PSObject -Property $result | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Get-Help -Name Get-XFile -ShowWindow | ||
+ | Show-Command -Name Get-XFile | ||
+ | Get-XFile -Path c:\ -Recurse -OlderThanDays 300 | Out-GridView | ||
+ | Get-XFile -Path c:\ -Recurse | ||
+ | Get-XFile -Path c:\ -Recurse -OlderThanDays 300 -LengthGE 10MB | Out-GridView | ||
+ | Get-XFile -Path c:\ -Recurse -OlderThanDays 300 -LengthGE 10MB -AgeOrBig | Out-GridView | ||
+ | |||
+ | #endregion | ||
+ | #region CmdLet: Test-ReadAccess | ||
+ | |||
+ | function Test-ReadAccess | ||
+ | { | ||
+ | <# # | ||
+ | .DESCRIPTION | ||
+ | Prüft ob Lese-Rechte vorliegen | ||
+ | |||
+ | .EXAMPLE | ||
+ | Test-ReadAccess c: | ||
+ | |||
+ | .EXAMPLE | ||
+ | Test-ReadAccess c: | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | " | ||
+ | |||
+ | .EXAMPLE | ||
+ | ls c:\*.* -Force | Test-ReadAccess | ||
+ | |||
+ | .INPUTS | ||
+ | Hinweise zur Eingabe | ||
+ | |||
+ | .OUTPUTS | ||
+ | Hinweise zur Ausgabe | ||
+ | |||
+ | |||
+ | .NOTES | ||
+ | Siehe auch Get-Acl | ||
+ | #> | ||
+ | [CmdletBinding()] | ||
+ | Param | ||
+ | ([Parameter(Mandatory=$true, | ||
+ | | ||
+ | [string]$Path | ||
+ | ) | ||
+ | Process | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | Get-Content $Path -ErrorAction Stop -ReadCount 1 | Out-Null | ||
+ | | ||
+ | return new-object PSObject -Property @{ | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | catch [UnauthorizedAccessException] | ||
+ | { | ||
+ | return new-object PSObject -Property @{ | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Datenbank zugriff (ADO.NET) | ||
+ | |||
+ | # | ||
+ | # 1. Connection-Objekt erstellen | ||
+ | # | ||
+ | |||
+ | # Microsoft SQL Server => System.Data.SqlClient | ||
+ | # Diverse DBMS => System.Data.Odbc ODER System.Data.OleDb | ||
+ | # MySql => Siehe Hersteller bzgl. .NET Treiber | ||
+ | # PostgreSQL => Siehe Hersteller bzgl. .NET Treiber | ||
+ | # Orcale => Siehe Hersteller bzgl. .NET Treiber | ||
+ | |||
+ | # | ||
+ | # Connection-String siehe http:// | ||
+ | # | ||
+ | |||
+ | $conn = New-Object -TypeName System.Data.SqlClient.SqlConnection | ||
+ | $conn.ConnectionString = " | ||
+ | $conn.Open() | ||
+ | #$ta = $conn.BeginTransaction() | ||
+ | |||
+ | # | ||
+ | # 2. Command-Objekt erstellen | ||
+ | # | ||
+ | |||
+ | $cmd = New-Object -TypeName System.Data.SqlClient.SqlCommand | ||
+ | $cmd.Connection = $conn | ||
+ | $cmd.CommandText = " | ||
+ | |||
+ | # | ||
+ | # 3.1 Nutzen (z.B. Reader-Objekt) | ||
+ | # | ||
+ | |||
+ | $reader = $cmd.ExecuteReader() | ||
+ | while ($reader.Read()) | ||
+ | { | ||
+ | "VN: {0} NN: {1} BusinessEntityID {2}" -f $reader[" | ||
+ | } | ||
+ | |||
+ | # | ||
+ | $conn.Close() | ||
+ | |||
+ | # | ||
+ | # 3.2 Nutzen (z.B. Datensatz ändern) | ||
+ | # | ||
+ | |||
+ | $conn.Open() | ||
+ | $cmd.CommandText = " | ||
+ | $ergebnis = $cmd.ExecuteNonQuery() | ||
+ | " | ||
+ | $conn.Close() | ||
+ | |||
+ | # | ||
+ | # 3.3 Nutzen (z.B. analysieren) | ||
+ | # | ||
+ | |||
+ | $conn.Open() | ||
+ | $cmd.CommandText = " | ||
+ | $ergebnis = $cmd.ExecuteScalar() | ||
+ | "In der Tabelle Person.Person sind {0} Datensätze enthalten" | ||
+ | $conn.Close() | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Dateiauswahl (WinForms.CommonDialogs) | ||
+ | |||
+ | $Dlg = New-Object System.Windows.Forms.OpenFileDialog | ||
+ | $Dlg.Filter = " | ||
+ | $Dlg.InitialDirectory = " | ||
+ | $DialogResult = $Dlg.ShowDialog() | ||
+ | if ($DialogResult -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | $Dlg.Filename | ||
+ | } | ||
+ | |||
+ | $Dlg = New-Object System.Windows.Forms.FolderBrowserDialog | ||
+ | $Dlg.Description = "Bitte Ordner für das Archivieren auswählen" | ||
+ | $Dlg.RootFolder = [System.Environment+SpecialFolder]:: | ||
+ | $Dlg.ShowNewFolderButton = $true | ||
+ | $DialogResult = $Dlg.ShowDialog() | ||
+ | if ($DialogResult -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | $Dlg.SelectedPath | ||
+ | } | ||
+ | |||
+ | # SaveAsDialog, | ||
+ | |||
+ | #endregion | ||
+ | #region HTTP-Kommunikation (Web-Request) | ||
+ | |||
+ | $webrequest = Invoke-WebRequest -Uri " | ||
+ | $xml = [xml]$webrequest.Content | ||
+ | $xml.Envelope.Cube.Cube.Cube | ? currency -eq " | ||
+ | |||
+ | #endregion | ||
+ | #region Proxy-Server | ||
+ | |||
+ | $webProxy = New-Object System.Net.WebProxy(" | ||
+ | $webProxy.Credentials = New-Object Net.NetworkCredential(" | ||
+ | $netCred = New-Object System.Net.NetworkCredentials(" | ||
+ | $webClient = New-Object System.Net.WebClient | ||
+ | # | ||
+ | $webClient.Credentials=$netCred | ||
+ | $page = $webClient.DownloadString(" | ||
+ | # | ||
+ | |||
+ | #endregion | ||
+ | #region Bing-Images downloaden | ||
+ | |||
+ | $ImageUrl = " | ||
+ | $response = Invoke-WebRequest -Uri $ImageUrl; | ||
+ | $xmlDocument = [xml]$response.Content | ||
+ | $xmlDocument.images.image | % { | ||
+ | $uri = " | ||
+ | $filename = " | ||
+ | Invoke-WebRequest -Uri $uri -OutFile $filename | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region Zugriff auf OneDrive | ||
+ | |||
+ | Install-Module -Name OneDrive -Scope CurrentUser -AllowClobber -Force | ||
+ | |||
+ | Start-Process https:// | ||
+ | $auth = Get-ODAuthentication -ClientID " | ||
+ | $accessToken = $auth.access_token | ||
+ | |||
+ | # ODER | ||
+ | |||
+ | Start-Process https:// | ||
+ | $accessToken = " | ||
+ | |||
+ | Add-ODItem | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region .NET Framework, CLI | ||
+ | #region using namespace-Anweisung (Require PS 5.0) | ||
+ | |||
+ | using namespace System.Diagnostics; | ||
+ | |||
+ | #endregion | ||
+ | #endregion | ||
+ | #region UserInterface, | ||
+ | |||
+ | #region Keyboard-Taste vom User abfragen | ||
+ | |||
+ | $key = [console]:: | ||
+ | $key.KeyChar | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Dateiauswahl (WinForms.CommonDialogs) | ||
+ | |||
+ | $Dlg = New-Object System.Windows.Forms.OpenFileDialog | ||
+ | $Dlg.Filter = " | ||
+ | $Dlg.InitialDirectory = " | ||
+ | $DialogResult = $Dlg.ShowDialog() | ||
+ | if ($DialogResult -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | $Dlg.Filename | ||
+ | } | ||
+ | |||
+ | $Dlg = New-Object System.Windows.Forms.FolderBrowserDialog | ||
+ | $Dlg.Description = "Bitte Ordner für das Archivieren auswählen" | ||
+ | $Dlg.RootFolder = [System.Environment+SpecialFolder]:: | ||
+ | $Dlg.ShowNewFolderButton = $true | ||
+ | $DialogResult = $Dlg.ShowDialog() | ||
+ | if ($DialogResult -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | $Dlg.SelectedPath | ||
+ | } | ||
+ | |||
+ | # SaveAsDialog, | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Eingabefenster/ | ||
+ | |||
+ | function inputbox([System.String]$strPrompt="", | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | if ($eingabefeld.Text.Trim() -gt "" | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | # | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | }) | ||
+ | |||
+ | | ||
+ | $global: | ||
+ | $global: | ||
+ | $form.Close(); | ||
+ | $form.Dispose()}) | ||
+ | |||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | # | ||
+ | if ($global: | ||
+ | { | ||
+ | return $global: | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | return $false | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | # | ||
+ | #echo (getScriptName) | ||
+ | $Erg=[reflection.assembly]:: | ||
+ | $Erg=[reflection.assembly]:: | ||
+ | " | ||
+ | |||
+ | echo (inputbox "Bitte Wert eingeben!" | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: MessageBox (WinForms.CommonDialogs) | ||
+ | |||
+ | # | ||
+ | $erg=[reflection.assembly]:: | ||
+ | |||
+ | [System.Windows.Forms.MessageBox]:: | ||
+ | |||
+ | |||
+ | if ([System.Windows.Forms.MessageBox]:: | ||
+ | " | ||
+ | (" | ||
+ | [System.Windows.Forms.MessageBoxButtons]:: | ||
+ | [System.Windows.Forms.MessageBoxIcon]:: | ||
+ | -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | echo " | ||
+ | exit | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | #hier folgt weiterer Code | ||
+ | echo " | ||
+ | } | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: 'Hallo Welt' | ||
+ | |||
+ | function Start-WpfHalloWelt | ||
+ | { | ||
+ | Add-Type -AssemblyName PresentationFramework | ||
+ | Add-Type -AssemblyName System | ||
+ | |||
+ | [XML]$XAML = @" | ||
+ | <Window x: | ||
+ | xmlns=" | ||
+ | xmlns: | ||
+ | Title=" | ||
+ | < | ||
+ | <TextBox x: | ||
+ | <Label x: | ||
+ | <Button x: | ||
+ | <Button x: | ||
+ | </ | ||
+ | </ | ||
+ | "@ | ||
+ | |||
+ | $XAML.Window.RemoveAttribute(" | ||
+ | $Reader = New-Object System.Xml.XmlNodeReader $XAML | ||
+ | $Form = [Windows.Markup.XamlReader]:: | ||
+ | |||
+ | $PSText | ||
+ | $PSLabel | ||
+ | $PSBtnOK | ||
+ | $PSBtnExit = $Form.FindName(' | ||
+ | |||
+ | $btnOKClick | ||
+ | $btnExitClick = {$Form.Close()} | ||
+ | |||
+ | $PSBtnOK.Add_Click($btnOKClick) | ||
+ | $PSBtnExit.Add_Click($btnExitClick) | ||
+ | |||
+ | $Form.ShowDialog() | ||
+ | } | ||
+ | |||
+ | Start-WpfHalloWelt | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Komplexe Fenster z.B. Uhr (WPF) | ||
+ | |||
+ | function Start-WpfUhr | ||
+ | { | ||
+ | <# | ||
+ | .SYSNOPSIS | ||
+ | Displays a clock on the screen with date. | ||
+ | |||
+ | .DESCRIPTION | ||
+ | Displays a clock on the screen with date. | ||
+ | |||
+ | .PARAMETER TimeColor | ||
+ | Specify the color of the time display. | ||
+ | |||
+ | .PARAMETER DateColor | ||
+ | Specify the color of the date display. | ||
+ | |||
+ | Default is White | ||
+ | |||
+ | .EXAMPLE | ||
+ | .\ClockWidget.ps1 | ||
+ | |||
+ | Description | ||
+ | ----------- | ||
+ | Clock is displayed on screen | ||
+ | |||
+ | .EXAMPLE | ||
+ | .\ClockWidget.ps1 -TimeColor DarkRed -DateColor Gold | ||
+ | |||
+ | Description | ||
+ | ----------- | ||
+ | Clock is displayed on screen with alternate colors | ||
+ | |||
+ | .EXAMPLE | ||
+ | .\ClockWidget.ps1 –TimeColor "# | ||
+ | |||
+ | Description | ||
+ | ----------- | ||
+ | Clock is displayed on screen with alternate colors as hex values | ||
+ | |||
+ | #> | ||
+ | Param ( | ||
+ | [parameter()] | ||
+ | [string]$TimeColor = " | ||
+ | [parameter()] | ||
+ | [string]$DateColor = " | ||
+ | ) | ||
+ | $Clockhash = [hashtable]:: | ||
+ | $Runspacehash = [hashtable]:: | ||
+ | $Runspacehash.host = $Host | ||
+ | $Clockhash.TimeColor = $TimeColor | ||
+ | $Clockhash.DateColor = $DateColor | ||
+ | $Runspacehash.runspace = [RunspaceFactory]:: | ||
+ | $Runspacehash.runspace.ApartmentState = “STA” | ||
+ | $Runspacehash.runspace.ThreadOptions = “ReuseThread” | ||
+ | $Runspacehash.runspace.Open() | ||
+ | $Runspacehash.psCmd = {Add-Type -AssemblyName PresentationCore, | ||
+ | $Runspacehash.runspace.SessionStateProxy.SetVariable(" | ||
+ | $Runspacehash.runspace.SessionStateProxy.SetVariable(" | ||
+ | $Runspacehash.runspace.SessionStateProxy.SetVariable(" | ||
+ | $Runspacehash.runspace.SessionStateProxy.SetVariable(" | ||
+ | $Runspacehash.psCmd.Runspace = $Runspacehash.runspace | ||
+ | $Runspacehash.Handle = $Runspacehash.psCmd.AddScript({ | ||
+ | |||
+ | | ||
+ | $day, | ||
+ | |||
+ | $Clockhash.time_txtbox.text = $Time.TrimStart(" | ||
+ | $Clockhash.day_txtbx.Text = $day | ||
+ | $Clockhash.ampm_txtbx.text = $AMPM | ||
+ | $Clockhash.day_n_txtbx.text = $Day_n | ||
+ | $Clockhash.month_txtbx.text = $Month | ||
+ | $Clockhash.year_txtbx.text = $year | ||
+ | } | ||
+ | |||
+ | [xml]$xaml = @" | ||
+ | <Window | ||
+ | xmlns=" | ||
+ | xmlns: | ||
+ | WindowStyle = " | ||
+ | ResizeMode = " | ||
+ | <Grid x:Name = " | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | < | ||
+ | HorizontalAlignment=" | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | "@ | ||
+ | |||
+ | $reader=(New-Object System.Xml.XmlNodeReader $xaml) | ||
+ | $Clockhash.Window=[Windows.Markup.XamlReader]:: | ||
+ | |||
+ | $Clockhash.time_txtbox = $Clockhash.window.FindName(" | ||
+ | $Clockhash.ampm_txtbx = $Clockhash.Window.FindName(" | ||
+ | $Clockhash.day_n_txtbx = $Clockhash.Window.FindName(" | ||
+ | $Clockhash.month_txtbx = $Clockhash.Window.FindName(" | ||
+ | $Clockhash.year_txtbx = $Clockhash.Window.FindName(" | ||
+ | $Clockhash.day_txtbx = $Clockhash.Window.FindName(" | ||
+ | |||
+ | #Timer Event | ||
+ | $Clockhash.Window.Add_SourceInitialized({ | ||
+ | #Create Timer object | ||
+ | Write-Verbose " | ||
+ | $Script: | ||
+ | #Fire off every 1 minutes | ||
+ | Write-Verbose " | ||
+ | $timer.Interval = [TimeSpan]" | ||
+ | #Add event per tick | ||
+ | Write-Verbose " | ||
+ | $timer.Add_Tick({ | ||
+ | $Update.Invoke() | ||
+ | [Windows.Input.InputEventHandler]{ $Clockhash.Window.UpdateLayout() } | ||
+ | | ||
+ | }) | ||
+ | #Start timer | ||
+ | Write-Verbose " | ||
+ | $timer.Start() | ||
+ | If (-NOT $timer.IsEnabled) { | ||
+ | $Clockhash.Window.Close() | ||
+ | } | ||
+ | }) | ||
+ | |||
+ | $Clockhash.Window.Add_Closed({ | ||
+ | $timer.Stop() | ||
+ | $Runspacehash.PowerShell.Dispose() | ||
+ | | ||
+ | [gc]:: | ||
+ | [gc]:: | ||
+ | }) | ||
+ | $Clockhash.month_txtbx.Add_SizeChanged({ | ||
+ | [int]$clockhash.length = [math]:: | ||
+ | Sort -Descending)[0]) | ||
+ | [int]$Adjustment = $clockhash.length + 52 + 10 #Hard coded margin plus white space | ||
+ | | ||
+ | $YearMargin = $Clockhash.year_txtbx.Margin | ||
+ | $Clockhash.year_txtbx.Margin = (" | ||
+ | $YearMargin.Top, | ||
+ | }) | ||
+ | $Clockhash.time_txtbox.Add_SizeChanged({ | ||
+ | If ($Clockhash.time_txtbox.text.length -eq 4) { | ||
+ | $Clockhash.ampm_txtbx.Margin | ||
+ | } Else { | ||
+ | $Clockhash.ampm_txtbx.Margin | ||
+ | } | ||
+ | }) | ||
+ | $Clockhash.Window.Add_MouseRightButtonUp({ | ||
+ | $This.close() | ||
+ | }) | ||
+ | $Clockhash.Window.Add_MouseLeftButtonDown({ | ||
+ | $This.DragMove() | ||
+ | }) | ||
+ | $Update.Invoke() | ||
+ | $Clockhash.Window.ShowDialog() | Out-Null | ||
+ | }).BeginInvoke() | ||
+ | } | ||
+ | |||
+ | Start-WpfUhr | ||
+ | |||
+ | #endregion | ||
+ | #region .NET: Read-Window (WinForm, CmdLet) | ||
+ | |||
+ | function Read-Window | ||
+ | { | ||
+ | <# | ||
+ | .EXAMPLE | ||
+ | Read-Window | ||
+ | |||
+ | .EXAMPLE | ||
+ | Read-Window -Title " | ||
+ | #> | ||
+ | | ||
+ | Param( | ||
+ | [string]$Title = [string]:: | ||
+ | [string]$Message = [string]:: | ||
+ | [string]$DefaultText = [string]:: | ||
+ | ) | ||
+ | |||
+ | $a = [System.Reflection.Assembly]:: | ||
+ | $b = [System.Reflection.Assembly]:: | ||
+ | | ||
+ | $messageLabel = New-Object System.Windows.Forms.Label | ||
+ | $messageLabel.Text | ||
+ | $messageLabel.Left | ||
+ | $messageLabel.Top | ||
+ | $messageLabel.Width | ||
+ | $messageLabel.Height = 30 | ||
+ | $messageLabel.Anchor = [System.Windows.Forms.AnchorStyles]:: | ||
+ | # | ||
+ | |||
+ | $inputTextBox = New-Object System.Windows.Forms.TextBox | ||
+ | $inputTextBox.Left | ||
+ | $inputTextBox.Top | ||
+ | $inputTextBox.Width | ||
+ | $inputTextBox.Multiline = $true | ||
+ | $inputTextBox.Height | ||
+ | $inputTextBox.Text | ||
+ | $inputTextBox.Anchor | ||
+ | [System.Windows.Forms.AnchorStyles]:: | ||
+ | [System.Windows.Forms.AnchorStyles]:: | ||
+ | [System.Windows.Forms.AnchorStyles]:: | ||
+ | |||
+ | $okButtom = New-Object System.Windows.Forms.Button | ||
+ | $okButtom.Text | ||
+ | $okButtom.Left | ||
+ | $okButtom.Top | ||
+ | $okButtom.DialogResult = [System.Windows.Forms.DialogResult]:: | ||
+ | $okButtom.Anchor | ||
+ | | ||
+ | |||
+ | $cancelButton = New-Object System.Windows.Forms.Button | ||
+ | $cancelButton.Text | ||
+ | $cancelButton.Left | ||
+ | $cancelButton.Top | ||
+ | $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]:: | ||
+ | $cancelButton.Anchor | ||
+ | | ||
+ | |||
+ | $inputboxForm = New-Object System.Windows.Forms.Form | ||
+ | $inputboxForm.AcceptButton = $okButtom | ||
+ | $inputboxForm.CancelButton = $cancelButton | ||
+ | $inputboxForm.StartPosition = [System.Windows.Forms.FormStartPosition]:: | ||
+ | $inputboxForm.MinimizeBox = $false | ||
+ | $inputboxForm.MaximizeBox = $false | ||
+ | $inputboxForm.Text | ||
+ | $inputboxForm.Height | ||
+ | $inputboxForm.Controls.AddRange(($messageLabel, | ||
+ | $inputboxForm.Scale(3) | ||
+ | |||
+ | $formClosingAction = { | ||
+ | if($inputboxForm.DialogResult -eq [System.Windows.Forms.DialogResult]:: | ||
+ | { | ||
+ | Out-Host -InputObject $inputTextBox.Text | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Out-Host -InputObject ([string]:: | ||
+ | } | ||
+ | } | ||
+ | $inputboxForm.Add_FormClosing($formClosingAction) | ||
+ | | ||
+ | $inputboxForm.ShowDialog() | Out-Null | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region UI-Abfrage per PromptForChoice | ||
+ | |||
+ | $title = " | ||
+ | $message = "Do you want to delete the remaining files in the folder?" | ||
+ | |||
+ | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "& | ||
+ | " | ||
+ | |||
+ | $no = New-Object System.Management.Automation.Host.ChoiceDescription "& | ||
+ | " | ||
+ | |||
+ | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, | ||
+ | |||
+ | $result = $host.ui.PromptForChoice($title, | ||
+ | |||
+ | switch ($result) | ||
+ | { | ||
+ | 0 {"You selected Yes."} | ||
+ | 1 {"You selected No."} | ||
+ | } | ||
+ | |||
+ | #endregion | ||
+ | #region Diagramm erstellen per DataVisualization | ||
+ | |||
+ | using namespace System.Windows.Forms.DataVisualization.Charting | ||
+ | using namespace System.Windows.Forms | ||
+ | |||
+ | [System.Reflection.Assembly]:: | ||
+ | |||
+ | $datasource = Get-Process | sort PrivateMemorySize -Descending | ||
+ | |||
+ | $chart1 = New-object Chart | ||
+ | $chart1.Width = 1000 | ||
+ | $chart1.Height = 1000 | ||
+ | $chart1.BackColor = [System.Drawing.Color]:: | ||
+ | $chart1.Dock = [DockStyle]:: | ||
+ | |||
+ | $chart1.Titles.Add(" | ||
+ | $chart1.Titles[0].Font = " | ||
+ | $chart1.Titles[0].Alignment = " | ||
+ | |||
+ | $chartarea = New-Object ChartArea | ||
+ | $chartarea.Name = " | ||
+ | $chartarea.AxisY.Title = " | ||
+ | $chartarea.AxisX.Title = " | ||
+ | $chartarea.AxisY.Interval = 100 | ||
+ | $chartarea.AxisX.Interval = 1 | ||
+ | $chart1.ChartAreas.Add($chartarea) | ||
+ | |||
+ | $legend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend | ||
+ | $legend.name = " | ||
+ | $chart1.Legends.Add($legend) | ||
+ | |||
+ | $chart1.Series.Add(" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $datasource | ForEach-Object { | ||
+ | $chart1.Series[" | ||
+ | |||
+ | $chart1.Series.Add(" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $chart1.Series[" | ||
+ | $datasource | ForEach-Object { | ||
+ | $chart1.Series[" | ||
+ | |||
+ | # z.B. als PNG speichern, oder | ||
+ | $chart1.SaveImage(" | ||
+ | |||
+ | # z.B. im Fenster anzeigen | ||
+ | $Form = New-Object Form | ||
+ | $Form.Width = 1024 | ||
+ | $Form.Height = 820 | ||
+ | $Form.controls.add($chart1) | ||
+ | $Form.Add_Shown({$Form.Activate()}) | ||
+ | $Form.ShowDialog() | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | |||
+ | #endregion | ||
+ | #region EINARBEITEN | ||
+ | |||
+ | function Join-Object | ||
+ | { | ||
+ | <# | ||
+ | .SYNOPSIS | ||
+ | Join data from two sets of objects based on a common value | ||
+ | |||
+ | .DESCRIPTION | ||
+ | Join data from two sets of objects based on a common value | ||
+ | |||
+ | For more details, see the accompanying blog post: | ||
+ | http:// | ||
+ | |||
+ | For even more details, see the original code and discussions that this borrows from: | ||
+ | Dave Wyatt' | ||
+ | Lucio Silveira' | ||
+ | |||
+ | .PARAMETER Left | ||
+ | ' | ||
+ | |||
+ | The objects in this collection should be consistent. | ||
+ | We look at the properties on the first object for a baseline. | ||
+ | |||
+ | .PARAMETER Right | ||
+ | ' | ||
+ | |||
+ | The objects in this collection should be consistent. | ||
+ | We look at the properties on the first object for a baseline. | ||
+ | |||
+ | .PARAMETER LeftJoinProperty | ||
+ | Property on Left collection objects that we match up with RightJoinProperty on the Right collection | ||
+ | |||
+ | .PARAMETER RightJoinProperty | ||
+ | Property on Right collection objects that we match up with LeftJoinProperty on the Left collection | ||
+ | |||
+ | .PARAMETER LeftProperties | ||
+ | One or more properties to keep from Left. Default is to keep all Left properties (*). | ||
+ | |||
+ | Each property can: | ||
+ | - Be a plain property name like " | ||
+ | - Contain wildcards like " | ||
+ | - Be a hashtable like @{Name=" | ||
+ | Name is the output property name | ||
+ | | ||
+ | |||
+ | | ||
+ | Each property using this hashtable syntax will be excluded from suffixes and prefixes | ||
+ | |||
+ | .PARAMETER RightProperties | ||
+ | One or more properties to keep from Right. Default is to keep all Right properties (*). | ||
+ | |||
+ | Each property can: | ||
+ | - Be a plain property name like " | ||
+ | - Contain wildcards like " | ||
+ | - Be a hashtable like @{Name=" | ||
+ | Name is the output property name | ||
+ | | ||
+ | |||
+ | | ||
+ | Each property using this hashtable syntax will be excluded from suffixes and prefixes | ||
+ | |||
+ | .PARAMETER Prefix | ||
+ | If specified, prepend Right object property names with this prefix to avoid collisions | ||
+ | |||
+ | Example: | ||
+ | Property Name = ' | ||
+ | Suffix = ' | ||
+ | Resulting Joined Property Name = ' | ||
+ | |||
+ | .PARAMETER Suffix | ||
+ | If specified, append Right object property names with this suffix to avoid collisions | ||
+ | |||
+ | Example: | ||
+ | Property Name = ' | ||
+ | Suffix = ' | ||
+ | Resulting Joined Property Name = ' | ||
+ | |||
+ | .PARAMETER Type | ||
+ | Type of join. Default is AllInLeft. | ||
+ | |||
+ | AllInLeft will have all elements from Left at least once in the output, and might appear more than once | ||
+ | if the where clause is true for more than one element in right, Left elements with matches in Right are | ||
+ | preceded by elements with no matches. | ||
+ | SQL equivalent: outer left join (or simply left join) | ||
+ | |||
+ | AllInRight is similar to AllInLeft. | ||
+ | |||
+ | OnlyIfInBoth will cause all elements from Left to be placed in the output, only if there is at least one | ||
+ | match in Right. | ||
+ | SQL equivalent: inner join (or simply join) | ||
+ | | ||
+ | AllInBoth will have all entries in right and left in the output. Specifically, | ||
+ | in right with at least one match in left, followed by all entries in Right with no matches in left, | ||
+ | followed by all entries in Left with no matches in Right. | ||
+ | SQL equivalent: full join | ||
+ | |||
+ | .EXAMPLE | ||
+ | # | ||
+ | #Define some input data. | ||
+ | |||
+ | $l = 1..5 | Foreach-Object { | ||
+ | [pscustomobject]@{ | ||
+ | Name = " | ||
+ | Birthday = (Get-Date).adddays(-1) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $r = 4..7 | Foreach-Object{ | ||
+ | [pscustomobject]@{ | ||
+ | Department = " | ||
+ | Name = " | ||
+ | Manager = " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #We have a name and Birthday for each manager, how do we find their department, using an inner join? | ||
+ | Join-Object -Left $l -Right $r -LeftJoinProperty Name -RightJoinProperty Manager -Type OnlyIfInBoth -RightProperties Department | ||
+ | |||
+ | |||
+ | # Name Birthday Department | ||
+ | # ---- -------- ---------- | ||
+ | # jsmith4 4/14/2015 3:27:22 PM Department 4 | ||
+ | # jsmith5 4/14/2015 3:27:22 PM Department 5 | ||
+ | |||
+ | .EXAMPLE | ||
+ | # | ||
+ | #Define some input data. | ||
+ | |||
+ | $l = 1..5 | Foreach-Object { | ||
+ | [pscustomobject]@{ | ||
+ | Name = " | ||
+ | Birthday = (Get-Date).adddays(-1) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $r = 4..7 | Foreach-Object{ | ||
+ | [pscustomobject]@{ | ||
+ | Department = " | ||
+ | Name = " | ||
+ | Manager = " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #We have a name and Birthday for each manager, how do we find all related department data, even if there are conflicting properties? | ||
+ | $l | Join-Object -Right $r -LeftJoinProperty Name -RightJoinProperty Manager -Type AllInLeft -Prefix j_ | ||
+ | |||
+ | # Name Birthday j_Department j_Name j_Manager | ||
+ | # ---- -------- ------------ ------ --------- | ||
+ | # jsmith1 4/14/2015 3:27:22 PM | ||
+ | # jsmith2 4/14/2015 3:27:22 PM | ||
+ | # jsmith3 4/14/2015 3:27:22 PM | ||
+ | # jsmith4 4/14/2015 3:27:22 PM Department 4 Department 4 jsmith4 | ||
+ | # jsmith5 4/14/2015 3:27:22 PM Department 5 Department 5 jsmith5 | ||
+ | |||
+ | .EXAMPLE | ||
+ | # | ||
+ | #Hey! You know how to script right? Can you merge these two CSVs, where Path1' | ||
+ | |||
+ | #Get CSV data | ||
+ | $s1 = Import-CSV $Path1 | ||
+ | $s2 = Import-CSV $Path2 | ||
+ | |||
+ | #Merge the data, using a full outer join to avoid omitting anything, and export it | ||
+ | Join-Object -Left $s1 -Right $s2 -LeftJoinProperty IP_ADDRESS -RightJoinProperty IP -Prefix ' | ||
+ | Export-CSV $MergePath -NoTypeInformation | ||
+ | |||
+ | .EXAMPLE | ||
+ | # | ||
+ | # "Hey Warren, we need to match up SSNs to Active Directory users, and check if they are enabled or not. | ||
+ | # I'll e-mail you an unencrypted CSV with all the SSNs from gmail, what could go wrong?" | ||
+ | |||
+ | # Import some SSNs. | ||
+ | $SSNs = Import-CSV -Path D:\SSNs.csv | ||
+ | |||
+ | #Get AD users, and match up by a common value, samaccountname in this case: | ||
+ | Get-ADUser -Filter " | ||
+ | Join-Object -LeftJoinProperty samaccountname -Right $SSNs ` | ||
+ | -RightJoinProperty samaccountname -RightProperties ssn ` | ||
+ | -LeftProperties samaccountname, | ||
+ | |||
+ | .NOTES | ||
+ | This borrows from: | ||
+ | Dave Wyatt' | ||
+ | Lucio Silveira' | ||
+ | |||
+ | Changes: | ||
+ | Always display full set of properties | ||
+ | Display properties in order (left first, right second) | ||
+ | If specified, add suffix or prefix to right object property names to avoid collisions | ||
+ | Use a hashtable rather than ordereddictionary (avoid case sensitivity) | ||
+ | |||
+ | .LINK | ||
+ | http:// | ||
+ | |||
+ | .FUNCTIONALITY | ||
+ | PowerShell Language | ||
+ | |||
+ | #> | ||
+ | [CmdletBinding()] | ||
+ | Param | ||
+ | ( | ||
+ | [Parameter(Mandatory=$true, | ||
+ | | ||
+ | [object[]] $Left, | ||
+ | |||
+ | # List to join with $Left | ||
+ | [Parameter(Mandatory=$true)] | ||
+ | [object[]] $Right, | ||
+ | |||
+ | [Parameter(Mandatory = $true)] | ||
+ | [string] $LeftJoinProperty, | ||
+ | |||
+ | [Parameter(Mandatory = $true)] | ||
+ | [string] $RightJoinProperty, | ||
+ | |||
+ | [object[]]$LeftProperties = ' | ||
+ | |||
+ | # Properties from $Right we want in the output. | ||
+ | # Like LeftProperties, | ||
+ | [object[]]$RightProperties = ' | ||
+ | |||
+ | [validateset( ' | ||
+ | [Parameter(Mandatory=$false)] | ||
+ | [string]$Type = ' | ||
+ | |||
+ | [string]$Prefix, | ||
+ | [string]$Suffix | ||
+ | ) | ||
+ | Begin | ||
+ | { | ||
+ | function AddItemProperties($item, | ||
+ | { | ||
+ | if ($null -eq $item) | ||
+ | { | ||
+ | return | ||
+ | } | ||
+ | |||
+ | foreach($property in $properties) | ||
+ | { | ||
+ | $propertyHash = $property -as [hashtable] | ||
+ | if($null -ne $propertyHash) | ||
+ | { | ||
+ | $hashName = $propertyHash[" | ||
+ | $expression = $propertyHash[" | ||
+ | |||
+ | $expressionValue = $expression.Invoke($item)[0] | ||
+ | | ||
+ | $hash[$hashName] = $expressionValue | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | foreach($itemProperty in $item.psobject.Properties) | ||
+ | { | ||
+ | if ($itemProperty.Name -like $property) | ||
+ | { | ||
+ | $hash[$itemProperty.Name] = $itemProperty.Value | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function TranslateProperties | ||
+ | { | ||
+ | [cmdletbinding()] | ||
+ | param( | ||
+ | [object[]]$Properties, | ||
+ | [psobject]$RealObject, | ||
+ | [string]$Side) | ||
+ | |||
+ | foreach($Prop in $Properties) | ||
+ | { | ||
+ | $propertyHash = $Prop -as [hashtable] | ||
+ | if($null -ne $propertyHash) | ||
+ | { | ||
+ | $hashName = $propertyHash[" | ||
+ | $expression = $propertyHash[" | ||
+ | |||
+ | $ScriptString = $expression.tostring() | ||
+ | if($ScriptString -notmatch ' | ||
+ | { | ||
+ | Write-Verbose " | ||
+ | $Expression = [ScriptBlock]:: | ||
+ | } | ||
+ | | ||
+ | $Output = @{Name =$HashName; Expression = $Expression } | ||
+ | Write-Verbose "Found $Side property hash with name $($Output.Name), | ||
+ | $Output | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | foreach($ThisProp in $RealObject.psobject.Properties) | ||
+ | { | ||
+ | if ($ThisProp.Name -like $Prop) | ||
+ | { | ||
+ | Write-Verbose "Found $Side property ' | ||
+ | $ThisProp.Name | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | function WriteJoinObjectOutput($leftItem, | ||
+ | { | ||
+ | $properties = @{} | ||
+ | |||
+ | AddItemProperties $leftItem $leftProperties $properties | ||
+ | AddItemProperties $rightItem $rightProperties $properties | ||
+ | |||
+ | New-Object psobject -Property $properties | ||
+ | } | ||
+ | |||
+ | #Translate variations on calculated properties. Doing this once shouldn' | ||
+ | foreach($Prop in @($LeftProperties + $RightProperties)) | ||
+ | { | ||
+ | if($Prop -as [hashtable]) | ||
+ | { | ||
+ | foreach($variation in (' | ||
+ | { | ||
+ | if(-not $Prop.ContainsKey(' | ||
+ | { | ||
+ | if($Prop.ContainsKey($variation) ) | ||
+ | { | ||
+ | $Prop.Add(' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | if(-not $Prop.ContainsKey(' | ||
+ | { | ||
+ | Throw " | ||
+ | } | ||
+ | |||
+ | |||
+ | if(-not $Prop.ContainsKey(' | ||
+ | { | ||
+ | if($Prop.ContainsKey(' | ||
+ | { | ||
+ | $Prop.Add(' | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | if(-not $Prop.ContainsKey(' | ||
+ | { | ||
+ | Throw " | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $leftHash = @{} | ||
+ | $rightHash = @{} | ||
+ | |||
+ | # Hashtable keys can't be null; we'll use any old object reference as a placeholder if needed. | ||
+ | $nullKey = New-Object psobject | ||
+ | | ||
+ | $bound = $PSBoundParameters.keys -contains " | ||
+ | if(-not $bound) | ||
+ | { | ||
+ | [System.Collections.ArrayList]$LeftData = @() | ||
+ | } | ||
+ | } | ||
+ | Process | ||
+ | { | ||
+ | #We pull all the data for comparison later, no streaming | ||
+ | if($bound) | ||
+ | { | ||
+ | $LeftData = $Left | ||
+ | } | ||
+ | Else | ||
+ | { | ||
+ | foreach($Object in $Left) | ||
+ | { | ||
+ | [void]$LeftData.add($Object) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | End | ||
+ | { | ||
+ | foreach ($item in $Right) | ||
+ | { | ||
+ | $key = $item.$RightJoinProperty | ||
+ | |||
+ | if ($null -eq $key) | ||
+ | { | ||
+ | $key = $nullKey | ||
+ | } | ||
+ | |||
+ | $bucket = $rightHash[$key] | ||
+ | |||
+ | if ($null -eq $bucket) | ||
+ | { | ||
+ | $bucket = New-Object System.Collections.ArrayList | ||
+ | $rightHash.Add($key, | ||
+ | } | ||
+ | |||
+ | $null = $bucket.Add($item) | ||
+ | } | ||
+ | |||
+ | foreach ($item in $LeftData) | ||
+ | { | ||
+ | $key = $item.$LeftJoinProperty | ||
+ | |||
+ | if ($null -eq $key) | ||
+ | { | ||
+ | $key = $nullKey | ||
+ | } | ||
+ | |||
+ | $bucket = $leftHash[$key] | ||
+ | |||
+ | if ($null -eq $bucket) | ||
+ | { | ||
+ | $bucket = New-Object System.Collections.ArrayList | ||
+ | $leftHash.Add($key, | ||
+ | } | ||
+ | |||
+ | $null = $bucket.Add($item) | ||
+ | } | ||
+ | |||
+ | $LeftProperties = TranslateProperties -Properties $LeftProperties -Side ' | ||
+ | $RightProperties = TranslateProperties -Properties $RightProperties -Side ' | ||
+ | |||
+ | #I prefer ordered output. Left properties first. | ||
+ | [string[]]$AllProps = $LeftProperties | ||
+ | |||
+ | #Handle prefixes, suffixes, and building AllProps with Name only | ||
+ | $RightProperties = foreach($RightProp in $RightProperties) | ||
+ | { | ||
+ | if(-not ($RightProp -as [Hashtable])) | ||
+ | { | ||
+ | Write-Verbose " | ||
+ | @{ | ||
+ | Name=" | ||
+ | Expression=[scriptblock]:: | ||
+ | } | ||
+ | $AllProps += " | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Write-Verbose " | ||
+ | $AllProps += [string]$RightProp[" | ||
+ | $RightProp | ||
+ | } | ||
+ | } | ||
+ | |||
+ | $AllProps = $AllProps | Select -Unique | ||
+ | |||
+ | Write-Verbose " | ||
+ | |||
+ | foreach ( $entry in $leftHash.GetEnumerator() ) | ||
+ | { | ||
+ | $key = $entry.Key | ||
+ | $leftBucket = $entry.Value | ||
+ | |||
+ | $rightBucket = $rightHash[$key] | ||
+ | |||
+ | if ($null -eq $rightBucket) | ||
+ | { | ||
+ | if ($Type -eq ' | ||
+ | { | ||
+ | foreach ($leftItem in $leftBucket) | ||
+ | { | ||
+ | WriteJoinObjectOutput $leftItem $null $LeftProperties $RightProperties | Select $AllProps | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | foreach ($leftItem in $leftBucket) | ||
+ | { | ||
+ | foreach ($rightItem in $rightBucket) | ||
+ | { | ||
+ | WriteJoinObjectOutput $leftItem $rightItem $LeftProperties $RightProperties | Select $AllProps | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if ($Type -eq ' | ||
+ | { | ||
+ | foreach ($entry in $rightHash.GetEnumerator()) | ||
+ | { | ||
+ | $key = $entry.Key | ||
+ | $rightBucket = $entry.Value | ||
+ | |||
+ | $leftBucket = $leftHash[$key] | ||
+ | |||
+ | if ($null -eq $leftBucket) | ||
+ | { | ||
+ | foreach ($rightItem in $rightBucket) | ||
+ | { | ||
+ | WriteJoinObjectOutput $null $rightItem $LeftProperties $RightProperties | Select $AllProps | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | #region Übungen | ||
+ | |||
+ | $request = Invoke-WebRequest -Uri " | ||
+ | $xImages = [xml]$request.Content | ||
+ | $xImages.images.image.url | ||
+ | $xImages.images.image.copyright | ||
+ | $url2 = " | ||
+ | Invoke-WebRequest -Uri $url2 -OutFile C: | ||
+ | |||
+ | |||
+ | |||
+ | # Alle *.temp löschen die älter sind als 1 Minuten | ||
+ | |||
+ | |||
+ | |||
+ | <# | ||
+ | ÜBUNG | ||
+ | 1.) Für den aktuellen Benutzer einen Schlüssel erstellen " | ||
+ | 2.) Eigenschaft Erstellungsdatum mit Datum von heute | ||
+ | 2.) NUR das Datum anzeigen lassen und darauf 5 Monate addieren | ||
+ | #> | ||
+ | |||
+ | |||
+ | <# | ||
+ | ÜBUNG "Was kann ich mit Datei-Objekten anfangen" | ||
+ | |||
+ | a) Finden Sie alle (auch Versteckte) große (> 5MB) Dateien | ||
+ | in c:\temp und Unterordner um diese zu löschen. | ||
+ | b) Kürzen Sie den Aufruf auf ein maximum | ||
+ | C) Finden Sie zum löschen eine Variante als CmdLet | ||
+ | |||
+ | Hinweise: | ||
+ | a) Get-ChildItem findet NUR ALLE Dateien auch in Unterordner (siehe Hilfe) | ||
+ | b) Erstellen Sie für Test-Zwecke z.B. große TXT-Dateien in den o.a. Ordnern | ||
+ | c) Das Where-Object filtert z.B. nach Datei-Größe | ||
+ | d) Get-Member zeigt Ihnen welche Eigenschaft die Größe (in Byte) enthält | ||
+ | e) Get-Member zeigt Ihnen die Methode zum löschen | ||
+ | f) ()-Paar spielt eine entscheidente Rolle | ||
+ | #> | ||
+ | |||
+ | <# | ||
+ | ÜBUNG "Was kann ich mit Datei-Objekten anfangen" | ||
+ | |||
+ | a) Finden Sie alle (auch Versteckte) große (> 5MB) Dateien | ||
+ | in c:\temp und Unterordner um diese zu löschen. | ||
+ | b) Kürzen Sie den Aufruf auf ein maximum | ||
+ | C) Finden Sie zum löschen eine Variante als CmdLet | ||
+ | |||
+ | Hinweise: | ||
+ | a) Get-ChildItem findet NUR ALLE Dateien auch in Unterordner (siehe Hilfe) | ||
+ | b) Erstellen Sie für Test-Zwecke z.B. große TXT-Dateien in den o.a. Ordnern | ||
+ | c) Das Where-Object filtert z.B. nach Datei-Größe | ||
+ | d) Get-Member zeigt Ihnen welche Eigenschaft die Größe (in Byte) enthält | ||
+ | e) Get-Member zeigt Ihnen die Methode zum löschen | ||
+ | f) ()-Paar spielt eine entscheidente Rolle | ||
+ | #> | ||
+ | |||
+ | <# | ||
+ | ÜBUNG: " | ||
+ | |||
+ | a) Finden Sie alle Schlüssel die mit Run beginnen in HKey Current User | ||
+ | b) Finden Sie alle Schlüssel die mit Run beginnen in HKey Current User | ||
+ | und HKey Local Machine AUF EINMAL !!!! | ||
+ | |||
+ | HINWEISE | ||
+ | Get-PSDrive, | ||
+ | führen zum Erfolg !!! | ||
+ | | ||
+ | #> | ||
+ | |||
+ | <# | ||
+ | ÜBUNG: " | ||
+ | |||
+ | a) Ist das ActiveDirectory Modul installiert? | ||
+ | b) Wie lautet das CmdLet um einen Benutzer im AD zu ändern? | ||
+ | n) Wieviele CmdLets aus dem ActiveDirectory-Modul gibt es? | ||
+ | #> | ||
+ | |||
+ | <# | ||
+ | ÜBUNG: " | ||
+ | |||
+ | (PowerShell Community Extensions) http:// | ||
+ | |||
+ | a) Installieren Sie das PSCX-Modul | ||
+ | b) Welche sinnvollen CmdLets enthält diese Modul für SIE? | ||
+ | #> | ||
+ | |||
+ | <# | ||
+ | ÜBUNG " | ||
+ | |||
+ | a) Sammeln Sie von min. 2 Remotecomputern die MAC-Adresse über das | ||
+ | | ||
+ | b) und geben eine Tabelle zurück mit den Spalten für | ||
+ | PowerShell-RemoteComputername, | ||
+ | ComputerNamen und | ||
+ | MAC-Adresse | ||
+ | c) Die MAC-Adresse soll ohne " | ||
+ | #> | ||
+ | #endregion | ||
+ | |||
+ | |||
+ | #endregion | ||
</ | </ | ||
=====Links===== | =====Links===== |