That's fantastic Matthew, thank you so much for taking the time to clarify this! If there are a number of cmdlets in the Exchange snapin that behave in such a manner, is that documented anywhere? I work with customers who have very large Exchange environments on a regular basis, and as I tend to use PowerShell quite heavily these days, knowing which cmdlets behave in this fashion would go a long way to helping me use PowerShell as efficiently as possible in these environments. It is really important that this difference in behaviour be known to PowerShell script authors.
Further, are there plans to change these cmdlets in the future so that they return objects iteratively through the pipeline and follow the PowerShell pipelining model?
You know, there is a really big impact to these cmdlets behaving this way. Compare these two examples:
foreach ($service in Get-Service) {$service}
and
foreach ($mailbox in Get-Mailbox -resultSize Unlimited) {$mailbox}
In the former, the services are returned iteratively from Get-Service but they are collected and stored in a temporary variable. This results in one collection of the objects returned by Get-Service being in memory at the time that the foreach statement starts iterating through them.
Now look at the latter. According to what you just posted in the comments, Get-Mailbox will gather and store the entire collection of mailboxes internally before it sends any of them back. Then the foreach statement will use a temporary variable to store the entire collection of mailboxes. Again. That's two copies, twice the memory footprint. This could be really bad news if you don't realize how Get-Mailbox really works under the covers. In the current implementation, from what you have stated it seems that you should *never* use Get-Mailbox with the foreach statement if you're collecting a large number of mailboxes (define large: more than the default size limit of 1000?) because you'll have two copies of that in memory. Never might seem like a strong word but I think it's better to go that route than to have to worry about doubling the amount of storage for large collections. This makes it all that much more important to know which Exchange cmdlets behave in this way (and it makes it all that much more important to understand the differences between the foreach statement and the ForEach-Object cmdlet :)).
Please correct me if I am wrong anywhere in this analysis.
Thanks again,
Kirk out.
http://poshoholic.com