{"id":353617,"date":"2024-09-26T14:45:45","date_gmt":"2024-09-26T14:45:45","guid":{"rendered":"https:\/\/www.ninjaone.com\/script-hub\/monitoring-von-tcp-und-udp\/"},"modified":"2024-10-13T19:02:44","modified_gmt":"2024-10-13T19:02:44","slug":"monitoring-von-tcp-und-udp","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/de\/script-hub\/monitoring-von-tcp-und-udp\/","title":{"rendered":"Wie man TCP- und UDP-Verbindungen unter Windows mit PowerShell \u00fcberwacht"},"content":{"rendered":"<p>In der sich st\u00e4ndig weiterentwickelnden Welt der IT-Sicherheit ist es von entscheidender Bedeutung, den \u00dcberblick \u00fcber die Netzwerkverbindungen zu behalten. Ganz gleich, ob Sie ein gro\u00dfes Unternehmensnetzwerk verwalten oder ein kleines bis mittleres Unternehmen beaufsichtigen, es ist wichtig zu wissen, welche<a href=\"https:\/\/www.ninjaone.com\/it-hub\/it-service-management\/what-is-an-ip-address\/\" target=\"_blank\" rel=\"noopener\"> IP-Adressen<\/a> aktiv mit Ihren Systemen kommunizieren.<\/p>\n<p>In diesem Blogbeitrag wird ein spezielles <a href=\"https:\/\/www.ninjaone.com\/it-hub\/endpoint-management\/what-is-powershell\/\" target=\"_blank\" rel=\"noopener\">PowerShell-Skript<\/a> vorgestellt, das Administratoren vor bestimmten IP-Adressen warnt, die entweder Listening-IP-Adressen sind oder sich in einem etablierten Status befinden. Dieses Tool ist von unsch\u00e4tzbarem Wert f\u00fcr IT-Experten, <a href=\"https:\/\/www.ninjaone.com\/de\/was-ist-ein-msp\" target=\"_blank\" rel=\"noopener\">Managed Service Provider (MSPs)<\/a> und Sicherheitsteams, die ihre Netzwerk\u00fcberwachungsfunktionen verbessern m\u00f6chten. Der folgende Inhalt erkl\u00e4rt, <strong>wie<\/strong><span class=\"TextRun SCXW103397608 BCX0\" lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW103397608 BCX0\" data-ccp-parastyle=\"heading 1\"><strong>wie man TCP- und UDP-Verbindungen unter Windows mit PowerShell \u00fcberwacht<\/strong>.<\/span><\/span><\/p>\n<h2>Verstehen des PowerShell-Skripts<\/h2>\n<p>Das bereitgestellte Skript dient als Warnmechanismus f\u00fcr Netzwerkverbindungen und identifiziert bestimmte IP-Adressen im Zustand &#8222;Listening&#8220; oder &#8222;Established&#8220;. Sie geht \u00fcber grundlegende Firewall-Pr\u00fcfungen hinaus und bietet Einblicke in aktive Verbindungen, die herk\u00f6mmliche Sicherheitsfilter umgehen k\u00f6nnen. Das Skript gibt wichtige Details wie Adresse, Prozess-ID, Zustand, Protokoll, lokale Adresse und Prozessnamen aus. Bei der Verwendung von NinjaOne k\u00f6nnen die Ergebnisse automatisch in einem benutzerdefinierten Feld zur weiteren Analyse gespeichert werden.<\/p>\n<h2>Bedeutung f\u00fcr IT-Experten und MSPs<\/h2>\n<p>In der heutigen digitalen Welt, in der Cyber-Bedrohungen allgegenw\u00e4rtig sind, ist eine minuti\u00f6se Kontrolle der Netzwerkverbindungen unerl\u00e4sslich. Dieses Skript ber\u00fccksichtigt die Notwendigkeit, die Netzwerkaktivit\u00e4ten in Echtzeit zu \u00fcberwachen, sodass IT-Experten schnell auf potenzielle Sicherheitsbedrohungen reagieren k\u00f6nnen. F\u00fcr MSPs, die mehrere Kundennetzwerke verwalten, bietet dieses Skript eine standardisierte Methode zum Monitoring und zur Berichterstattung \u00fcber die Netzwerkaktivit\u00e4t und gew\u00e4hrleistet so eine einheitliche und gr\u00fcndliche \u00dcberwachung.<\/p>\n<h2>Das Skript:<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">#Requires -Version 5.1\r\n\r\n&lt;#\r\n.SYNOPSIS\r\n    Alert on specified addresses that are Listening or Established and optionally save the results to a custom field.\r\n.DESCRIPTION\r\n    Will alert on addresses, regardless if a firewall is blocking them or not.\r\n    Checks for addresses that are in a 'Listen' or 'Established' state.\r\n    UDP is a stateless protocol and will not have a state.\r\n    Outputs the addresses, process ID, state, protocol, local address, and process name.\r\n    When a Custom Field is provided this will save the results to that custom field.\r\n\r\nPARAMETER: -IpAddress \"192.168.11.1, 192.168.1.1\/24\"\r\n    A comma separated list of IP Addresses to check. Can include IPv4 CIDR notation for ranges. IPv6 CIDR notation not supported. (e.g. 192.168.1.0\/24, 10.0.10.12)\r\n.EXAMPLE\r\n    -IpAddress \"192.168.1.0\/24, 10.0.10.12\"\r\n    ## EXAMPLE OUTPUT WITH IpAddress ##\r\n    [Info] Valid IP Address: 192.168.11.1\r\n    [Info] Valid IP Network: 192.168.1.1\/24\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 139, Remote Address: 0.0.0.0, Remote Port: None, PID: 4, Protocol: TCP, State: Listen, Process: System\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 138, Remote Address: None, Remote Port: None, PID: 4, Protocol: UDP, State: None, Process: System\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 137, Remote Address: None, Remote Port: None, PID: 4, Protocol: UDP, State: None, Process: System\r\n\r\nPARAMETER: -CustomField \"ReplaceMeWithAnyMultilineCustomField\"\r\n    Name of the custom field to save the results to.\r\n.EXAMPLE\r\n    -IpAddress \"192.168.11.1, 192.168.1.1\/24\" -CustomField \"ReplaceMeWithAnyMultilineCustomField\"\r\n    ## EXAMPLE OUTPUT WITH CustomField ##\r\n    [Info] Valid IP Address: 192.168.11.1\r\n    [Info] Valid IP Network: 192.168.1.1\/24\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 139, Remote Address: 0.0.0.0, Remote Port: None, PID: 4, Protocol: TCP, State: Listen, Process: System\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 138, Remote Address: None, Remote Port: None, PID: 4, Protocol: UDP, State: None, Process: System\r\n    [Alert] Found Local Address: 192.168.1.18, Local Port: 137, Remote Address: None, Remote Port: None, PID: 4, Protocol: UDP, State: None, Process: System\r\n    \r\n    [Info] Saving results to custom field: ReplaceMeWithAnyMultilineCustomField\r\n    [Info] Results saved to custom field: ReplaceMeWithAnyMultilineCustomField\r\n.OUTPUTS\r\n    None\r\n.NOTES\r\n    Supported Operating Systems: Windows 10\/Windows Server 2016 or later with PowerShell 5.1\r\n    Release Notes: Initial Release\r\nBy using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https:\/\/www.ninjaone.com\/terms-of-use.\r\n    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. \r\n    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. \r\n    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. \r\n    Warranty Disclaimer: The script is provided \u201cas is\u201d and \u201cas available\u201d, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. \r\n    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. \r\n    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. \r\n    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).\r\n#&gt;\r\n\r\n[CmdletBinding()]\r\nparam (\r\n    [Parameter()]\r\n    [String]$IpAddress,\r\n    [String]$CustomFieldName\r\n)\r\n\r\nbegin {\r\n    function Test-IsElevated {\r\n        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()\r\n        $p = New-Object System.Security.Principal.WindowsPrincipal($id)\r\n        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)\r\n    }\r\n    function Set-NinjaProperty {\r\n        [CmdletBinding()]\r\n        Param(\r\n            [Parameter(Mandatory = $True)]\r\n            [String]$Name,\r\n            [Parameter()]\r\n            [String]$Type,\r\n            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]\r\n            $Value,\r\n            [Parameter()]\r\n            [String]$DocumentName\r\n        )\r\n    \r\n        $Characters = $Value | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n        if ($Characters -ge 10000) {\r\n            throw [System.ArgumentOutOfRangeException]::New(\"Character limit exceeded, value is greater than 10,000 characters.\")\r\n        }\r\n        \r\n        # If we're requested to set the field value for a Ninja document we'll specify it here.\r\n        $DocumentationParams = @{}\r\n        if ($DocumentName) { $DocumentationParams[\"DocumentName\"] = $DocumentName }\r\n        \r\n        # This is a list of valid fields that can be set. If no type is given, it will be assumed that the input doesn't need to be changed.\r\n        $ValidFields = \"Attachment\", \"Checkbox\", \"Date\", \"Date or Date Time\", \"Decimal\", \"Dropdown\", \"Email\", \"Integer\", \"IP Address\", \"MultiLine\", \"MultiSelect\", \"Phone\", \"Secure\", \"Text\", \"Time\", \"URL\", \"WYSIWYG\"\r\n        if ($Type -and $ValidFields -notcontains $Type) { Write-Warning \"$Type is an invalid type! Please check here for valid types. https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality\" }\r\n        \r\n        # The field below requires additional information to be set\r\n        $NeedsOptions = \"Dropdown\"\r\n        if ($DocumentName) {\r\n            if ($NeedsOptions -contains $Type) {\r\n                # We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.\r\n                $NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2&gt;&amp;1\r\n            }\r\n        }\r\n        else {\r\n            if ($NeedsOptions -contains $Type) {\r\n                $NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2&gt;&amp;1\r\n            }\r\n        }\r\n        \r\n        # If an error is received it will have an exception property, the function will exit with that error information.\r\n        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }\r\n        \r\n        # The below type's require values not typically given in order to be set. The below code will convert whatever we're given into a format ninjarmm-cli supports.\r\n        switch ($Type) {\r\n            \"Checkbox\" {\r\n                # While it's highly likely we were given a value like \"True\" or a boolean datatype it's better to be safe than sorry.\r\n                $NinjaValue = [System.Convert]::ToBoolean($Value)\r\n            }\r\n            \"Date or Date Time\" {\r\n                # Ninjarmm-cli expects the  Date-Time to be in Unix Epoch time so we'll convert it here.\r\n                $Date = (Get-Date $Value).ToUniversalTime()\r\n                $TimeSpan = New-TimeSpan (Get-Date \"1970-01-01 00:00:00\") $Date\r\n                $NinjaValue = $TimeSpan.TotalSeconds\r\n            }\r\n            \"Dropdown\" {\r\n                # Ninjarmm-cli is expecting the guid of the option we're trying to select. So we'll match up the value we were given with a guid.\r\n                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header \"GUID\", \"Name\"\r\n                $Selection = $Options | Where-Object { $_.Name -eq $Value } | Select-Object -ExpandProperty GUID\r\n        \r\n                if (-not $Selection) {\r\n                    throw [System.ArgumentOutOfRangeException]::New(\"Value is not present in dropdown\")\r\n                }\r\n        \r\n                $NinjaValue = $Selection\r\n            }\r\n            default {\r\n                # All the other types shouldn't require additional work on the input.\r\n                $NinjaValue = $Value\r\n            }\r\n        }\r\n        \r\n        # We'll need to set the field differently depending on if its a field in a Ninja Document or not.\r\n        if ($DocumentName) {\r\n            $CustomField = Ninja-Property-Docs-Set -AttributeName $Name -AttributeValue $NinjaValue @DocumentationParams 2&gt;&amp;1\r\n        }\r\n        else {\r\n            $CustomField = $NinjaValue | Ninja-Property-Set-Piped -Name $Name 2&gt;&amp;1\r\n        }\r\n        \r\n        if ($CustomField.Exception) {\r\n            throw $CustomField\r\n        }\r\n    }\r\n    function Test-IPNetwork {\r\n        param([string]$Text)\r\n        $Ip, $Prefix = $Text -split '\/'\r\n        $Ip -as [System.Net.IPAddress] -and\r\n        $Prefix -as [int] -and $Prefix -ge 0 -and $Prefix -le 32\r\n    }\r\n    function Get-IPNetwork {\r\n        [CmdletBinding()]\r\n    \r\n        Param(\r\n            [Parameter(Mandatory, Position = 0)]\r\n            [ValidateScript({ $_ -eq ([IPAddress]$_).IPAddressToString })]\r\n            [string]$IPAddress,\r\n    \r\n            [Parameter(Mandatory, Position = 1, ParameterSetName = \"SubnetMask\")]\r\n            [ValidateScript({ $_ -eq ([IPAddress]$_).IPAddressToString })]\r\n            [ValidateScript({\r\n                    $SMReversed = [IPAddress]$_\r\n                    $SMReversed = $SMReversed.GetAddressBytes()\r\n                    [array]::Reverse($SMReversed)\r\n                    [IPAddress]$SMReversed = $SMReversed\r\n                    [convert]::ToString($SMReversed.Address, 2) -match \"^[1]*0{0,}$\"\r\n                })]\r\n            [string]$SubnetMask,\r\n    \r\n            [Parameter(Mandatory, Position = 1, ParameterSetName = \"CIDRNotation\")]\r\n            [ValidateRange(0, 32)]\r\n            [int]$PrefixLength,\r\n    \r\n            [switch]$ReturnAllIPs\r\n        )\r\n    \r\n        [IPAddress]$IPAddress = $IPAddress\r\n    \r\n        if ($SubnetMask) {\r\n            [IPAddress]$SubnetMask = $SubnetMask\r\n            $SMReversed = $SubnetMask.GetAddressBytes()\r\n            [array]::Reverse($SMReversed)\r\n            [IPAddress]$SMReversed = $SMReversed\r\n    \r\n            [int]$PrefixLength = [convert]::ToString($SMReversed.Address, 2).replace(0, '').length\r\n        } \r\n        else {\r\n            [IPAddress]$SubnetMask = ([Math]::Pow(2, $PrefixLength) - 1) * [Math]::Pow(2, (32 - $PrefixLength))\r\n        }\r\n    \r\n        \r\n        $FullMask = [UInt32]'0xffffffff'\r\n        $WildcardMask = [IPAddress]($SubnetMask.Address -bxor $FullMask)\r\n        $NetworkId = [IPAddress]($IPAddress.Address -band $SubnetMask.Address)\r\n        $Broadcast = [IPAddress](($FullMask - $NetworkId.Address) -bxor $SubnetMask.Address)\r\n    \r\n        # Used for determining first usable IP Address\r\n        $FirstIPByteArray = $NetworkId.GetAddressBytes()\r\n        [Array]::Reverse($FirstIPByteArray)\r\n    \r\n        # Used for determining last usable IP Address\r\n        $LastIPByteArray = $Broadcast.GetAddressBytes()\r\n        [Array]::Reverse($LastIPByteArray)\r\n    \r\n        # Handler for \/31, \/30 CIDR prefix values, and default for all others.\r\n        switch ($PrefixLength) {\r\n            31 {\r\n                $TotalIPs = 2\r\n                $UsableIPs = 2\r\n                $FirstIP = $NetworkId\r\n                $LastIP = $Broadcast\r\n                $FirstIPInt = ([IPAddress]$FirstIPByteArray).Address\r\n                $LastIPInt = ([IPAddress]$LastIPByteArray).Address\r\n                break\r\n            }\r\n    \r\n            32 {\r\n                $TotalIPs = 1\r\n                $UsableIPs = 1\r\n                $FirstIP = $IPAddress\r\n                $LastIP = $IPAddress\r\n                $FirstIPInt = ([IPAddress]$FirstIPByteArray).Address\r\n                $LastIPInt = ([IPAddress]$LastIPByteArray).Address\r\n                break\r\n            }\r\n    \r\n            default {\r\n    \r\n                # Usable Address Space\r\n                $TotalIPs = [Math]::pow(2, (32 - $PrefixLength))\r\n                $UsableIPs = $TotalIPs - 2\r\n    \r\n                # First usable IP\r\n                $FirstIPInt = ([IPAddress]$FirstIPByteArray).Address + 1\r\n                $FirstIP = [IPAddress]$FirstIPInt\r\n                $FirstIP = ($FirstIP).GetAddressBytes()\r\n                [Array]::Reverse($FirstIP)\r\n                $FirstIP = [IPAddress]$FirstIP\r\n    \r\n                # Last usable IP\r\n                $LastIPInt = ([IPAddress]$LastIPByteArray).Address - 1\r\n                $LastIP = [IPAddress]$LastIPInt\r\n                $LastIP = ($LastIP).GetAddressBytes()\r\n                [Array]::Reverse($LastIP)\r\n                $LastIP = [IPAddress]$LastIP\r\n            }\r\n        }\r\n    \r\n        $AllIPs = if ($ReturnAllIPs) {\r\n    \r\n            if ($UsableIPs -ge 500000) {\r\n                Write-Host ('[Warn] Generating an array containing {0:N0} IPs, this may take a little while' -f $UsableIPs)\r\n            }\r\n    \r\n            $CurrentIPInt = $FirstIPInt\r\n    \r\n            Do {\r\n                $IP = [IPAddress]$CurrentIPInt\r\n                $IP = ($IP).GetAddressBytes()\r\n                [Array]::Reverse($IP) | Out-Null\r\n                $IP = ([IPAddress]$IP).IPAddressToString\r\n                $IP\r\n    \r\n                $CurrentIPInt++\r\n    \r\n            } While ($CurrentIPInt -le $LastIPInt)\r\n        }\r\n    \r\n    \r\n        $obj = [PSCustomObject]@{\r\n            NetworkId    = ($NetworkId).IPAddressToString\r\n            Broadcast    = ($Broadcast).IPAddressToString\r\n            SubnetMask   = ($SubnetMask).IPAddressToString\r\n            PrefixLength = $PrefixLength\r\n            WildcardMask = ($WildcardMask).IPAddressToString\r\n            FirstIP      = ($FirstIP).IPAddressToString\r\n            LastIP       = ($LastIP).IPAddressToString\r\n            TotalIPs     = $TotalIPs\r\n            UsableIPs    = $UsableIPs\r\n            AllIPs       = $AllIPs\r\n        }\r\n    \r\n        Write-Output $obj\r\n    }\r\n}\r\nprocess {\r\n    if (-not (Test-IsElevated)) {\r\n        Write-Error -Message \"Access Denied. Please run with Administrator privileges.\"\r\n        exit 1\r\n    }\r\n    if ($env:ipAddress -and $env:ipAddress -ne 'null') {\r\n        $IpAddress = $env:ipAddress\r\n    }\r\n    if ($env:customFieldName -and $env:customFieldName -ne 'null') {\r\n        $CustomFieldName = $env:customFieldName\r\n    }\r\n\r\n    # Parse the Addresses to check\r\n    $Addresses = if ($IpAddress) {\r\n        # Validate the IP Address\r\n        $IpAddress -split ',' | ForEach-Object {\r\n            \"$_\".Trim()\r\n        } | ForEach-Object {\r\n            if (($_ -as [System.Net.IPAddress])) {\r\n                Write-Host \"[Info] Valid IP Address: $_\"\r\n                [System.Net.IPAddress]::Parse($_)\r\n            }\r\n            elseif ($(Test-IPNetwork $_)) {\r\n                Write-Host \"[Info] Valid IP Network: $_\"\r\n                $Address, $PrefixLength = $_ -split '\/'\r\n                try {\r\n                    Get-IPNetwork -IPAddress $Address -PrefixLength $PrefixLength -ReturnAllIPs | Select-Object -ExpandProperty AllIPs\r\n                }\r\n                catch {\r\n                    Write-Host \"[Error] Invalid IP CIDR: $_\"\r\n                    exit 1\r\n                }\r\n            }\r\n            else {\r\n                Write-Host \"[Error] Invalid IP Address: $_\"\r\n                exit 1\r\n            }\r\n        }\r\n    }\r\n    else { $null }\r\n\r\n    # Get the open ports\r\n    $FoundAddresses = $(\r\n        Get-NetTCPConnection | Select-Object @(\r\n            'LocalAddress'\r\n            'LocalPort'\r\n            @{Name = \"RemoteAddress\"; Expression = { if ($_.RemoteAddress) { $_.RemoteAddress }else { \"None\" } } }\r\n            @{Name = \"RemotePort\"; Expression = { if ($_.RemotePort) { $_.RemotePort }else { \"None\" } } }\r\n            'State'\r\n            @{Name = \"Protocol\"; Expression = { \"TCP\" } }\r\n            'OwningProcess'\r\n            @{Name = \"Process\"; Expression = { (Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName } }\r\n        )\r\n        Get-NetUDPEndpoint | Select-Object @(\r\n            'LocalAddress'\r\n            'LocalPort'\r\n            @{Name = \"RemoteAddress\"; Expression = { \"None\" } }\r\n            @{Name = \"RemotePort\"; Expression = { \"None\" } }\r\n            @{Name = \"State\"; Expression = { \"None\" } }\r\n            @{Name = \"Protocol\"; Expression = { \"UDP\" } }\r\n            'OwningProcess'\r\n            @{Name = \"Process\"; Expression = { (Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName } }\r\n        )\r\n    ) | Where-Object {\r\n        $(\r\n            &lt;# When Addresses are specified select just those addresses. #&gt;\r\n            if ($Addresses) {\r\n                $_.LocalAddress -in $Addresses -or\r\n                $_.RemoteAddress -in $Addresses\r\n            }\r\n            else { $true }\r\n        ) -and\r\n        (\r\n            &lt;# Filter out anything that isn't listening or established. #&gt;\r\n            $(\r\n                $_.Protocol -eq \"TCP\" -and\r\n                $(\r\n                    $_.State -eq \"Listen\" -or\r\n                    $_.State -eq \"Established\"\r\n                )\r\n            ) -or\r\n            &lt;# UDP is stateless, return all UDP connections. #&gt;\r\n            $_.Protocol -eq \"UDP\"\r\n        )\r\n    } | Sort-Object LocalAddress, RemoteAddress | Select-Object * -Unique\r\n\r\n    if (-not $FoundAddresses -or $FoundAddresses.Count -eq 0) {\r\n        Write-Host \"[Info] No Addresses were found listening or established with the specified network or address\"\r\n    }\r\n\r\n    # Output the found Addresses\r\n    $FoundAddresses | ForEach-Object {\r\n        Write-Host \"[Alert] Found Local Address: $($_.LocalAddress), Local Port: $($_.LocalPort), Remote Address: $($_.RemoteAddress), Remote Port: $($_.RemotePort), PID: $($_.OwningProcess), Protocol: $($_.Protocol), State: $($_.State), Process: $($_.Process)\"\r\n    }\r\n    # Save the results to a custom field if one was provided\r\n    if ($CustomFieldName -and $CustomFieldName -ne 'null') {\r\n        try {\r\n            Write-Host \"[Info] Saving results to custom field: $CustomFieldName\"\r\n            Set-NinjaProperty -Name $CustomFieldName -Value $(\r\n                $FoundAddresses | ForEach-Object {\r\n                    \"Local Address: $($_.LocalAddress), Local Port: $($_.LocalPort), Remote Address: $($_.RemoteAddress), Remote Port: $($_.RemotePort), PID: $($_.OwningProcess), Protocol: $($_.Protocol), State: $($_.State), Process: $($_.Process)\"\r\n                } | Out-String\r\n            )\r\n            Write-Host \"[Info] Results saved to custom field: $CustomFieldName\"\r\n        }\r\n        catch {\r\n            Write-Host $_.Exception.Message\r\n            Write-Host \"[Warn] Failed to save results to custom field: $CustomFieldName\"\r\n            exit 1\r\n        }\r\n    }\r\n}\r\nend {\r\n    \r\n    \r\n    \r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n\n<div class=\"blog-cta-new blog-cta-style-1\"><div class=\"cta-left\"><h2><\/h2><p><\/p><\/div><div class=\"cta-right\"><a class=\"button\" href=\"\"><\/a><\/div><\/div>\n<h2>Wie das Skript funktioniert<\/h2>\n<h3><em>1. Ersteinrichtung<\/em><\/h3>\n<p>Das Skript erfordert PowerShell Version 5.1 oder h\u00f6her und ist f\u00fcr die Verwendung unter Windows 10 oder Windows Server 2016 und neuer vorgesehen. Zun\u00e4chst wird gepr\u00fcft, ob das Skript mit Administratorrechten ausgef\u00fchrt wird, die f\u00fcr den Zugriff auf Netzwerkverbindungsinformationen erforderlich sind.<\/p>\n<h3><em>2. Parsen der Parameter<\/em><\/h3>\n<p>Das Skript akzeptiert zwei Hauptparameter: -IpAddress und -CustomField. Mit dem Parameter -IpAddress k\u00f6nnen Sie eine Liste von IP-Adressen oder CIDR-notierten IP-Bereichen zur \u00dcberwachung angeben. Der Parameter -CustomField ist optional und wird verwendet, um die Ergebnisse in einem benutzerdefinierten Feld von NinjaOne zu speichern.<\/p>\n<h3><em>3. Validierung von Adressen<\/em><\/h3>\n<p>Sobald die Parameter eingegeben sind, \u00fcberpr\u00fcft das Skript jede IP-Adresse oder jeden Netzwerkbereich. Wird eine g\u00fcltige Adresse oder ein g\u00fcltiges Netzwerk gefunden, werden alle entsprechenden IPs innerhalb dieses Bereichs abgerufen.<\/p>\n<h3><em>4. Monitoring von Netzwerkverbindungen<\/em><\/h3>\n<p>Das Skript verwendet die cmdlets Get-NetTCPConnection und Get-NetUDPEndpoint, um alle aktuellen TCP- und UDP-Verbindungen auf dem System zu erfassen. Es filtert diese Verbindungen, um diejenigen zu identifizieren, die sich im &#8222;Listening&#8220;- oder &#8222;Established&#8220;-Status f\u00fcr TCP befinden, und erfasst alle UDP-Verbindungen aufgrund ihrer zustandslosen Natur.<\/p>\n<h3><em>5. Ausgabe und optionale Speicherung<\/em><\/h3>\n<p>Die identifizierten Verbindungen werden dann in einem strukturierten Format angezeigt, das Details wie lokale und entfernte Adressen, Ports, Prozess-IDs, Protokolle und Zust\u00e4nde enth\u00e4lt. Wenn ein benutzerdefiniertes Feld angegeben wird, speichert das Skript diese Ergebnisse zur sp\u00e4teren Analyse in NinjaOne.<\/p>\n<h2>Anwendungsfall: Anwendung aus der Praxis<\/h2>\n<p>Stellen Sie sich ein Szenario vor, in dem ein MSP die IT-Infrastruktur eines Finanzdienstleisters verwaltet. Das Unternehmen hat strenge Sicherheitsanforderungen und muss alle ein- und ausgehenden Verbindungen auf unbefugten Zugriff \u00fcberwachen. Der MSP setzt dieses Skript auf allen Servern und Endpunkten ein und gibt die internen IP-Bereiche des Unternehmens an, um sicherzustellen, dass nur zugelassene Ger\u00e4te mit dem Netzwerk kommunizieren. Wenn das Skript eine Verbindung von einer nicht genehmigten IP-Adresse feststellt, benachrichtigt es den Administrator, der dann sofort Ma\u00dfnahmen ergreifen kann, um das Risiko zu untersuchen und zu minimieren.<\/p>\n<h2>Vergleich mit anderen Methoden<\/h2>\n<p>W\u00e4hrend andere Tools wie Wireshark oder Netstat detaillierte Einblicke in den Netzwerkverkehr liefern k\u00f6nnen, bietet dieses PowerShell-Skript einen optimierten und automatisierten Ansatz. Im Gegensatz zu Wireshark, das eine manuelle Paketanalyse erfordert, gibt dieses Skript automatisch Warnmeldungen zu bestimmten Verbindungen aus, wodurch es f\u00fcr das laufende Monitoring geeigneter ist. Im Vergleich zu Netstat bietet das Skript einen Mehrwert, indem es Verbindungen in einem strukturierteren und besser umsetzbaren Format filtert und meldet.<\/p>\n<h2>H\u00e4ufig gestellte Fragen<\/h2>\n<h3>F: Kann dieses Skript IPv6-Adressen \u00fcberwachen?<\/h3>\n<p>A: Derzeit unterst\u00fctzt das Skript nur IPv4-Adressen und -Netze. Die Unterst\u00fctzung von IPv6 w\u00fcrde \u00c4nderungen am Skript erfordern, um das unterschiedliche Adressformat zu verarbeiten.<\/p>\n<h3>F: Was passiert, wenn eine ung\u00fcltige IP-Adresse eingegeben wird?<\/h3>\n<p>A: Das Skript enth\u00e4lt Validierungschecks und bricht die Ausf\u00fchrung ab, wenn eine ung\u00fcltige IP-Adresse oder ein ung\u00fcltiges Netzwerk festgestellt wird, und gibt den Benutzer:innen eine Fehlermeldung.<\/p>\n<h3>F: Wie werden die Ergebnisse in NinjaOne gespeichert?<\/h3>\n<p>A: Wenn der Parameter -CustomField angegeben wird, verwendet das Skript CLI von NinjaOne, um die Ergebnisse in das angegebene benutzerdefinierte Feld zu speichern. Es wird so sichergestellt, dass die <a href=\"https:\/\/www.ninjaone.com\/de\/blog\/datensicherheitskonzept-erstellung-leitfaden\/\" target=\"_blank\" rel=\"noopener\">Daten<\/a> f\u00fcr zuk\u00fcnftige Referenzen oder Berichte zug\u00e4nglich sind.<\/p>\n<h2>Auswirkung der Ergebnisse<\/h2>\n<p>Die Ausgabe dieses Skripts kann erhebliche Auswirkungen auf die IT-Sicherheit haben. Durch die Identifizierung und Benachrichtigung bei aktiven Verbindungen k\u00f6nnen IT-Experten unberechtigten Zugriff, potenzielle Malware-Kommunikation oder falsch konfigurierte Dienste schnell erkennen. Die regelm\u00e4\u00dfige Verwendung dieses Skripts verbessert die Transparenz der Netzwerkaktivit\u00e4ten und tr\u00e4gt zu einer sichereren und widerstandsf\u00e4higeren IT-Umgebung bei.<\/p>\n<h2>Best Practices f\u00fcr die Verwendung des Skripts<\/h2>\n<ol>\n<li><strong>Lassen Sie es regelm\u00e4\u00dfig laufen<\/strong>: Planen Sie die Ausf\u00fchrung des Skripts in regelm\u00e4\u00dfigen Abst\u00e4nden, um ein kontinuierliches Monitoring der Netzwerkverbindungen zu gew\u00e4hrleisten.<\/li>\n<li><strong>Integrieren Sie es mit NinjaOne<\/strong>: Nutzen Sie die M\u00f6glichkeiten von NinjaOne, um die Ergebnisse zu speichern und zu analysieren und so eine langfristige \u00dcberwachung und Trendanalyse zu erm\u00f6glichen.<\/li>\n<li><strong>Passen Sie es Ihrer Umgebung an<\/strong>: \u00c4ndern Sie das Skript nach Bedarf, um bestimmte IP-Bereiche oder zus\u00e4tzliche Protokollierungsanforderungen zu ber\u00fccksichtigen.<\/li>\n<li><strong>Testen Sie es in einer sicheren Umgebung<\/strong>: Bevor Sie das Skript in der Produktion einsetzen, testen Sie es in einer kontrollierten Umgebung, um sicher zu sein, dass es wie erwartet funktioniert.<\/li>\n<\/ol>\n<h2>Abschlie\u00dfende \u00dcberlegungen<\/h2>\n<p>Dieses PowerShell-Skript bietet eine zuverl\u00e4ssige L\u00f6sung f\u00fcr das Monitoring von TCP- und UDP-Verbindungen auf Windows-Systemen. Durch die Integration in Ihr Netzwerk\u00fcberwachungs-Toolkit, insbesondere in <a href=\"https:\/\/www.ninjaone.com\/de\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a>, k\u00f6nnen Sie mehr Transparenz und Kontrolle \u00fcber Ihre IT-Umgebung erreichen. IT-Experten und MSPs bietet dieses Skript einen praktischen Ansatz zur Sicherung der Netzwerkintegrit\u00e4t und erm\u00f6glicht proaktive Reaktionen auf potenzielle Bedrohungen.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"author":35,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","_lmt_disableupdate":"","_lmt_disable":""},"operating_system":[4212],"use_cases":[4383],"class_list":["post-353617","script_hub","type-script_hub","status-publish","hentry","script_hub_category-windows","use_cases-monitoring-de"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/script_hub\/353617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/script_hub"}],"about":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/types\/script_hub"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/comments?post=353617"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/media?parent=353617"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/operating_system?post=353617"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/de\/wp-json\/wp\/v2\/use_cases?post=353617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}