add fields to custom object or add array

AintGotNoTime 161 Reputation points
2021-09-23T14:59:32.967+00:00

Trying to find a way to combine arrays or add fields to a custom object. I have this working but the output is not one constant table for an output. Is there a way to add a column to the custom field or make 2 arrays and combine. I tried to use arrays but got the you cant add them error. Tried adding custom object to array but got errors as well. thank you for the assistance

#Script to troubleshoot Cyberark accounts
Import-Module ActiveDirectory

#Get the csv file
$list = gc -Path C:\temp\server.txt

#Now loop throught he list to ping, DNS and AD

foreach ($server in $list)
    {


        $result = Test-NetConnection -ComputerName $server -Port 3389 -InformationLevel Detailed

        $output  = [PSCustomObject]@{
                    "Hostname" = $server
                    "RDP_Pass_?" = $result.TcpTestSucceeded
                    "DNS_Resolved_?" = $result.NameResolutionSucceeded
                    }

        #if DNS resolution works then get information on server
        if ($result.NameResolutionSucceeded -eq "true")
            {
            #Need to split the server name and the domain to find the server.
            $charSplit = $server.split('.', 2)

            Get-ADComputer -Identity $charSplit[0] -Properties DistinguishedName, Enabled  -Server $charSplit[1] | Select DistinguishedName
            }

        $output | select -Property Hostname,RDP_Pass_?,DNS_Resolved_?, DistinguishedName



       Write-Host $output. | Format-Table -Force


     }
Windows for business | Windows Server | User experience | PowerShell
{count} votes

Accepted answer
  1. Michael Taylor 60,161 Reputation points
    2021-09-23T15:53:39.377+00:00

    You can do both. To add a value to a hash table then just use the dictionary syntax.

    $output = @{ "Hostname" = "host`"; "RDP_Pass" = $true }
    $output["NewProperty"] = 10
    

    This would add a value to the current object which is a hash table. If you need to store per-server info then do this. Personally I find it better to go ahead and add all the properties up front defaulted to some value and then set them later if needed rather than dynamically adding them in as you go.

    For adding to an array then a PS array can be added to.

    $items = @()
    $items += 10
    

    But if you try to call Add you'll get an error because Add isn't a valid call. PS array is an actual array so when you use += it creates a new array, copies the original values over, adds the new value and returned the updated array. If you're going to be doing this a lot then it is inefficient. At that point the better approach is to switch to a List which handles the details.

    $list = New-Object Collections.ArrayList
    $list += 10
    $list.Add(20)
    

    ArrayList is equivalent to the PS array and you can store anything in it. If you want to only store a specific type then prefer the generic version instead.

    [System.Collections.Generic.List[int]] $integersOnly = @()
    $integersOnly += 10
    $integersOnly.Add(20)
    $integersOnly.Add("Hello")  # Error
    

2 additional answers

Sort by: Most helpful
  1. AintGotNoTime 161 Reputation points
    2021-09-23T17:03:56.87+00:00

    Hi,

    Ok I did you second option in Arrays and its working as I want it. though it might be overkill, but it works.

    #Script to troubleshoot Cyberark accounts
    Import-Module ActiveDirectory
    
    #Get the csv file
    $list = gc -Path C:\temp\server.txt
    
    #Now loop throught he list to ping, DNS and AD
    
    foreach ($server in $list)
        {
    
    
            $result = Test-NetConnection -ComputerName $server -Port 3389 -InformationLevel Detailed
    
    
    
            $output  = [PSCustomObject]@{
                        "Hostname" = $server
                        "RDP_Pass_?" = $result.TcpTestSucceeded
                        "DNS_Resolved_?" = $result.NameResolutionSucceeded
                        }
    
            #if DNS resolution works then get information on server
            if ($result.NameResolutionSucceeded -eq "true")
                {
                #Need to split the server name and the domain to find the server.
                $charSplit = $server.split('.', 2)
    
                $test =  Get-ADComputer -Identity $charSplit[0] -Properties DistinguishedName, Enabled  -Server $charSplit[1] | Select DistinguishedName
    
                $output = $result | select @{Name="Hostname";Expression={$server}}, @{Name="RDP_Pass";Expression={$result.TcpTestSucceeded}}, @{Name="DNS_Resolved";Expression={$result.NameResolutionSucceeded}}, @{Name="DName";Expression={$test.DistinguishedName}}
    
                }
                else {
                    $output = $result | select @{Name="Hostname";Expression={$server}}, @{Name="RDP_Pass";Expression={$result.TcpTestSucceeded}}, @{Name="DNS_Resolved";Expression={$result.NameResolutionSucceeded}}, @{Name="DName";Expression={"No AD Object"}}
    
                }
    
    
            #$output | select -Property Hostname,RDP_Pass_?,DNS_Resolved_?, DistinguishedName
    
    
    
           Write-Host $output. | Format-Table -Force
    
    
         }
    
    0 comments No comments

  2. Rich Matheisen 47,901 Reputation points
    2021-09-23T19:38:34.873+00:00

    Try this:

    #Script to troubleshoot Cyberark accounts
    Import-Module ActiveDirectory
    
    # results template
    $output = [ordered]@{
        Hostname = ""
        'RDP_Pass_?' = ""
        'DNS_Resolved_?' = ""
        DName = ""   
    }
    
    #Get the csv file
    $list = Get-Content -Path C:\temp\server.txt
    #Now loop throught he list to ping, DNS and AD
    foreach ($server in $list) {
        $result = Test-NetConnection -ComputerName $server -Port 3389 -InformationLevel Detailed
        $output.Hostname         = $server
        $output."RDP_Pass_?"     = $result.TcpTestSucceeded
        $output."DNS_Resolved_?" = $result.NameResolutionSucceeded
    
        #if DNS resolution works then get information on server
        if ($result.NameResolutionSucceeded -eq "true") {
            #Need to split the server name and the domain to find the server.
            $charSplit = $server.split('.', 2)
            $test = Get-ADComputer -Identity $charSplit[0] -Properties DistinguishedName, Enabled  -Server $charSplit[1] | Select-Object -Expand DistinguishedName
            $output.DName = $test.DistinguishedName
        }
        else {
            $output."DName" = "No AD Object"
        }
        [PSCustomObject]$output
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.