PowerShell for Windows Admins

Aug 1 2015   4:05AM GMT

Scripting Games July 12015 thoughts on the solution

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
Powershell

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

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: