Add multiple instances of a noteproperty to an object

This topic contains 4 replies, has 3 voices, and was last updated by  Dave Wyatt 3 years, 8 months ago.

  • Author
    Posts
  • #13763

    Stephen Owen
    Participant

    Hello all,

    I've got a list of ADSiteNames and Subnets. My ideal output is:

    Name:       SiteName
      Subnets:       subneta
                     subnetb
                     subnetc
    

    So that I could pipe this on to a further command and do somethning with each subnet. I can't quite think of the formatting, so as I workaround I've come up with this, in which I add a SubNet$i noteproperty to the object with each iteration of a for loop. It works but is so very ugly, and working with the output later is dodgy at best.

    $sites = Import-Csv -Delimiter ";" .\AdSitestoSubnets.csv
    #$sites | Select-Object -Unique Site
    
    $unique_sites = @()
    
    ForEach ($site in ($sites | Select-Object -Unique Site)){
        
        $obj = New-Object PSObject -Property @{
                Name   = $site.site
                }
        $i = 0        
        $sites | Where-Object Site -eq $site.Site | ForEach-Object {
            $obj | Add-Member -NotePropertyName "SubNet$i" $_.SubNet
            $i++
            }
    
            $unique_sites += $obj
            
        }
    
    
    Name     : USLouisville
    SubNet0  : 10.1.128.0
    SubNet1  : 10.14.0.0
    SubNet2  : 10.16.0.0
    SubNet3  : 10.16.10.0
    SubNet4  : 10.16.10.0
    SubNet5  : 10.16.100.0
    SubNet6  : 10.16.90.0
    SubNet7  : 10.220.16.0
    SubNet8  : 10.220.18.0
    SubNet9  : 10.220.20.0
    SubNet10 : 10.220.46.0
    SubNet11 : 10.221.38.0
    SubNet12 : 10.3.0.0
    
    Name    : USHouston
    SubNet0 : 10.1.137.0
    SubNet1 : 10.220.188.0
    SubNet2 : 10.220.49.0
    
    
    

    If you have to do this task, how would you do it? I'd consider my solution to be very, very ugly, even if it works. I'm hoping you guys can show me a new construct or method of doing this.

  • #13764

    Tore Groneng
    Participant

    hi,

    Kind of hard when we don't have the "source-data" of your $sites variable 🙂 You could use the export-clixml cmdlet next time and add the xml from that as a file attatchment. That way we can import it and play with it easy.

    If I understand you correctly, here is what I would do:


    # Create dummy data
    $sites = @()
    1..2 | foreach {
    $site = "" | select Site, Subnet
    $site.site ="Houston"
    $site.Subnet = "10.0.$_.0"
    $sites += $site
    }
    1..4 | foreach {
    $site = "" | select Site, Subnet
    $site.site ="USLouisville"
    $site.Subnet = "10.$_.0.0"
    $sites += $site
    }

    $sites should now contain this:

    Site Subnet
    —- ——
    Houston 10.0.1.0
    Houston 10.0.2.0
    USLouisville 10.1.0.0
    USLouisville 10.2.0.0
    USLouisville 10.3.0.0
    USLouisville 10.4.0.0

    Now if you do this:

    $UniqueSites = @()
    foreach($site in ($sites | select -Unique site))
    {
    $LevelOne = "" | select SiteName,Subnet
    $levelOne.SiteName = $site.site
    $levelOne.Subnet = @()
    foreach($singleSite in ($sites | where {$_.site -eq $site.site}))
    {
    $LevelOne.subnet += $singleSite.subnet
    }
    $UniqueSites += $LevelOne
    }

    $UniqueSites will now produce this:

    SiteName Subnet
    ——– ——
    Houston {10.0.1.0, 10.0.2.0}
    USLouisville {10.1.0.0, 10.2.0.0, 10.3.0.0, 10.4.0.0}

    Does it make sense?

    Cheers

    Tore

  • #13772

    Dave Wyatt
    Moderator

    It sounds like what you want is an object that has a string property (site name), and an array property (Subnets). Anytime you find yourself creating properties or variables named Thingy1, Thingy2, etc, it's a sure sign that you should actually be dealing with some sort of array or collection. You can also shorten the code quite a bit by making use of Group-Object, instead of reinventing that particular wheel yourself with the nested loop:

    $sites = Import-Csv -Delimiter ";" .\AdSitestoSubnets.csv
    
    $unique_sites = $sites |
    Group-Object -Property Site |
    Select-Object -Property @(
        @{ Name = 'Site';    Expression = { $_.Name } }
        @{ Name = 'Subnets'; Expression = { $_.Group | Select-Object -ExpandProperty Subnet } }
    )
    
  • #13781

    Stephen Owen
    Participant

    Tore, thanks for the pointers. My issue was converting from a [string] to an [int] in order to do math functions, hence my ugly code there.

    Dave, I've never heard of Group object before and I absolutely LOVE it!

    Thanks a lot, this is precisely what I needed.

  • #13788

    Dave Wyatt
    Moderator

    No problem! The -Object cmdlets are mostly pretty useful (though I don't use Tee-Object much, for whatever reason.) If any of these look unfamiliar to you at this point, I'd suggest checking out their help files when you have some free time, and keep them in your toolbox. 🙂 Heck, even if you know them, read the help files anyway; some of them have some sneaky features in parameters or syntax that you might not have known about.

    PS C:\Source\temp> Get-Command *-Object
    
    CommandType     Name                                               ModuleName
    -----------     ----                                               ----------
    Cmdlet          Compare-Object                                     Microsoft.PowerShell.Utility
    Cmdlet          ForEach-Object                                     Microsoft.PowerShell.Core
    Cmdlet          Group-Object                                       Microsoft.PowerShell.Utility
    Cmdlet          Measure-Object                                     Microsoft.PowerShell.Utility
    Cmdlet          New-Object                                         Microsoft.PowerShell.Utility
    Cmdlet          Select-Object                                      Microsoft.PowerShell.Utility
    Cmdlet          Sort-Object                                        Microsoft.PowerShell.Utility
    Cmdlet          Tee-Object                                         Microsoft.PowerShell.Utility
    Cmdlet          Where-Object                                       Microsoft.PowerShell.Core
    

You must be logged in to reply to this topic.