Introduction
A long time ago, I ran into one of my most referenced articles ever from Microsoft. The title was an aptly names ‘Dude, where’s my rollup?’ which is a short, concise article on how to query the version of an Exchange server. Although it looks like the images of the original article are gone though and while it is not relevant to this article, it is good to see that the general information is still available.
The gist of the article boiled down to querying the version of the local Exchange server based off the file version of the exesetup.exe file on the server and then cross referencing that version with what Microsoft Published on this Page.
Original Code – Single Server
As I said, the article covered, in a single line, how to query the version of the local Exchange server. Here is the original code:
GCM exsetup |%{$_.Fileversioninfo}
Which provides this feedback:
Cross-referencing that version page of Microsoft, we see this:
Expand to All Exchange Servers
How do we expand the use of this one-liner to query all Exchange servers in an environment? Well, we first need to the names of each Exchange server in the environment.
$Servers = (Get-ExchangeServer).Name
Once we have that, we can then run the same one liner remotely on each Exchange server like so:
Foreach ($Server in $Servers) { Invoke-Command -ComputerName $Server -ScriptBlock { GCM exsetup |%{$_.Fileversioninfo} } }
Now what if we wanted to reduce to one line? Yes and here’s how:
(Get-ExchangeServer).Name | % { Invoke-Command -ComputerName $_ -ScriptBlock { GCM exsetup |%{$_.Fileversioninfo} } }
Our results (from either method):
What If we would want it to be more concise?
(Get-ExchangeServer).Name | % { Invoke-Command -ComputerName $_ -ScriptBlock { GCM exsetup |%{$_.Fileversioninfo | Select ProductVersion} } }
Let’s tweak that one more time:
(Get-ExchangeServer).Name | % { $Ver = Invoke-Command -ComputerName $_ -ScriptBlock { GCM exsetup |%{$_.Fileversioninfo | select ProductVersion} } ; $Version = $Ver.ProductVersion ; "$_,$Version" }
Conclusion
Tips like this are why I like PowerShell. We can take an existing one-liner and expand its reach to objects outside of the normal PowerShell scope and we also have the ability to make the code used small and more efficient. This same practice and procedure can potentially be used in other areas of PowerShell to help create more concise, compressed code making it easier to write and easier to understand.
———————————————————————————————————–
Comments? Questions?
Feel free to leave your Comments below! Learn to more efficiently utilize PowerShell to manage Exchange Server, Exchange Online, Microsoft Defender for Office or Microsoft Purview Compliance portals by picking up frequently updated eBooks: