0

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
Aaron
  • 563
  • 3
  • 13
  • 1
    Use `$properties = @{}` instead of `[hashtable]$properties`. Always use `Set-StrictMode -Version latest` to avoid such errors… – JosefZ Feb 26 '20 at 00:39
  • I agree, but I don't think that's the actual cause of the problem. Inside the loop he's assigning $Properties to a hash anyhow. Posting an answer shortly. – Steven Feb 26 '20 at 00:46
  • Actually I stand corrected. [hashtable]$properties is a problem all by itself. Very difficult to see via testing, but it is responsible for the null. I'll correct my answer. – Steven Feb 26 '20 at 05:43

2 Answers2

3

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
}

Jawad
  • 11,028
  • 3
  • 24
  • 37
  • 1
    I think he's trying to create a single big object. I don't know why, but I had to guess that's the reason to increment the property names themselves. I'm hoping he clarifies shortly. BTW nice solution, I gave you a vote. – Steven Feb 26 '20 at 01:00
1

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.

Steven
  • 6,817
  • 1
  • 14
  • 14