Aaron
Aaron

Reputation: 573

Unable to outputting PSCustomObject

I input a collection then I have have to loop through to make the customobject. The Names in the object are all unique. I am hoping to have PSCustomObject in a variable that I can use later.

Function Get-PSCustomObjectAsOutputType {

     $services = get-service | select -First 5
     [hashtable]$properties
     $X = 0
     foreach ($s in $services)
        {
            $properties += @{"Name$x" = $S.name
                            "Status$x" = $S.status
                            "Displayname$x" = $S.displayName
                           }
            $obj = New-Object -TypeName PSCustomObject -Property $properties
            $x++     
         }

        $Obj
}

It appears that the $null happens when I assign it to a varible.

$TheTypeNeedsToBePSCustomOutputType = Get-PSCustomObjectAsOutputType

$TheTypeNeedsToBePSCustomOutputType.PSobject.TypeNames

I required that System.Object[] be PSCustomObject

PS> $TheTypeNeedsToBePSCustomOutputType.PSobject.TypeNames

System.Object[]
System.Array
System.Object

$TheTypeNeedsToBePSCustomOutputType.PSObject

The "$null" in the BaseObject is getting in my way.

BaseObject          : {$null, @{Displayname3=Application Layer Gateway Service; Name4=AppIDSvc; Displayname2=AllJoyn Router 
                      Service; Displayname0=Agent Activation Runtime_8af1b; Status0=Stopped; Status2=Stopped; Name3=ALG; 
                      Displayname1=Intel® SGX AESM; Name2=AJRouter; Name1=AESMService; Status1=Running; Status3=Stopped; 
                      Name0=AarSvc_8af1b; Status4=Stopped; Displayname4=Application Identity

Upvotes: 0

Views: 1421

Answers (2)

Steven
Steven

Reputation: 7057

So you'r casting a variable without ever assigning it. So null in null out. Later when you use the += operator you are adding the hash table to the null. That operation results in an array where index 0 is null and index 1 and beyond are the hash tables.

I'm somewhat amazed that casting to a null initiates the variable.

Test:

[hashtable]$properties
Get-Variable properties

That returns Cannot find a variable with the name 'properties'. Nevertheless, if you were to comment that line the function would indeed return a PSCustomObject.

That said, I think the real problem is you are creating the object inside the loop. And so recreating it on every iteration. That doesn't seem to be the intention of your code.

If I'm interpreting your intent properly you want to create a single big object with properties named incrementally for each service you encounter.

Try these minor adjustments:

Function Get-PSCustomObjectAsOutputType
{
    $Services = Get-Service | Select -First 5
    $Properties = [Ordered]@{}

    # Ordered can only be on a literal

    For( $i = 0; $i -le $Services.Count; ++$i)
    {
        $Service = $Services[$i] # Assign a var; easier to reference
        $Properties +=
        @{
            "Name$i" = $Service.Name
            "Status$i" = $Service.Status
            "Displayname$i" = $Service.DisplayName
        }
    }

[PSCustomObject]$Properties # Another way to create the object...

} #End Function Get-PSCustomObjectAsOutputType

Notice I used ordered hash. This should make your output a little more readable.

I also used a for loop, which relieves you of having to increment the variable yourself...

Let me know if this helps. Thanks.

Upvotes: 1

Jawad
Jawad

Reputation: 11364

I am not sure why you are assigning properties to $obj when its overwritten each time the loop happens. If I not mistaken, you intend to return the completed $properties hashtable once the loop is done.

Also, declaration of Hashtable is not right. You can simply use @{} to define a hashtable. If you are interested in getting a PSCustomObject, then you can cast the HashTable to a PSCustomObject.

Function Get-PSCustomObjectAsOutputType {

     $services = get-service | select -First 5
     $properties = @{}
     $X = 0
     foreach ($s in $services)
        {
            $properties += @{"Name$x" = $S.name
                            "Status$x" = $S.status
                            "Displayname$x" = $S.displayName
                           }
            $x++     
         }
        [PsCustomObject]$properties
}

$TheTypeNeedsToBePSCustomOutputType = Get-PSCustomObjectAsOutputType
$TheTypeNeedsToBePSCustomOutputType.GetType()

# Output :
IsPublic IsSerial Name                                     BaseType                                                                                                                                                                                  
-------- -------- ----                                     --------                                                                                                                                                                                  
True     False    PSCustomObject                           System.Object    

I am not sure how you plan to retrieve these since you are simply adding all the properties together. I would suggest using the hashtable with a key and assigning each of these as values to it.

Function Get-PSCustomObjectAsOutputType {

    $services = get-service | select -First 5
    $properties = @{}
    $X = 0
    foreach ($s in $services)
    {
        # Use $x as number or use $s.Name as the key for this service.
        $properties[$x] = @{Name = $S.name
                        Status = $S.status
                        Displayname = $S.displayName
                        }
        $x++     
        }
    [PsCustomObject]$properties
}

Upvotes: 3

Related Questions