The July 2015 puzzle can be found here:
http://powershell.org/wp/2015/07/04/2015-july-scripting-games-puzzle/
Write a one-liner that produces the following output (note that property values will be different from computer to computer; that’s fine).
PSComputerName ServicePackMajorVersion Version BIOSSerial
————– ———————– ——- ———-
win81 0 6.3.9600 VMware-56 4d 09 1 71 dd a9 d0 e6 46 9f
By definition, a one-liner is a single, long command or pipeline that you type, hitting Enter only at the very end. If it wraps to more than one physical line as you’re typing, that’s OK. But, in order to really test your skill with the parser, try to make your one-liner as short as technically possible while still running correctly.
Challenges:
•Try to use no more than one semicolon total in the entire one-liner
•Try not to use ForEach-Object or one of its aliases
•Write the command so that it could target multiple computers (no error handling needed) if desired
•Want to go obscure? Feel free to use aliases and whatever other shortcuts you want to produce a teeny-tiny one-liner.
By definition, a one-liner is a single, long command or pipeline that you type, hitting Enter only at the very end. If it wraps to more than one physical line as you’re typing, that’s OK. But, in order to really test your skill with the parser, try to make your one-liner as short as technically possible while still running correctly.
Initial thoughts.
One liner is a mis-nomer that has caused more problems than enough for the PowerShell community. The requirement is correctly stated as a single pipline. One pipeline can spread over many lines but is called a one-liner. This is one line of code:
get-service; get-process;
but is not a one-liner because the semi-colon is a line termination character so you’ve combined 2 lines but into 1 but they’ll execute as 2 pipelines.
Obviously need to use CIM (WMI) to retrieve the data. Standard approach would be Win32_OperatingSystem & Win32_Bios
£> Get-CimClass *Bios
NameSpace: ROOT/cimv2
CimClassName
————
Win32_BIOS
Win32_SystemBIOS
£> Get-CimClass *OperatingSystem
NameSpace: ROOT/cimv2
CimClassName
————
CIM_OperatingSystem
Win32_OperatingSystem
Win32_SystemOperatingSystem
If you want to shave off a couple of characters you could use the CIM_OperatingSystem class as Boe suggests http://powershell.org/wp/2015/07/29/2015-july-scripting-games-wrap-up/
Be aware that the CIM_ classes adhere to the standard definition from the DMTF – http://www.dmtf.org/standards/cim and Win32_ classes are the Microsoft version from when WMI was introduced. The win32_ classes are often subtly different to the CIM_ classes so check carefully with Get-CimClass before using.
My first though was to use Get-CimInstance
Get-CimInstance -ClassName Win32_OperatingSystem |
select PSComputerName, ServicePackMajorVersion, Version,
@{N=’BIOSSerial’; E={(Get-CimInstance -ClassName Win32_Bios).SerialNumber}}
But for the local machine that won’t return the PSComputerName attribute unless you use the –ComputerName parameter and point to the local machine or pipe the computer name to the cmdlet
Get-WmiObject doesn’t have that problem
Get-WmiObject -ClassName Win32_OperatingSystem |
select PSComputerName, ServicePackMajorVersion, Version,
@{N=’BIOSSerial’; E={(Get-CimInstance -ClassName Win32_Bios).SerialNumber}}
The trick here is to use a calculated field to get the BIOS serial number
I prefer using Invoke-Command to get the data from a remote machine. I get the RunSpaceId as well but that can be filtered out.
The last part of the puzzle was to shrink the code to the smallest number of characters possible. I’ve never seen the point of that in production use so never bother – if I wanted to write something unreadable I’d use Perl. The time taken to shrink is never regained and I can use tab completion to get my code input quickly and working. Boe has done an excellent job of showing that could be done so I’ll point you in that direction