@UWPVIOLATOR Getting available host properties/parameters Well first for your question on the attributes I think it’s because of what the api returns. For example $hostObj = Get-FogObject -type Object -CoreObject host $hostObj; # You would see a count column with a count of all your hosts and a hosts column with a hash table object # if you then set a variable to the hosts object in the return object, you'll get what you're looking for. You could also do it with select-object by doing | select-object -expandproperty hosts | select-object * $hosts = $hostObj.hosts; # I'm removing some information from this output $hosts | get-member; #note get-member has an alias of gm which is what I typically use instead, save those keystrokes! TypeName: System.Management.Automation.PSCustomObject Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() ADDomain NoteProperty string ADDomain= ADOU NoteProperty string ADOU= ADPass NoteProperty string ADPass= ADPassLegacy NoteProperty string ADPassLegacy= ADUser NoteProperty string ADUser= biosexit NoteProperty string biosexit= building NoteProperty string building=0 createdBy NoteProperty string createdBy=jmin createdTime NoteProperty string createdTime=2016-02-25 14:43:30 deployed NoteProperty string deployed=0000-00-00 00:00:00 description NoteProperty string description= efiexit NoteProperty string efiexit= enforce NoteProperty string enforce=1 hostalo NoteProperty System.Management.Automation.PSCustomObject hostalo=@{id=; hostID=; time=} hostscreen NoteProperty System.Management.Automation.PSCustomObject hostscreen=@{id=; hostID=; width=800; he... id NoteProperty string id=83 image NoteProperty System.Management.Automation.PSCustomObject image=@{imageTypeID=; imagePartitionTypeID=; i... imageID NoteProperty string imageID=0 imagename NoteProperty string imagename= init NoteProperty string init= inventory NoteProperty System.Management.Automation.PSCustomObject inventory=@{id=; hostID=; primaryUser=; other1... ip NoteProperty string ip= kernel NoteProperty string kernel= kernelArgs NoteProperty string kernelArgs= kernelDevice NoteProperty string kernelDevice= macs NoteProperty Object[] macs=System.Object[] name NoteProperty string name= pending NoteProperty string pending= pingstatus NoteProperty string pingstatus=<i class="icon-ping-down fa fa-exclamation-circle red" data-toggle="tool... primac NoteProperty string primac= printerLevel NoteProperty string printerLevel=1 productKey NoteProperty string productKey= pub_key NoteProperty string pub_key= sec_time NoteProperty string sec_time=0000-00-00 00:00:00 sec_tok NoteProperty string sec_tok= useAD NoteProperty string useAD= You’ll notice that some of the return values are objects and custom objects. These have even more sub fields that can be referenced. A quick note though, in the newer not yet released to the master branch of the api, and @Tom-Elliott can correct me if this is no longer the case or something, the name of the property will become universal for each coreobject type. i.e right now you get hosts and then go into the hosts property, if you got groups it would be a groups property. The new version (that I believe is available in the working branch of the fogproject git along with a new ui/Fog 1.6) will have one name for all those properties. So if creating custom scripts around this try to make it modular so that you can find where you went into coreobject returns and change them to the new universtal property name (I can’t remember what its called right now). Using For-EachObject and Where-Object to do magic notes on foreach vs foreach-object So you can indeed do some foreach stuff, but know that you can get weird behavior in powershell if you use an objects .ForEach({}) member function vs piping the object into a ForEach-Object command (which has an alias of % ie $hosts | % {do stuff}). see this link for more detail on what I think is the related reason for this, but I’m not 100%, but I do know it’s different between the two. Find the laptops So lets look at putting all the laptops in a To Be Image Group (Which I’m going to assume already exists). First thing you need to know is how you would identify the laptops from the information in the system. i.e. are they all the same model and have they all been imaged or at least inventoried in fog already? There is a systype field captured in inventory that might work. You could also utilize sysproduct if they are all the same model or have a list of models (you would use -in instead of where -match is in this example and put the list of strings in an @('array','of','model','names') I believe). You could also do this with the name property if you happen to have named them in a way to test against. But for this example we’re going to assume all laptops have the systype of ‘Notebook’ #Put all the hosts in an object, since you were using select-object in your question I'll do it in that style for the example $hosts = Get-FogObject -type Object -CoreObject host | Select-Object -ExpandProperty hosts; # Find all the hosts where the property of systype in inventory matches notebook $laptops = $hosts | Where-Object { $PsItem.inventory.systype -match 'Notebook' } # note the shorthand/alias version of above would be $hosts | ? { $_.inventory.systype -match 'Notebook' } The new laptops object would have a foreach member ie $laptops.ForEach({code on each $_}) but that member function works best with a single property of an object as it processes the code in a different order, I think it’s related to begin {} process {} end {} blocks that I linked earlier. So I strongly suggest using foreach-object instead of $laptops.foreach({do stuff}); Get the group Before we loop though we should get the information for the group you want to add to. I’m going to be inconsistent in how I nest into the property, I recommend consistency, just want to demonstrate the many ways you can access the property instead of assuming all readers of this just know all the ways. In this instance I am also assuming that the group already exists. You could also create the group with the api, but this answer is already too long and it can be hopefully figured out with these examples if it’s needed. $groups = (Get-Fogobject -type Object -CoreObject group).groups $group = $groups | ? name -match 'To Be Image' Working with group associations Now to add hosts to a group (or to see what groups they’re in) you’ll want the groupassociation object, here’s a little extra example on how it is used There is a group association for every host to group connection. There are just 3 properties, the id of the association, the id of the host and the id of the group $groupAssocs = Get-FogObject -Type Object -CoreObject groupassociation $groupAssocs = $groupAssocs.GroupAssociations; Now you have an object with all the group associations and you can do some fun stuff with it Find and output all hosts in a group Here’s an example of how you could find all the hosts currently in the group found earlier $hostIdsInGroup = $groupAssocs | ? { $_.GroupID -match $group.id } | Select-Object -ExpandProperty HostId; #convert the ids into an object with all the full hosts objects in it $hostsInGroup = $hosts | ? id -in $hostIdsInGroup # or $hosts | ? { $hostIdsInGroup -contains $_.id } # then list the findings in the console with just the host names Write-Host "Hosts in the group $($Group.name) `n $($hostsInGroup.name | Out-String)" out-string isn’t 100% needed there just wanted to use it in an example as it is helpful when wanting to output multiple properties of an object in a write-host command Getting all groups a host is a member of If you wanted all groups a specific host is a member of, lets say the last laptop in that laptop object ([-1] grabs the last object in an array)… $hostInGroups = $laptops[-1]; $groupIdsInHost = $groupAssocs | ? { $_.hostID -match $hostInGroups.id } | Select-Object -ExpandProperty groupID; $groupsWithHost = $groups | ? { $groupIdsInHost -contains $_.id } #now list the findings Write-Host "Groups the host $($hostInGroups.name) belongs to `n $($groupsWithHost.name | Out-String)" Removing all hosts from a group Now lets say you wanted To Be Image to be empty before adding, lets remove all hosts in that group, which we already found and have stored in $hostIdsInGroup we first get the full group associations object (since we grabbed the variable with a piped selectobject we only have the one property in memory) and send a delete to each of the matching associations $groupAssocsToDelete = $groupAssocs | ? { $_.GroupID -match $group.id } # or $groupAssocsToDelete = $groupAssocs | ? hostID -in $hostsIdsInGroup; # loop through and start deleting $groupAssocsToDelete | ForEach-Object { Remove-FogObject -type object -coreObject groupassociation -IdOfObject $_.id; } alternatively this might work too without looping, but not sure that the api supports this or not $json = $groupAssocsToDelete | ConvertTo-Json; Remove-FogObject -type object -coreObject groupassociation -jsonData $json Adding hosts to a group And finally at long last the answer to your actual question… add all the laptops to the group and store the results in a list (because I like being able to reference what happened in my loop, and also list objects are cool because you cad .add($stuff) and .Remove($stuff) with simple methods) $newAssocs = New-Object System.Collections.Generic.List[object]; $laptops | ForEach-Object { $json = @{ "hostID"="$($_.id)"; "groupID"="$($group.id)"; } | ConvertTo-Json; # Note, when creating the json splat and then piping it to convertto-json you must encapsulate properties and values in quotes and match the case of the original property (i.e. ID instead of Id) as in this example or it won't parse right and will return a 417 error from the api $result = New-FogObject -type object -coreObject groupassociation -jsonData $json; $NewAssocs.Add($result); } #list the newassocs that added the laptops to your group $NewAssocs; Making sure it worked Now you can go look in the gui to see the hosts are now in the group or you can use the method from earlier to output it in the console. #you'll want to refresh the groupassocs variable because they have changed and then the rest is the same $groupAssocs = Get-FogObject -Type Object -CoreObject groupassociation $groupAssocs = $groupAssocs.GroupAssociations; $hostIdsInGroup = $groupAssocs | ? { $_.GroupID -match $group.id } | Select-Object -ExpandProperty HostId; #convert the ids into an object with all the full hosts objects in it $hostsInGroup = $hosts | ? id -in $hostIdsInGroup # or $hosts | ? { $hostIdsInGroup -contains $_.id } # then list the findings in the console with just the host names Write-Host "Hosts in the group $($Group.name) `n $($hostsInGroup.name | Out-String)" Concluding ramblings One day in the future I hope to magically have time to update the module with helper functions to make some of these kinds of things easier. But I am yet to be able to find that time sadly. Although I suppose I do have the code written here now for some of the helper functions like Add-HostToGroup, Remove-HostFromGroup, Get-HostsInGroup, Get-GroupsInHost/get-HostMembership, get-fogHosts, get-fogGroups, get-FogGroupByName. But at least it is possible to do all those things with the existing commands, those would just be easier, but then you wouldn’t get to learn how to create them yourselves, and where’s the fun in that? I hope these examples help and that I didn’t give too much information. Edit: Edited post to have headings and separated the code segments so that more people can more easily find answers to other possible questions