none
IP Adresse in Adressblöcke unterteilen RRS feed

  • Frage

  • Mein bisheriger Code sieht so aus:

    $sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites | Where-Object {($_.Name -ne '*******') -and ($_.Name -ne '*******')}
    $sitesubnets = @() 
    ForEach ($site in $sites)
    {
    	ForEach ($subnet in $site.subnets)
    	{
    	    $temp = New-Object PSCustomObject -Property @{
    	        'Subnetz' = $subnet
    	        'Domain' = (($site.Name).Substring(0,6) + 'S01').ToUpper()
            }
    		$sitesubnets += $temp
    	}
    }
    $sitesubnets = $sitesubnets | Sort-Object  -Property 'Domain' -Unique
    $filename = Read-Host -Prompt 'Dateiname!'
    $servercsv = Import-Csv "$filename.csv"
    $array = @()
    ForEach($s in $servercsv)
    {
        $ipdata = Test-Connection $s.Name -Count 1 | Select-Object -Property Address,IPV4Address
        $eintrag = $sitesubnets | Where-Object {$_.Domain -eq $ipdata.Address}
    	If ($eintrag.Subnetz -contains "/24")
    		{
    		[Bool]$check = 0
    		}
    	Else
    		{
    		[Bool]$check = 1
    		}
    	If($check)
    	{
    		
    	}
    	If ($eintrag)
    	{
            $temp = New-Object PSCustomObject -Property @{
                'SubnetzAD' = $eintrag.Subnetz
    	        'DomainAD' = $eintrag.Domain
                'DomainIP' = $ipdata.Address
    	        'IPAdresse' = $ipdata.IPV4Address
    			'Check' = $check
    			'Status' = ""
            }
    	    $array += $temp
        }
    }

    Die Sternchen stehen für einen bestimmten Namen der allerdings nicht relevant ist.

    Mein Problem ist jetzt, dass ich nicht weiß wie ich die ersten drei Adressblöcke der Subnetz IP und der normalen IP vergleichen kann. Die Zeilen die mir jetzt noch fehlen sollen in den If($check) Block.

    Ich habe versucht das ganze so zu lösen:

    $status = $eintrag.Subnetz.Split(".") | -eq $ipdata.IPV4Adresse


    Allerdings bekomme ich dann so eine Fehlermeldung:

    Fehler beim Aufrufen der Methode, da [System.DirectoryServices.ActiveDirectory.ActiveDirectorySubnet] keine Methode mit
     dem Namen "Split" enthält.
    Bei E:\test\new 3.ps1:33 Zeichen:35
    +         $status = $eintrag.Subnetz.Split <<<< (".") | -eq $ipdata.IPV4Adresse
        + CategoryInfo          : InvalidOperation: (Split:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    Da ich noch nicht sehr erfahren im Umgang mit PowerShell bin, bin ich auch für andere Tipps offen.

    Dienstag, 19. Juli 2016 07:24

Antworten

  • > $sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites
        TypeName: System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
     
    Die Subnetze mußt Du erst extrahieren, die stehen in $sites.Subnets und
    sind natürlich ein Objekt-Array (eine Site kann ja mehrere Subnetze
    haben...)
     
    Du landest also in zwei Foreach-Schleifen - sinngemäß:
     
    $sites | % { $_.Subnets | % { $_.Name } }
     
    Oder anders:
     
    Foreach ( $Site in $Sites ) {
        Foreach ( $Subnet in $( $Site.Subnets ) ) {
            $SubnetIP = $Subnet.Name
            # Mach irgendwas mit $SubnetIP :-)
        }
    }
     
    In neueren Posh-Versionen geht das auch direkt:
     
    $SubnetIPs = $Sites.Subnets.Name
     
    Dann hast ein Array mit allen Subnetzen aller Sites.
     
    PS: Seltsam genug, daß man zwar die Sites aus dem Forest kriegt, aber
    nicht die Subnetze :)
     
    Dienstag, 19. Juli 2016 08:27

Alle Antworten

  • Moin,

    den Punkt bei Split musst Du escapen. Versuch mal

    $eintrag.Subnetz.Split("\.") 


    Evgenij Smirnov

    msg services ag, Berlin -> http://www.msg-services.de
    my personal blog (mostly German) -> http://it-pro-berlin.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com

    In theory, there is no difference between theory and practice. In practice, there is.

    Dienstag, 19. Juli 2016 07:27
  • Danke für die schnelle Antwort aber leider hat das auch nicht funktioniert. Da kam die selbe Fehlermeldung.

    Ich denke das Problem liegt tiefer. Ich weiß zwar nicht wie diese Codezeile funktioniert, da ich sie aus dem Internet habe und sie auch nur ein Workaround ist, da die PowerShell Befehle die das selbe bewirken sollten in meiner Version nicht laufen. Ich weiß zwar was diese Zeile bewirkt aber anscheinend wird da eine Ausgabe erzeugt die vom Datentyp her kein String ist und daher nicht mit Split zusammenarbeitet.

    $sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites
    Ich vermute, dass hier in die Variable kein wirkliches Ergebnis abgelegt wird. Stattdessen scheint er bei Aufruf der Variable diese Zeile aufzurufen.

    Dienstag, 19. Juli 2016 07:43
  • Achso...

    OK, ich dachte, die Property "Subnetz" setzt Du selber (Import aus CSV), und die enthält dann einen String. Habe mir das Skript nicht wirklich angeschaut. Wenn das aber ein Subnet-Objekt ist´, brauchst Du am Anfang, wo Du die Objekte ausliest, statt

       'Subnetz' = $subnet

    eher

       'Subnetz' = $subnet.Name

    Dann wird auch das Splitten funktioneren.

    Aber ich glaube, Du solltest Dir noch einmal in Ruhe anschauen, was Du wirklich mit dem Skript bezweckst. Ich habe den Eindruck, Du gehst furchtbare Umwege auf dem Weg zu einem Ziel, das viel schneller zu erreichen ist...


    Evgenij Smirnov

    msg services ag, Berlin -> http://www.msg-services.de
    my personal blog (mostly German) -> http://it-pro-berlin.de
    Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
    Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com

    In theory, there is no difference between theory and practice. In practice, there is.

    Dienstag, 19. Juli 2016 07:57
  • Nein das wird in dieser Zeile auf "magische" Weise aus der AD gelesen. In der ersten ForEach Schleife sollte das schon so laufen wie sie das vorgeschlagen haben, wenn ich Sie richtig verstanden habe. Der Plan sieht eigentlich folgendermaßen aus. Ich habe eine CSV Liste mit den Domain Namen einiger Server. Als erstes hole ich mir eine Liste aller Domaincontroller plus deren Subnetze aus dem AD. Dann packe ich die Liste in ein Array namens $sitesubnets. Da sortiere ich einige Einträge aus und hänge an den Namen noch S01 an. Dann lade ich mir die CSV in ein Array namens $array (Ich arbeite noch an den Namen). Die Namen aus der CSV pinge ich an und schneide noch ein paar Überbleibsel von der Ausgabe ab. Über ein customObject packe ich das dann in ein Array. Dann vergleiche ich die Liste aller DC´s mit der CSV und schreibe die Übereinstimmungen in $equal. Ich weiß, dass das letzte mit Compare-Object nur ein Workaround ist um die identischen Einträge zu bekommen. Ich habe versucht das ganze mit -ExcludeDifferent zu machen aber da bekomme ich trotz der Übereinstimmung kein Output. Mein Ziel ist es eine Liste mit den DC´s und deren Adresse, welche ich durch das anpingen checke in eine Liste zu packen. In diese Liste möchte ich noch gerne die Subnetze jedes DC´s laden. Am Ende möchte ich die IP´s vom Anpingen mit den Subnetzen vergleichen und schauen ob die korrekt sind.

    Ich bin jetzt soweit, dass das alles eigentlich gut funktioniert. Ich habe über die Check Variable festgelegt bei welchen Einträgen die IP´s verglichen werden sollen.

    Falls Sie eine Idee haben wie ich einfacher an dieses Ziel komme wäre das auch gut.


    Dienstag, 19. Juli 2016 08:18
  • > $sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites
        TypeName: System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
     
    Die Subnetze mußt Du erst extrahieren, die stehen in $sites.Subnets und
    sind natürlich ein Objekt-Array (eine Site kann ja mehrere Subnetze
    haben...)
     
    Du landest also in zwei Foreach-Schleifen - sinngemäß:
     
    $sites | % { $_.Subnets | % { $_.Name } }
     
    Oder anders:
     
    Foreach ( $Site in $Sites ) {
        Foreach ( $Subnet in $( $Site.Subnets ) ) {
            $SubnetIP = $Subnet.Name
            # Mach irgendwas mit $SubnetIP :-)
        }
    }
     
    In neueren Posh-Versionen geht das auch direkt:
     
    $SubnetIPs = $Sites.Subnets.Name
     
    Dann hast ein Array mit allen Subnetzen aller Sites.
     
    PS: Seltsam genug, daß man zwar die Sites aus dem Forest kriegt, aber
    nicht die Subnetze :)
     
    Dienstag, 19. Juli 2016 08:27
  • Okay danke das klingt schon sehr gut. Da ich erst seit ein paar Tagen mit PowerShell arbeite klingt das teilweise noch unbekannt für mich. Meine erste Frage wäre ob diese Klammer in dem zweiten foreach um das $site.subnets eine Bedeutung hat? Und die zweite Frage ist wo genau der Unterschied zu der bisherigen Version liegt? Ich habe mir das bei mir noch einmal angeschaut und nur dies hier ausgeführt:

    $sites = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites | Where-Object {($_.Name -ne '*******') -and ($_.Name -ne '********')}
    $sitesubnets = @() 
    ForEach ($site in $sites)
    {
    	ForEach ($subnet in $site.subnets)
    	{
    	    $temp = New-Object PSCustomObject -Property @{
    	        'Subnetz' = $subnet
    	        'Domain' = (($site.Name).Substring(0,6) + 'S01').ToUpper()
            }
    		$sitesubnets += $temp
    	}
    }
    $sitesubnets = $sitesubnets | Sort-Object  -Property 'Domain' -Unique
    $sitesubnets

    Als Ausgabe kommt da bei mir schon eine Liste in diesem Stil heraus:

    Domain                                                      Subnetz
    ------                                                      -------
    *********                                                   **********
    *********                                                   **********
    *********                                                   **********

    Anstelle der Sternchen stehen da natürlich auch korrekte Angaben die ich auch genauso über das AD Stadorte und Dienste Tool auslesen kann. Ich denke mal mit Posh ist Powershell gemeint. Ich hab eauch schon davon gelesen, dass es diesen Bafehl gibt allerdings ist der laut meinen Infos unter Win7 nicht verfügbar. Ich habe zwar die AD Module geladen aber dieses CMDlet ist Powershell leider nicht bekannt.

    Tut mir Leid, dass ich nicht so das Verständnis habe, PowerShell ist so ziemlich mein Einstieg in Scipting Sprachen und dies auch nahezu mein erstes Script.

    Dienstag, 19. Juli 2016 08:53
  • Hallo,

    natürlich hat die Klammer eine Bedeutung (siehe das folgende Beispiel und finde den Unterschied :) )

    PS U:\> Get-Process *PowerSh*
    
    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  SI ProcessName
    -------  ------    -----      ----- -----   ------     --  -- -----------
        771      30    57916      68156 ...87     1,53   5500   5 powershell
    
    
    PS U:\> $a = Get-Process *PowerSh*
    PS U:\> Write-Host "$a.ProcessName"
    System.Diagnostics.Process (powershell).ProcessName
    PS U:\> Write-Host "$($a.ProcessName)"
    powershell
    PS U:\>

    Man spricht da von AdHoc-Variablen. Das sind aber ehere alles Posh (PowerShell) Grundlagen. Mit denen solltest du dich mal ausführlicher Beschäftigen und danach wieder an dein Projekt, dann wirds einfacher.

    Beste Gruesse
    brima

    Dienstag, 19. Juli 2016 09:28
  • > Und die zweite Frage ist wo genau der Unterschied zu der bisherigen
    > Version liegt?
     
    Hab net bis zu Ende gelesen - sorry :-(
     
    $eintrag.Subnetz.ToString().Split(".") sollte funktionieren. Tatsächlich
    ist das ja ein Subnet-Objekt und kein String...
     > gerne die Subnetze jedes DC´s laden. Am Ende möchte ich die IP´s vom
     > Anpingen mit den Subnetzen vergleichen und schauen ob die korrekt sind.
     
    Ich versteh den Zweck nicht so ganz - was genau soll das Ergebnis sein?
     
    Und vielleicht hilft das hier auch noch weiter:
     
     
     
    Dienstag, 19. Juli 2016 13:52