My first suggestion, but unrelated to your actual question, would be to change how you’re creating your array of monitor objects. When you use +=
to ‘add’ to an array what Powershell is actually doing in the background is destroying the array and recreating it with the original contents plus the new contents.
On a small scale this isn’t that much of a performance hit, but on a larger scale it can really slow things down, so it’s best to be aware of it now and start approaching this differently.
Instead of
# creating an empty array
$Monitor_Array = @()
# and adding stuff to it
$Monitor_Array += "Stuff"
$Monitor_Array += "Things"
Since your Foreach loop is only outputting the Monitor objects you’re creating, start your Foreach loop like this instead:
$Monitor_Array = ForEach ($Monitor in $Monitors) {
<#...#>
}
Now anything that it output during the loop is captured in the $Monitor_Array variable which automatically becomes an array as soon as multiple objects are received.
Now, your question:
An array is not constrained to only holding one type of object. Observe:
$Array = 1,2,3,"Stuff","Things"
# the output of it would look like this
PS > $Array
1
2
3
Stuff
Things
This is now an array that’s holding integers and strings. You can do the same thing with objects that have more properties.
$Array = @()
$Array += [PSCustomObject] @{
Make = "Toyota"
Model = "Land Cruiser"
Color = "Silver"
Year = "2024"
Engine = "Hybrid"
}
$Array += [PSCustomObject]@{
FoodCategory = "Breakfast"
Item = "Eggs"
Drink = "Coffee"
}
But the output of this would look like this:
PS > $Array
Make : Toyota
Model : Land Cruiser
Color : Silver
Year : 2024
Engine : Hybrid
FoodCategory : Breakfast
Item : Eggs
Drink : Coffee
This may not be what you want, and ultimately you shouldn’t do this. You should strive to only put like-objects in arrays with each other.
Right now your $Monitor_Obj only have 4 properties which means Powershell is automatically formatting them as a table which probably looks really nice in the output. 5 or more properties means Powershell would format it as a list (vertically), an Array containing even one object with 5 or more properties will make Powershell format the entire array as a list instead of a table.
Your dock object has 6 properties so the above scenario would apply to it. The question then is: what is your end goal? Do you want table output in the console?
Also consider that when making Powershell tools you should really only have your code produce one type of object. Right now you’re producing an object with dock information and objects with monitor information. If I wanted to do something with those objects after they are output from the code I’m kind of in a bind because they’re not like objects. I can’t easily pipe the output to something else (even just Export-Csv). If you really need the dock information on there as well you might consider making your objects contain ALL of the information you collect:
$Monitor_Obj = [PSCustomObject]@{
AttachedComputer = $Mon_Attached_Computer
Manufacturer = $Mon_Manufacturer_Friendly
Model = $Mon_Model
SerialNumber = $Mon_Serial_Number
DockName = $DeviceNames.name
DockMachineType = $DockInfo.MachineType
DockDockId = $Dockinfo.DockId
DockMacAddress = $DockInfo.MacAddress
DockSerialNumber = $DockInfo.SerialNumber
}
It wouldn’t automatically format as a table, but then you would have uniform objects to deal with and you could capture the output of your code in a variable, or pipe it, and do whatever you want with it.