Private/Wissen/B_Basic/B34_Remoting.ps1
<#
# Remoting PowerShell-Interaktion zwischen Client- und Remote-Hosts. Mit PowerShell 7 können folgende Remote-Host existieren: Windows, Linux und MacOS. - **Hashtags** Remoting WinRM Troubleshooting - **Version** 2020.05.23 #> # ! PowerShell-Remoting wird mittels einem WebDienst bereitgestellt. Dieser wird über den Dienst **WinRM** gesteuert (Default: StartType=Manuell, Status=Stopped) Get-Service -Name 'WinRM' | Select-Object -Property 'Name', 'Status', 'DisplayName', 'StartType' # ! In div. Nicht-Windows-Firewalls muss der Port 5985 TCP (HTTP) bzw. 5986 TCP (HTTPS) freigeschallten sein. In Windows erfolgt dies automatisch durch das aktivieren einer Regel. # TIPP - In der Praxis sollten die folgenden Schritte per GPO umgesetzt werden. # TIPP - Die PowerShell ist im System verwurzelt. Daher sorgt ein generelles Blockieren nur für scheinbare Sicherheit. Den besten Schutz versprechen letztlich die **Schutzmechanismen von PowerShell** selbst. Neben Mitteln, die den Missbrauch von PowerShell unterbinden, stehen auch solche zur Verfügung, um verdächtigen und unerwünschten Aktivitäten zu **protokollieren** und diese auf die Spur zu kommen. Weitere Details im Aufbau-Teil bzgl. ScriptBlockLogging und JEA. # READ Weiterführende und Nachschlage-Informationen: Get-Help 'about_*remote_*' Get-Command -Noun 'PSSession' #region 1. PowerShell-Remoting einrichten # ! 1.1 ALLE Netzwerkprofile müssen ungleich Public sein: Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory 'Private' -PassThru # ! 1.2 WinRM für Quell- und Zielhost aktivieren: Enable-PSRemoting # Dann auch im Public-Netzwerkprofil möglich: Enable-PSRemoting -SkipNetworkProfileCheck -Force # ! 1.3 Die Client- und Zielhost-Vertrauensstellung einrichten: Get-Item -Path 'WSMan:\localhost\Client\TrustedHosts' # TIPP DEFAULT-Value -eq "" Set-Item -Path 'WSMan:\localhost\Client\TrustedHosts' -Value '*' -Force # TIPP Alternativen sind: SqlServer01, ADS01.abc.local, 192.168.50.50, *.abc.local, 192.168.50.0, * #endregion #region 2. PowerShell-Remoting verwenden # TIPP PowerShell-Remoting-Verbindungen kommunizieren standardmäßig über HTTP. Allerdings verschlüsselt dabei WinRM die übertragenen Daten. Zusätzliche Sicherheit erlangt man speziell in Workgroups durch HTTPS. Siehe weiter unten! # ! Vorbereitung: # TODO Eigene IP-Adresse ermitteln: Get-NetIPAddress -Type 'Unicast' -AddressState 'Preferred' | Select-Object -Property IPAddress, InterfaceIndex, InterfaceAlias # TODO Ziel-Remote-Hosts, z.B. linker und rechter Nachbar: $ips = '192.168.103.102', '192.168.103.113' # ! REMOTING VERWENDEN - Simple: Enter-PSSession -ComputerName $ips[0] New-Item -Path 'C:\Temp\Attila_WasHere.Simple' -ItemType 'File' Exit-PSSession # ! REMOTING VERWENDEN - Complex: $admin = Get-Credential -Message "Anmeldung für Server X & Y" -UserName 'Administrator' # Passw0rd $serverX = New-PSSession -ComputerName $ips[0] -Credential $admin -Name 'ServerX' $serverY = New-PSSession -ComputerName $ips[1] -Credential $admin -Name 'ServerY' Get-PSSession Enter-PSSession -Session $serverX New-Item -Path 'C:\Temp\Attila_WasHere.ComplexA' -ItemType 'File' Exit-PSSession Enter-PSSession -Session $serverY New-Item -Path 'C:\Temp\Attila_WasHere.ComplexB' -ItemType 'File' Exit-PSSession Remove-PSSession -Session $serverX, $serverY Get-PSSession # ! REMOTING VERWENDEN - 1-zu-n : Invoke-Command -ComputerName $ips -ScriptBlock { Get-Process } -AsJob -JobName 'lfdProcHosts' Get-Job Receive-Job -Name 'lfdProcHosts' -Keep # TODO OPTIONAL - PowerShell Remoting dauerhaft zurückbauen und deaktivieren: Set-Item -Path 'WSMan:\localhost\Client\TrustedHosts' -Value ([string]::Empty) -Force Disable-PSRemoting -Force Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory 'Public' #endregion #region PowerShell Remoting über HTTPS # ! PowerShell Remoting über HTTPS mit einem selbstsignierten SSL-Zertifikat # ! https://www.windowspro.de/script/powershell-remoting-ueber-https-einem-selbstsignierten-ssl-zertifikat # ! https://docs.microsoft.com/de-de/powershell/scripting/learn/remoting/ssh-remoting-in-powershell-core?view=powershell-7 #endregion #region Remoting Troubleshooting # READ Weiterführende und Nachschlage-Informationen: Get-Help -Name 'about_Remote_FAQ' -ShowWindow Get-Help -Name 'about_Remote_Requirements' -ShowWindow Get-Help -Name 'about_Remote_Troubleshooting' -ShowWindow # TODO Vorbereitung: $MyTargetComputer = 'PickPick', '192.168.178.56' # ? Remote-Zugriff auf Remote-CIM möglich: Get-CimInstance -ClassName 'Win32_BIOS' -ComputerName '192.168.178.34' # ? Remoteunterstützung in der Windows-Firewall aktive (Enabled): Get-NetFirewallRule -DisplayGroup 'Remoteunterstützung' | Where-Object 'Profile' -In 'Private', 'Domain' # TODO | Set-NetFirewallRule -Enabled True # ? Namenauflösung prüfen: [System.Net.Dns]::GetHostByName($MyTargetComputer[0]) [System.Net.Dns]::GetHostByAddress($MyTargetComputer[1]) # ? Netzwerkprofil private oder Domain? Get-NetConnectionProfile | Select-Object -Property 'NetworkCategory', 'Name', 'InterfaceAlias', 'InterfaceIndex' # ? Remoteregistrierungs-Dienst (RemoteRegistry) läuft: Get-Process -ComputerName $MyTargetComputer[0] # ? Remote-Zugriff erfolgreich ? Get-Service -Name 'RemoteRegistry' -ComputerName $MyTargetComputer[0] | Select-Object -Property 'Name', 'Status', 'DisplayName', 'StartType' Set-Service -Name 'RemoteRegistry' -StartupType 'Automatic' -Status 'Running' -ComputerName $MyTargetComputer[0] -WhatIf # ? Windows Remotemanagement-Dienst (WinRM) läuft: Get-Service -Name 'WinRM' | Select-Object -Property 'Name', 'Status', 'DisplayName', 'StartType' Get-Service -Name 'WinRM' -ComputerName $MyTargetComputer[0] | Select-Object -Property 'Name', 'Status', 'DisplayName', 'StartType' # ? Korrekte und passende Credential? $cred = Get-Credential -Message 'Anmelde-Credential für Server ....' -UserName 'Administrator' $cred # ? LocalAccountTokenFilterPolicy wenn UAC an ist werden Admin-Rechte entfernt: Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' -Name 'LocalAccountTokenFilterPolicy' Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' -Name 'LocalAccountTokenFilterPolicy' -Value 1 -Type 'DWord' -WhatIf # ? Ports überprüfen: function Test-OpenPort { param ( [string]$Target='localhost' ) $ports = @" 20,FTP 21,FTP 22,SSH 23,TelNet 25,Smtp 135,RPC 137,NetBIOS-Namensauflösung 138,NetBIOS-Namensauflösung 139,NetBIOS-Namensauflösung 161,SNMP 162,SNMP 445,SMB Freigabe+ADS+CIM/WMI 464,Kerberos Change/SetPassword 5985,PowerShellRemoting (HTTP) 5986,PowerShellRemoting (HTTPS) "@ $ports | ConvertFrom-Csv -Header 'Port', 'Function' | ForEach-Object -Process { $tnc = Test-NetConnection -ComputerName $Target -Port $_.Port -WarningAction 'SilentlyContinue' return [PSCustomObject]@{ Target = $tnc.ComputerName RemoteAddress = $tnc.RemoteAddress Port = $tnc.RemotePort Function = $_.Function Status = $tnc.tcpTestSucceeded } } } Test-OpenPort -Target $MyTargetComputer[0] #endregion # TODO QUIZ - https://attilakrick.com/schlagwort/powershell-remoting/ <# TODO ÜBUNG # Übung A A1. Sammeln Sie von mindestens zwei Remote-Computern die MAC-Adressen. (OPTIONAL Die Ausgabe der MAC-Adresse sollen ohne "-" (Bindestrichen) erfolgen.) # Übung B 1. Erstellen Sie auf mindestens zwei Remote-Rechnern 2 neue lokale Benutzer MIT Passwort. 2. Überprüfen Sie ob diese neu angelegten Benutzerkonten auf dem Remote-Rechner erstellt wurden und aktiv sind. 3. Löschen Sie die gerade erstellten Benutzerkonten wieder von den Remote-Rechnern (-WhatIf). TIPPS - Get-NetAdapter; $ips; Invoke-Command; ForEach-Object ; -replace; New-LocalUser; Invoke-Command; Get-LocalUser; ConvertTo-SecureString; Remove-LocalUser; Get-Job; Receive-Job; Remove-Job #> |