Scripting Games July 12015 thoughts on the solution

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). 

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.

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.

 

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

Advertisements
This entry was posted in Powershell Basics, Scripting Games. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s