One of the great things about Windows PowerShell is that it can run Windows native command line tools, such as ping, ipconfig, and others. There are times, however, when there are exceptions. While recently working in the console, I brainlessly entered ‘ver’ (without the quotes), and it didn’t return what I expected. Instead of printing ‘Microsoft Windows [Version 6.3.9600]’ to the console, it reported that ver wasn’t recognized.
PS C:\> ver ver : The term 'ver' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + ver + ~~~ + CategoryInfo : ObjectNotFound: (ver:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException
While I wouldn’t recommend opening CMD to run the command, because seriously get out of that habit already, you can switch to CMD from inside the PowerShell console, as demonstrated below.
PS C:\> cmd Microsoft Windows [Version 6.3.9600] (c) 2013 Microsoft Corporation. All rights reserved. C:\>ver Microsoft Windows [Version 6.3.9600] C:\>exit PS C:\>
Still, this wasn’t quite as native as I wanted. For whatever reason, I wanted to type ver, and get the identical output I was used to seeing,… regardless of the fact that the ver output doesn’t really tell me much.
The first thing I did was launch the ISE and create an alias for ver. Keep in mind, that you may need to add -ErrorAction SilentlyContinue to the New-Alias cmdlet, if you run the script more than once inside the ISE. The problem here is that you’ll receive an error if you try and create an alias that is already being used. Either that, or you can add the -Force parameter and make New-Alias act like Set-Alias (and overwrite the alias even though it’s not really changing it).
New-Alias -Name ver -Value Get-TMVersion
Next, I constructed a function called Get-TMVersion that the alias ver would use. Inside the function, I created a single variable, $OS, and assigned it the results of a Get-CimInstance command. If for some reason you’re still using PowerShell 2.0, this can be replaced by the Get-WmiObject equivalent: Get-WmiObject -Class Win32_OperatingSystem.
Function Get-TMVersion { $OS = Get-CimInstance -ClassName Win32_OperatingSystem }
Once I have this data stored in a variable, I can begin checking for a value in the variable, and then, building out my results to match the native Windows command. The If statement checks to see if the Name property of $OS begins with the string Microsoft Windows. Providing it does, it sets a second variable, $Version, as seen in the example below. Once that’s complete, it then echos a blank line, the $Version variable, and then echos a second blank line. At this point, $Version should be identical to the ver command’s standard output.
Function Get-TMVersion { $OS = Get-CimInstance -ClassName Win32_OperatingSystem If ($OS.Name -like 'Microsoft Windows*') { $Version = "Microsoft Windows [Version $($OS.Version)]" } Write-Output -Verbose `r`n$Version`r`n }
Here’s the function in action.
PS C:\> ver Microsoft Windows [Version 6.3.9600] PS C:\>
Boring, but it works. I should note that this function would probably be best served to include some error checking, in case setting the $OS variable errors out. In addition, I suspect there are probably other ways to produce the same resul–… (pause, keyboard keys clicking) …ugh, here’s a couple variations of yet another, simpler way.
PS C:\> cmd /c ver Microsoft Windows [Version 6.3.9600] PS C:\> cmd /c ver;echo '' Microsoft Windows [Version 6.3.9600] PS C:\>
It seems I could have just dropped a tiny bit of text into my function and called it a day. If you’ve ever read anything else I’ve written and posted, then you may have noticed a pattern. I seem to do things the hard way, long before I figure out a simpler way. I like it that way, though. If anything, it keeps me thinking, and therefore, improving my PowerShell skills overall.
Function Get-TMVersion { cmd /c ver Write-Output -Verbose '' }