Features PowerShell 5 Lead image: Lead Image © Zarko Cvijovic, 123RF.com
Lead Image © Zarko Cvijovic, 123RF.com
 

Innovations in PowerShell 5

Upshift

Windows 10 brings an updated, fifth release of PowerShell that vastly simplifies the task of managing modules and software packages. The scripting language now also handles various formatted output from commands and selection lists. By Thomas Wiefel

In Windows  10, Microsoft waived the option of an easy PowerShell update and presented a fully overhauled Shell, as demonstrated by the PowerShell environment variable $PSVersionTable, which outputs the version number 5.0.10018.0. This development is all the more interesting, given that the installation directory still goes by the name v1.0; it will probably keep this name for all time for reasons of compatibility. Existing concepts and commands have been optimized, bugs fixed, and missing parameters added. That accounts for the standard improvements that you would expect on any version change.

However, with each new PowerShell version comes a design highlight. In the current PowerShell on Windows  8.1 and Server  2012  R2, this was the "Desired State Configuration" (DSC), which was designed to make other operating systems such as Unix and Android configurable. What are the fundamental changes that the new PowerShell  5 adds?

Extensions Installed in the Blink of an Eye

This unifying approach is a key feature of PowerShell. However, in version 5, the focus has now shifted to the software infrastructure. Microsoft has revamped the PowerShell module management, in particular for third parties and software package management. Two modules provide the necessary commands: PowerShellGet and OneGet. The similarity between the names is not accidental, and the objectives are very similar. As a universal package manager, OneGet supports centralized management of software packages, their sources, and product versions. In contrast, the PowerShell host's packages are managed using PowerShellGet.

Despite all the advances in PowerShell, you should still not rely exclusively on Microsoft's own extensions. PowerShell modules encapsulate specific commands developed for services or servers. Extensions for VMware (PowerCLI) or Citrix have helped PowerShell assert itself in areas where Microsoft only supplies a part of the IT landscape. Another field of deployment is in extending the current command set. As an example, just look at the popular PowerShell Community Extensions (PSCX) module.

Across all versions of PowerShell, PSCX has offered useful additions, such as the ability to create ZIP archives, voice output, or extended host information, just to name a few. To install the desired extension, though, you first had to find it. On the CodePlex website  [1], users needed to find the right version. Even after downloading and unblocking the file, administrators still had not achieved their objectives. Up to version 2, a complete PowerShell module existed, but it still had to be added to $PSModulePath  – the basic directory of all PowerShell modules.

Providing PSCX is now much easier in version 5: Install-Module pscx. After confirming the untrusted source, the installation simply completes. This is made possible by the convenient approach to managing PowerShell extensions; a new central repository named "PowerShell Gallery"  [2]. Currently, it houses 150 modules deemed to be useful and interesting, and DSC resources are hosted here in addition to PowerShell modules. To take a closer look at a package, enter:

Find-Package -name pscx | select source, links, version | fl

The provider is the newly implemented "chocolatey," and the links contain a reference to codeplex.com (Figure  1). As in OneGet, NuGet is again the driving force behind PowerShellGet, which is a variant on the NuGet Gallery. Just as with OneGet, you can create your own sources and use them as command containers.

PowerShell Community Extensions sources.
Figure 1: PowerShell Community Extensions sources.

This is implemented by the Register-PsRepository cmdlet. If you consider the metaphor of a garden here, the relations are as follows: PowerShell Gallery is the fertilizer that allows PowerShellGet and OneGet to flourish in the OneGet core soil. The soil is delivered by NuGet Provider.

PowerShell Goes Mainstream

Other innovations are also worthy of note, starting with the syntax extension, which sees the scripting language moving closer to object-oriented role models such as C#. Newly added keywords in the language such as class and enum offer users more options for structuring instructions in the development of PS1 scripts.

The scripting engine in PowerShell thus takes a huge step from an object-based scripting language that can only use existing classes to an object-oriented programming (OOP) language. The central construct in the world of OOP is the class keyword, which lets programmers create schematic templates for a more efficient design.

Peek into Packages

In PowerShell  5, script developers can resort to Find-Package for the first time. The properties of an object can be defined by using variables within a class. Methods are class-internal functions. All the interfaces created (i.e., variables and functions) are public; they are usable in the derived object. The scope of a self-defined type is, however, restricted to the module in which it was created.

A simple example illustrates the task of creating and using a class in PowerShell (Listing  1). Instantiating with the static method new() is a little difficult to get used to, but the slightly more consistent

new-Object -typeName NetConfig

is not cleanly implemented at the current time.

Listing 1: Creating and Using Classes

01 class NetConfig
02 {
03 #Properties
04 [STRING]$ComputerName = "srv01";
05 [STRING]$IpAddress = "192.168.178.2";
06 [STRING]$DNS = "192.168.178.1";
07 #Methods
08
09         [Void]
10             SetComputerName([STRING]$Name)
11            {
12                  $this.ComputerName = $name;
13            }
14 }
15 $MyObj = [NetConfig]::new();
16 $myObj.ComputerName;
17 $MyObj.SetComputerName("srv02");
18 $myObj.ComputerName;

Reusable Selection Lists

Another innovation relates to the task of creating reusable selection lists as a list of constants. The name of this constructor is Enum. The separator character is the line break, which makes the enumerator list similar to an array. However, the element type cannot be defined – it is always an integer (Listing  2).

Listing 2: Using Enums

01 Enum MemberServer {
02     SRV01
03     SRV02
04     SRV03
05     SRV04
06 }
07
08 $Remote = [MemberServer]::SRV02;
09 [enum]::IsDefined(([MemberServer]),$Remote)  #Type, Member

The reason these new constructs exist is to allow programmers to create their own DSC resources, types, and exception handlers – although the focus is on DSC. If you take a look at the help, using get-help about_Classes, this becomes more than clear. Thus far, a programmer's own configuration type – and a DSC resource is precisely that – relied on the interaction between PowerShell and "Managed Object Files" (MOF), an unwieldy Windows Management Instrumentation (WMI) construct. The major difference between using a cmdlet-based DSC resource and a class is that you do not need an MOF file.

Instead, the control information resides in the defined interfaces, thus making the information container unnecessary. Subordinate DSC resources within the PowerShell are no longer needed. At the same time, multiple DSC resources can be stored within a single module. In this respect, PowerShell  5 is a consistent advancement of the predecessor versions and makes handling a key feature like DSC easier and more elegant.

PowerShell as a Text Processor

PowerShell  2 implemented the processing of structured data through a cmdlet, and entering XML and CSV data has been unproblematic ever since – as has the task of converting console output to these formats. In many cases, however, the return value from the commands is non-standard text. Downstream processing then requires fairly complex programming routines. This gap has been plugged by the new ConvertFrom-String cmdlet. The objective is to convert arbitrary text content into objects. The technology is based on FlashExtract, a string-parsing tool.

The new PowerShell command has parameters for managing string analysis. The ability to use templates is particularly impressive. For example, a one-off return value can be used to generate a template, which is then used repeatedly for the data type in question. Administrators will appreciate this new cmdlet if they need to analyze the return value of a command. If the command returns objects, these are easier to process downstream. The example:

Get-ChildItem -Path C:\Windows-Filter *.xml -recurse | sort-Object -Property length | Select-Object -First 2

makes the benefits of an object-based approach clear. All it does is output the two largest XML files below C:\Windows. But what happens to the return value from a command such as netstat -a or ping?

These commands output a sequence of strings that needs to be evaluated using regular expressions. ConvertFrom-String converts this collection of strings into a new type. You can define the properties yourself, or use a template to determine them; for example,

$MyObj = "192.168.1.0 srv DNS" | convertFrom-String -PropertyNames IP, Name, Service
$MyObj.IP

converts simple, space-separated text into an object. Access to the individual columns is via the designators stated in the PropertyNames parameter. Downstream processing is now simple and familiar. Templates are useful for more complex tasks because they can assign attribute names to the expected characters.

Archiving and Links

The developers of Windows PowerShell have finally gotten around to tackling the task of handling archives in the current version. So far, administrators wanting to compress files often resorted to the PowerShell Community Extensions module, which has had the ability to create ZIP and RAR files for some time now.

The Microsoft.PowerShell.Archive module is somewhat more spartan in its feature set. The only supported format right now is ZIP, but the syntax is quite intuitive. The two new cmdlets, Archive and Expand-Archive only need parameter values for the source and target of the operation:

Compress-Archive -Path C:\template.txt -DestinationPath C:\udat\t.zip -update

This instruction lets you create a ZIP archive from the template.txt file.

When creating elements, especially on the filesystem, the selection of the element type was formerly restricted to physical objects. For example, you could only choose between the file and directory types. The New-Item cmdlet offers a slightly more convenient approach. A new value that is now supported for the ItemType parameter is SymbolicLink; the name is fairly self-explanatory.

Conclusions

You can already install PowerShell  5 for Windows  8.1, Server  2012  R2, and making the move is definitely worthwhile, even if you only need OneGet and PowerShellGet. The feeling of getting everything from a single source, instead of losing control over sources and versions, is something special.

Many of the improvements introduced here, such as ConvertFrom-String would have been amazing features back in version 3. Many fine-tuning capabilities will probably not be revealed until tangible use cases arise (e.g., the ability to install and load multiple versions of a module or the extended debug options  – also for PowerShell processes running in parallel).

At the same time, an important feature for software development, a Unit Testing System, has been implemented in the form of the "Pester" project. All told, the new PowerShell version 5 looks more universal and offers both developers and administrators versatile scope for action.