1 Einleitung

In diesem Kapitel möchte ich zeigen, wie man mit der Powershell und WindowsBoardmitteln einen Rechner untersuchen kann, ob dieser ein ungewöhnliches Verhalten zeigt. Als ungewöhnlich definiere ich

             Netzwerkverbindungen von und zu verdächtigen Web-/ IP-Adressen, ausgelöst von möglicherweise verdächtigen Prozessen

 

2 Netzwerkverbindungen analysieren

Hat man sich mal Schadsoftware auf seinen Rechner eingefangen, so kann diese auf verschiedenste Arten tätig werden. Im aktiven Netzwerkverkehr kann der Eindringling an den Parametern "ungewöhnlicher Prozess im Betriebssystem" und "Verbindungen zu RemoteIP-Adressen" aufgefunden werden. Je nachdem welche Power im Backoffice des Rechners bereitsteht, können (sollten) Firewalls und verschiedene Auditingsysteme erkennen können, wenn ein korrumpierter Rechner sich im Netzwerk merkwürdig verhält.

 

Mit reinen Powershellmitteln kann man aber auch -zumindest in begrenztem Ausmaß- die Netzwerkaktivitäten seines Rechners beobachten und analysieren. 

 

2.1 momentan aktive TCP/IP-Verbindungen

Ein nützliches und nativ verfügbares Tool ist "Netstat" oder "netstat -aon". Damit lassen sich die aktuellen Netzwerkverbindungen auf einem Rechner anzeigen.

 

Beispiel 1: Überblick über aktuelle Netzverbindungen mit "netstat -aon"

netstat -aon | Select -First 8
Active Connections
 
  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       896
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:2179           0.0.0.0:0              LISTENING       1992
  TCP    0.0.0.0:2869           0.0.0.0:0              LISTENING       4

Ein wichtiges Alleinstellungsmerkmal (soweit mir bekannt) ist die Ausgabe der ProzessID (PID) zu jeder Verbindung. Über Get-Process oder den Taskmanager, die beide die PID und den zugehörigen Prozessnamen anzeigen,  kann man damit auf den Prozess schließen.

Der Nachteil liegt darin, dass bei älteren CommaindlineTools wie Netstat die Ausgabe als Text und nicht objektorientiert erfolgt.

 

Beispiel 2 : Überblick über aktuelle Netzverbindungen mit der Klasse "GetIPGlobalProperties"

Genau andersrum verhält es sich beim Einsatz von .Net Klassen

Clear-Host
Set-StrictMode -Version "2.0"
 
$IPProperties =  [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
$ActiveTCPConnections = $($IPProperties.GetActiveTcpConnections()) 
 
$PSOTable = $ActiveTCPConnections | Foreach{
$RemoteAddress = $($_.RemoteEndPoint).Address.IPAddressToString
$LocalAddress = $($_.LocalEndPoint).Address.IPAddressToString
   If ($RemoteAddress -ne $LocalAddress){
     New-Object PSObject -Property `
        @{"State" = $_.State;
          "RemoteAddress"  =  $($_.RemoteEndPoint).Address.IPAddressToString;  
          "LocalAddress" = $($_.LocalEndPoint).Address.IPAddressToString;
          "RemotePort" = $($_.RemoteEndPoint).Port;
          "LocalPort" = $($_.LocalEndPoint).Port;
          "TimeStamp" = $([System.DateTime]::Now);
         }#PSObject
      }#Endif
    }#ForEach
 
#Output 
$myFormat = @{Label = "State"          ; Expression = {"{0}" -f $($_.State)}        ; Align = "Left" },
            @{Label = "LocalAddress"   ; Expression = {"{0}" -f $($_.LocalAddress)} ; Align = "Left" },
            @{Label = "LocalPort"      ; Expression = {"{0}" -f $_.LocalPort}       ; Align = "Left" },
            @{Label = "RemoteAddress"  ; Expression = {"{0}" -f $_.RemoteAddress}   ; Align = "Left" },
            @{Label = "RemotePort"     ; Expression = {"{0}" -f $_.RemotePort}      ; Align = "Left" },
            @{Label = "TimeStamp"     ; Expression = {"{0}" -f 
            $_.TimeStamp}      ; Align = "Left" }
              
 
$PSOTable | Format-Table $myFormat -AutoSize
#$ActiveTCPConnections | ft * -auto
State       LocalAddress   LocalPort RemoteAddress   RemotePort TimeStamp          
-----       ------------   --------- -------------   ---------- ---------          
Established 192.168.178.37 61941     157.55.236.109  443        20.09.2014 16:34:12
Established 192.168.178.37 62007     64.233.162.188  5228       20.09.2014 16:34:12
Established 192.168.178.37 62177     64.233.165.125  5222       20.09.2014 16:34:12
Established 192.168.178.37 62484     77.234.44.63    80         20.09.2014 16:34:12

Hier erfolgt die Ausgabe objektorientiert und man kann mit $_.RemoteEndPoint etc. wunderbar auf die einzelnen Objekte zugreifen. Dafür kommt man nicht an die PIDs der Verbindungen. 

In höheren Powershellversionen könnt ihr auch das CmdLet "Get-NetTCPConnection | ft -AutoSize" anstelle der .Net Klasse verwenden. Aber auch damit erhaltet ihr nicht die wichtige ProzessID.

 

Beispiel 3: Mit Netstat aktive Verbindungen auslesen und gegen eine aktuelle Blackliste vergleichen

Der technisch aufwändigste Teil dieses Skripts ist die Zerlegung der Ausgabe von Netstat -aon in der Function "Get-Processes", den ich von dieser Seite kopiert habe

Powershell Code Repository 3139

#get-content "http://lists.blocklist.de/lists/all.txt"
 
Set-StrictMode -Version "2.0"
Clear-Host
 
Function Main{
  $FilePath = "c:\temp\blocklist.txt"
  $Uri = "http://lists.blocklist.de/lists/all.txt"
  $Time2Update = 120
    
  $SuspiciousIPs = Get-Up2Date_Blocklist $Uri $FilePath $Time2Update
  #$SuspiciousIPs.count
 
  $SuspiciousIP_Found = 0
  $AllProcesses = Get-Processes
  Foreach ($Process in $AllProcesses){
     If ($Process.RemoteAddress -ne "0.0.0.0" -and $Process.RemoteAddress -ne '[::]' -and $Process.RemoteAddress -ne '[::1]'){
        If ($SuspiciousIPs -contains $($Process.RemoteAddress) ){
          Write-Host "Connection to an IP-address of the blocklist detected: " -BackgroundColor DarkRed  -ForegroundColor Yellow
          $($Process | Format-Table -Autosize -HideTableHeaders )
          $Found = 1
        }#if
     }#if
  }#foreach
  If ($SuspiciousIP_Found -eq 0){
     Write-Host "no suspcious IP has been found in the current $($AllProcesses.count) IP-Connections compared to the current blocklist"
     #$AllProcesses |Format-Table -AutoSize
   }
}#Main
 
Function Get-Processes{
        #see  http://poshcode.org/3139   
 
    $netstat = netstat -a -n -o
    [regex]$regexTCP = '(?<Protocol>\S+)\s+((?<LAddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<LAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<Lport>\d+)\s+((?<Raddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<RAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<RPort>\d+)\s+(?<State>\w+)\s+(?<PID>\d+$)'
    [regex]$regexUDP = '(?<Protocol>\S+)\s+((?<LAddress>(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?))|(?<LAddress>\[?[0-9a-fA-f]{0,4}(\:([0-9a-fA-f]{0,4})){1,7}\%?\d?\]))\:(?<Lport>\d+)\s+(?<RAddress>\*)\:(?<RPort>\*)\s+(?<PID>\d+)'
     
    $allprocesses = @()
     
    foreach ($net in $netstat)
    
    {
    [psobject]$process = "" | Select-Object Protocol, LocalAddress, Localport, RemoteAddress, Remoteport, State, PID, ProcessName
        switch -regex ($net.Trim())
        {
             $regexTCP
            {          
                $process.Protocol = $matches.Protocol
                $process.LocalAddress = $matches.LAddress
                $process.Localport = $matches.LPort
                $process.RemoteAddress = $matches.RAddress
                $process.Remoteport = $matches.RPort
                #$process.State = $matches.State
                $process.PID = $($matches.PID) -as [int]
                $process.ProcessName = ( Get-Process -Id $matches.PID ).ProcessName
                $allprocesses += $process
            }
            $regexUDP
            {          
                $process.Protocol = $matches.Protocol
                $process.LocalAddress = $matches.LAddress
                $process.Localport = $matches.LPort
                $process.RemoteAddress = $matches.RAddress
                $process.Remoteport = $matches.RPort
                #$process.State = $matches.State
                $process.PID = $($matches.PID) -as [int]
                $process.ProcessName = ( Get-Process -Id $matches.PID ).ProcessName
                $allprocesses += $process
            }
        }
     }
 Return ,$allprocesses
} #End Get-Processes
 
Function Get-Up2Date_Blocklist{
  Param($Uri,$FilePath,$Time2Update)
  $Request = [System.Net.WebRequest]::Create($Uri)
  $Response= $Request.GetResponse()
  $ResponseStream = $Response.GetResponseStream()
  $StreamReader = New-Object System.IO.StreamReader $ResponseStream
  
  $FileInfo = New-Object System.IO.FileInfo("$FilePath") 
  $SuspiciousIPs =@()
  If ($FileInfo.Exists -eq $False){
      Write-Host "download new blocklist in $FilePath from $uri"
      While ($StreamReader.Endofstream -eq $False){
        $Line=$StreamReader.ReadLine()
        $SuspiciousIPs += $Line
      }#While
      $SuspiciousIPs | Out-File -FilePath "C:\temp\blocklist.txt"
  }#if
  Elseif (  $([System.DateTime]::now - $($FileInfo.LastWriteTime)  ).TotalMinutes -gt $Time2Update ){
      Write-Host "download new blocklist in $FilePath from $uri"
      While ($StreamReader.Endofstream -eq $False){
        $Line=$StreamReader.ReadLine()
        $SuspiciousIPs += $Line
        }#While
         $SuspiciousIPs | Out-File -FilePath "C:\temp\blocklist.txt"
  }Else{
      Write-Host "no new blockfile has been downloaded because the existing list in $FilePath is still up to date"
      $SuspiciousIPs = Get-Content -Path $FilePath
  }
 
 Return ,$SuspiciousIPs
}#End Get-NewBlocklist
 
Main

#mögliche Ausgabe

 

no new blockfile has been downloaded because the existing list in c:\temp\blocklist.txt is still up to date
Connection to an IP-address of the blocklist detected: 
 
TCP      192.168.178.37 52528     1.50.235.82   80               6076 chrome     
 
 
Connection to an IP-address of the blocklist detected: 
 
TCP      192.168.178.37 52529     1.50.235.82   80               6076 chrome     
 
 
Connection to an IP-address of the blocklist detected: 
 
TCP      192.168.178.37 52530     1.50.235.82   80               6076 chrome  

eine kleine Auswahl weiterer Seiten mit aktuellen schwarzen Listen an Web- und IPAdressen findet ihr hier:

www.blocklist.de:  generiert alle 30 Minuten neue Listen mit Attacker IPs der letzten 48 Stunden 

mehr solcher Seiten findet ihr unter:

Wikipedia - Comparison of DNS blacklists: eine Zusammenstellung von blacklists

 

2.2 Netzwerkverbindungen sammeln und konsolidieren

Beispiel 1: Remoteverbindungen analysieren

Download 1:_CollectConnections.ps1.txt

Download 2:_GetDNSNames.ps1.txt

 

Die beiden Skripten sind jetzt doch relativ lang, daher ladet sie euch bitte herunter. Das Skript "1_CollectConnections.ps1" sammelt mittels dem Boardmittel Netstat -AON laufend aktive Netzverbindungen ein und konsolidiert diese am Ende. Zur Analyse der Textausgabe von "Netstat -aon" benutze ich diese Source:  http://poshcode.org/2974 

 

Das Skript "2_GetDNSNames.ps1" versucht aus der erstellten XML-Datei die Remoteadressen aufzulösen. Da dieser Schritt je nach Umfang der Netzverbindungen länger dauern kann, habe ich diese Aufgabe in ein zweites Skript aufgeteilt.

 

2.3 spezifische Website checken

Von eurem Browser könnt ihr jede beliebige Website gegen die GoogleDatenbank prüfen

 

http://www.google.com/safebrowsing/diagnostic?site=powershellpraxis.de

Stand: 13.9.2014

 

Ob der Betreiber dieser Website mit diesem Ergebnis oder dessen Darstellung zufrieden ist, weiss ich nicht: 

http://www.google.com/safebrowsing/diagnostic?site=google.com

Stand: 13.9.2014

 

3 DNSResolver

Ebenfalls nützliche Auskünfte kann der DNSResolvercache geben. Seine Inhalte liefert uns der Commandline-Befehl "Ipconfig -DisplayDNS". Dieser Cache liefert die Adressen, mit denen sich unser Client versucht hat in Verbindung zu setzen.

Konfiguriert werden kann dieser Dienst in der Registry unter
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"  Technet: Configuring Caching and Negative Caching

Am HKLM-Hive sieht man, dass der ResolverCache ein maschinenweiter und kein userspezifischer Zwischenspeicher ist. Je nach Konfiguration des lokalen Resolvers und des DNSServers sind die Einträge in diesem Cache mehr oder weniger schnell wieder verschwunden.

Ein sorgfältiger Angreifer kann allerdings diesen Cache mit "ipconfig /flushdns" auch manuell leeren und so die Forensic erschweren. Aber auch nicht jeder Angreifer rechnet mit einer Resolveranalyse auf seinem Targetsystem.

 

Beispiel 1: Resolvercache anzeigen

Die wesentliche Funktion "Get.DNSClientCache" stammt von Rich Prescott aus der ScriptingGallery

Set-StrictMode -Version "2.0"
Clear-Host
   
Function Main{
   $DNSCache = Get-DNSClientCache
   $DNSCache |Sort TTL | Format-Table Name,Section,TTL,HostRecord -AutoSize
}
 
Function Get-DNSClientCache{ 
 #see http://gallery.technet.microsoft.com/scriptcenter/ad12dc1c-b0c7-44d6-97c7-1a537b0b4fef  
 $DNSCache = @() 
  
  Invoke-Expression "IPConfig /DisplayDNS" |  `
  Select-String -Pattern "Record Name|Eintragsname" -Context 0,5  `
  | %{ 
        $Record = New-Object PSObject -Property @{ 
        Name=($_.Line -Split ":")[1] 
        Type=($_.Context.PostContext[0] -Split ":")[1] 
        TTL=($_.Context.PostContext[1] -Split ":")[1] -as [int]
        Length=($_.Context.PostContext[2] -Split ":")[1] 
        Section=($_.Context.PostContext[3] -Split ":")[1] 
        HostRecord=($_.Context.PostContext[4] -Split ":")[1] 
        } 
        $DNSCache +=$Record 
    } 
    return $DNSCache 
}#end Get-DNSClientCache
 
Main   

#mögliche Ausgabe

 

Name                                     Section   TTL HostRecord
----                                     -------   --- ---------- 
 fonts.googleapis.com                     Answer    16  googleapis.l.google.com  
 googleapis.l.google.com                  Answer    16  173.194.65.95
 www.google.com                           Answer    22  173.194.44.83
 www.google.com                           Answer    22  173.194.44.84
 www.google.com                           Answer    22  173.194.44.82

 www.google.com                           Answer    22  173.194.44.81 

....

Auch hier ist es wie schon im oberen Kapitel sinnvoll aktuelle Blacklisten mit verdächtigen IPAdressen und Domänennamen lokal herunterzuladen

und gegen die lokalen Cacheeinträge zu vergleichen.

Wie das funktioniert, habe ich weiter oben in Kapitel 2.1, Beispiel 3 "Beispiel 3: Mit Netstat aktive Verbindungen auslesen und gegen eine aktuelle Blackliste vergleichen" gezeigt. Bei Gelegenheit werde ich dieses Skript hier auch noch mit damit ausstatten.

 

4 Arp Cache

Ebenfalls nützliche Daten kann der ARP-Cache enthalten, wenn man einen Zugriff auf seinen Rechner aus dem eigenen Netzsegment vermutet. Dieser Cache ist aber leider noch flüchtiger und manipulierbarer ist, als der ResolverCache ist. 

  • Invoke-Expression "ARP -a"

    #mögliche Ausgabe

     

    Interface: 192.168.178.57 --- 0x4
      Internet Address      Physical Address      Type
      192.168.178.1         c0-25-06-4a-76-c7     dynamic
      192.168.178.25        5c-f8-a1-09-65-fa     dynamic
      192.168.178.255       ff-ff-ff-ff-ff-ff     static
      ..
  •  

 

5 Netzwerliste

 

In den folgenden Registrykeys kann man herauslesen, an welchen Netzwerkzugängen der Rechner sich schonmal registriert hatte. Man erfährt unter anderem das Datum der ersten und letzten Verbindung, sowie die MAC-Addresse des Zugangspunktes.

Websiten wie WiGLE.Net (Stichwort: "Geolocation") kann man eventuell anhand der MACAdresse sogar herausfinden, wo sich der zugehörige Router befindet. Allerdings muss man sich dafür auf der Website registrieren

 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList

 

 

Mit der Powershell lassen sich diese Daten bequem auslesen

Beispiel 1: Wo ist ein Rechner am Netzwerk gewesen?

#Run as administrator
 
Set-StrictMode -Version "2.0"
Clear-Host
 
Function Main{
  $ComputerName = ""
  #$ComputerName = "Client_01" 
  $ManageKinds = @()
  $ManageKinds += "managed"
  $ManageKinds += "unmanaged"
  $RegField = "LocalMachine"
 
  $Signature_NetWorkConnections = @()
  Foreach ($ManageKind in $ManageKinds){
    $Signature_NetWorkConnections += Get-NetWorkConnections_from_Signatures $Computername $RegField $ManageKind 
  }
    
  $Profile_NetWorkConnections  = (Get-NetWorkConnections_from_Profiles $Computername $RegField) 
    
  Merge-SignatureProfiles $Signature_NetWorkConnections $Profile_NetWorkConnections
   
}#Main
 
Function Convert-Date{
  Param($TimeString)
  $elements = $TimeString -split " "
  
  $yearHex= "$([Convert]::ToString($elements[1],16))$([Convert]::ToString($elements[0],16))"
  $Year = [Convert]::ToInt32($YearHex, 16) 
  
  $MonthHex = "$([Convert]::ToString($elements[3],16))$([Convert]::ToString($elements[2],16))"
  $Month = [Convert]::ToInt32($MonthHex, 16) 
  $Month = $Month.ToString("00")
 
  $DayHex = "$([Convert]::ToString($elements[7],16))$([Convert]::ToString($elements[6],16))"
  $Day = [Convert]::ToInt32($DayHex, 16) 
  $Day = $Day.ToString("00")
 
  $HourHex = "$([Convert]::ToString($elements[9],16))$([Convert]::ToString($elements[8],16))"
  $Hour = [Convert]::ToInt32($HourHex, 16) 
  $Hour = $Hour.ToString("00")
 
  $MinuteHex = "$([Convert]::ToString($elements[11],16))$([Convert]::ToString($elements[10],16))"
  $Minute = [Convert]::ToInt32($MinuteHex, 16)
  $Minute = $Minute.ToString("00") 
 
  $SecondHex = "$([Convert]::ToString($elements[13],16))$([Convert]::ToString($elements[12],16))"
  $Second = [Convert]::ToInt32($SecondHex, 16)
  $Second = $Second.ToString("00") 
 
  $DateTime = "$Year-$Month-$Day $Hour`:$Minute`:$Second"
  Return  $DateTime
}
 
Function Convert-MacAddress{
  Param($MAcString)
  $MacAddress = ""
  $elements = $MacString -split " "
  Foreach($element in $elements){
   $Mac = $([Convert]::ToString($element,16))
   If($Mac.Length -eq 1){ $Mac = "0$Mac"}
   $MacAddress += "$Mac " 
  }
  Return $MacAddress 
}
 
Function Merge-SignatureProfiles{
  Param($PSO01,$PSO02)
  $MergedObjects = @()
  Foreach($obj01 in $PSO01){
    $MergedObject = New-Object PsObject
    #$MergedObject = $obj01 
    Foreach($obj02 in $PSO02){
      
      If($obj02.ProfileGUID -eq $($obj01.ProfileGUID)){
        $MergedObject = $obj01
        $MergedObject | Add-Member -NotePropertyName Category -NotePropertyValue $Obj02.Category
 
        $DateCreated = Convert-Date $Obj02.DateCreated
        $MergedObject | Add-Member -NotePropertyName DateCreated -NotePropertyValue $DateCreated 
           
        $DateLastConnected = Convert-Date $Obj02.DateLastConnected
        $MergedObject | Add-Member -NotePropertyName DateLastConnected -NotePropertyValue $DateLastConnected 
        
        $MergedObject | Add-Member -NotePropertyName NameType -NotePropertyValue $Obj02.NameType
        $MergedObject | Add-Member -NotePropertyName Managed -NotePropertyValue $Obj02.Managed 
      }#if 
   }#foreach02
   $MergedObjects += $MergedObject
  }#foreach01
  Return ,$MergedObjects 
}#function
 
Function Get-NetWorkConnections_from_Profiles{
  Param($Computername,$RegField)
 
  $RootType = [Microsoft.Win32.RegistryHive]::$RegField
  $RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType,$ComputerName)
  
  $Subkey ="SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles" 
  $RegKey = $RootKey.OpenSubKey($SubKey)
  $SubKeyNames = $RegKey.GetSubKeyNames()  #keys under managed or unmanaged
 
  $Networkconnections = @()
  Foreach ($SubkeyName in $SubKeyNames){
    $CompleteProfileKeyName = "$Subkey\$SubKeyname"
    $ProfileRegKey = $RootKey.OpenSubKey($CompleteProfileKeyName)
   
   $NetworkConnection = New-Object PSObject
   $NetworkConnection | Add-Member -NotePropertyName ProfileGuid -NotePropertyValue $SubKeyName
    Foreach($ValueName in $ProfileRegKey.GetValueNames()){  
      $RegKey1 = $RootKey.OpenSubKey($CompleteProfileKeyName)
      [String]$Data = $RegKey1.GetValue($ValueName)
      $Networkconnection | Add-Member -NotePropertyName $ValueName -NotePropertyValue $Data
     }#foreach valuename
   $Networkconnections += $NetworkConnection
    
   } #Foreach subKeyName
   Return ,$Networkconnections 
  }
 
Function Get-NetWorkConnections_from_Signatures{
  Param($Computername,$RegField,$ManageKind)
 
  $RootType = [Microsoft.Win32.RegistryHive]::$RegField
  $RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType,$ComputerName)
  
  $Subkey ="SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\" + $ManageKind
  $RegKey = $RootKey.OpenSubKey($SubKey)
  $SubKeyNames = $RegKey.GetSubKeyNames()  #keys under managed or unmanaged
 
  $Networkconnections = @()
  Foreach ($SubkeyName in $SubKeyNames){
    $CompleteSignatureKeyName = "$Subkey\$SubKeyname"
    $SignatureRegKey = $RootKey.OpenSubKey($CompleteSignatureKeyName)
   
   $NetworkConnection = New-Object PSObject
    Foreach($ValueName in $SignatureRegKey.GetValueNames()){  
      $RegKey1 = $RootKey.OpenSubKey($CompleteSignatureKeyName)
      
      [String]$Data = $RegKey1.GetValue($ValueName)
      If ($ValueName -eq "DefaultGatewayMac"){
         $Data = Convert-MacAddress $($RegKey1.GetValue($ValueName))
      }
 
      $Networkconnection | Add-Member -NotePropertyName $ValueName -NotePropertyValue $Data
     }#foreach valuename
    $Networkconnection | Add-Member -NotePropertyName ManageKind -NotePropertyValue $ManageKind
    $Networkconnections += $NetworkConnection
    
   } #Foreach subKeyName
   Return ,$Networkconnections 
  }
 
Main

#mögliche ausgabe

 

ProfileGuid       : {A999E4FF-F2D4-467A-A1ED-D76848CAA05C}
Description       : Netz01
Source            : 8
DnsSuffix         : fritz.box
FirstNetwork      : Netz01
DefaultGatewayMac : 00 a2 3f ee 82 a1 
ManageKind        : unmanaged
Category          : 0
DateCreated       : 2014-09-11 13:00:07
DateLastConnected : 2014-10-23 15:48:04
NameType          : 113
Managed           : 0
 
ProfileGuid       : {33B41C34-714C-4D7D-9C83-1074431A92E1}
Description       : Memory2Move-B7CA
Source            : 8
DnsSuffix         : <none>
FirstNetwork      : Memory2Move-B7CA
DefaultGatewayMac : 00 1c a1 0c b7 aa 
ManageKind        : unmanaged
Category          : 0
DateCreated       : 2014-10-23 21:45:06
DateLastConnected : 2014-10-23 22:18:49
NameType          : 71
Managed           : 0