Pour mes besoins de scripting, j'ai du faire un audit des connexions RDP en cours sur un serveur sous Windows 2008R2...

Le principal problème étant qu 'une commande de Netstat n'étant pas (à ma connaissance) nativement intégrée dans Powershell, j'ai du créer une fonction qui me permet d'interpreter les résultats de la commande issue de cmd "netstat" pour pouvoir faire ensuite des requêtes.

Il s'agit la d'une interpretation et d'un parsing de texte issu de la commande, si quelqu'un possède une façon tierce de faire cela, je suis preneur!

Vous pouvez télécharger le script depuis mon dépot git personnel.

function get-netstat
{
#definition des paramètres servant aux requetes 
param($port_local="*",$adresse_locale="*",$adresse_distante="*",$port_distant="*",[string]$Connection_Status="*")

#vérification de la validité des entrées
if ($port_local -ne '*')
    {
    if ($port_local -as [int] -is [int])
        {[int]$port_local = $port_local}
        else { throw("Port local non valide")}
    }

if ($port_distant -ne '*')
    {
    if ($port_distant -as [int] -is [int])
        {[int]$port_distant = $port_distant}
        else { throw("Port distant non valide")}

    }

if ($adresse_distante -ne '*') 
    {
    if ($adresse_distante -as [Net.IPAddress] -is [Net.IPAddress])
            {[Net.IPAddress]$adresse_distante =$adresse_distante}
            else { throw("Adresse distante non valide")}
    }
if ($adresse_locale -ne '*') 
    {
    if ($adresse_locale -as [Net.IPAddress] -is [Net.IPAddress])
            {[Net.IPAddress]$adresse_locale =$adresse_locale}
            else { throw("Adresse locale non valide")}  
    }

$netstat = netstat -n

#on saute les 4 premières lignes pour éviter le texte de présentation des résultats de la commande netstat -n
$netstat = $netstat | Select-Object -Skip 4

#on modifie chaque ligne pour faire disparaitre les espaces surnuméraires
$resultat = @()
foreach ($entry in $netstat)
{

    $entry = $entry.replace("    "," ")
    $entry = $entry.replace("   "," ")
    $entry = $entry.replace("  "," ")
    $entry = $entry.replace("  "," ")

#cette entrée compte aussi les espaces insécables (alt+255)
    $entry = $entry.replace(" "," ")

#création d'un objet qui va recueillir les proprietés de la ligne en cours
    $ajout = New-Object Psobject

#on coupe à l'espace, et l'on ne prend pas en compte la première entrée qui correspond à l'espace avant le protocole
    $entry = $entry.Split(" ") | Select-Object -Skip 1

#on sépare l'ip du port en prenant du début jusqu'à la dernière occurence du caractère ":" (séparer juste à ":" sans prendre la dernière occurence pose problème sur de l'ipv6
    [string]$adresselocale = $entry[1].substring(0,$entry[1].lastindexof(":"))
    [string]$adressedistante = $entry[2].substring(0,$entry[2].lastindexof(":"))

#de même pour le port, on prend la chaine allant du dernier ":" jusqu'a la fin. L'ajustement +1 / -1 est fait car la valeur "length" commence à 1, alors que l'indexation des caractères commence à 0
    $portlocal = $entry[1].substring($entry[1].lastindexof(":")+1,$entry[1].length - $entry[1].lastindexof(":")-1)
    $portdistant = $entry[2].substring($entry[2].lastindexof(":")+1,$entry[2].length - $entry[2].lastindexof(":")-1)

#si c'est une IPV6, l'adresse est entre [], il faut les retirer pour pouvoir avoir une info utilisable
    if ($adresselocale.Chars(0) -eq "[")
        {
        $adresselocale = $adresselocale.Remove(0,1)
        $adresselocale = $adresselocale.Remove($adresselocale.Length - 1,1)

#Une fois que l'on a ôté les caractères superflus, la variable peut être enregistrée sous le format [Net.IPAdress]
        [Net.IPAddress]$adresselocale = $adresselocale
        $adressedistante = $adressedistante.Remove(0,1)
        $adressedistante = $adressedistante.Remove($adressedistante.Length - 1,1)
        [Net.IPAddress]$adressedistante = $adressedistante

        }
#on ajoute chacune des valeurs à l'objet...
        $ajout | add-member -MemberType NoteProperty -Name "Protocole" -Value $entry[0]
        $ajout | add-member -MemberType NoteProperty -Name "Adresse_locale" -Value $adresselocale
        $ajout | add-member -MemberType NoteProperty -Name "Port_local" -Value $portlocal
        $ajout | add-member -MemberType NoteProperty -Name "Adresse_distante" -Value $adressedistante
        $ajout | add-member -MemberType NoteProperty -Name "Port_distant" -Value $portdistant
        $ajout | add-member -MemberType NoteProperty -Name "status" -Value $entry[3]

# ... que l'on ajoute ensuite au tableau...
    $resultat += $ajout
    }

# ... dans lequel on filtre ensuite en fonction de ce qui a été demandé. Si les propriétés ne sont pas renseignées, elles sont de valeur "*", ce qui permet de renvoyer tout ce qui n'est pas précisé

$retour = $resultat | Where-Object {($_.port_local -like $port_local) -and ($_.adresse_locale -like $adresse_locale) -and ($_.adresse_distante -like $adresse_distante) -and ($_.port_distant -like $port_distant) -and ($_.status -like $connection_status)}

    return $retour 
}

Ainsi, nous pourrons faire une requête de ce format :

requete

Et d'avoir un résultat de ce format :

resultat

L'avantage est que les valeurs sont enregistrées avec leurs propriétés. Ainsi, si vous avez mis le résultat dans la commande dans la variable $toto , en choisissant $toto.port_local , vous aurez le résultat : 18145

Ajouter un commentaire

Article précédent Article suivant