Lead Image © Philip Kinsey, 123RF.com

Lead Image © Philip Kinsey, 123RF.com

Working with objects in PowerShell

Useful Tool

Article from ADMIN 39/2017
By , By
This workshop helps admins understand the object-oriented structure of PowerShell.

If you want to professionally manage Windows systems, and above all servers, it's hard to avoid using PowerShell. Many admins, however, find it somewhat difficult to cope with the object-oriented approaches of the scripting language. Our workshop provides assistance and illuminates the fundamental concepts.

Of course, admins use scripting languages to handle administrative and support tasks, and many system administrators will have had no alternative but to delve the depths of the SQL language. Basically, most administrators want to do their jobs rather than develop programs, which explains why many experienced Windows admins have a certain aversion to working with PowerShell. This is particularly unfortunate, because this language can significantly facilitate the work, specifically because of its structure and object-oriented approach (see the "Object-Oriented Structure in PowerShell" box for more information). The motivation behind this article is thus to show how the developers implemented this concept and how the scripting language uses these objects.

Object-Oriented Structure in PowerShell

The foundation of PowerShell comprises special .NET classes that make it possible to use the entire .NET library from within the PowerShell environment. The cmdlets available directly in the PowerShell environment run perform specified actions, such as enumerating the files in a directory or managing a system service.

The cmdlets for PowerShell objects typically return objects, although there are some exceptions. The cmdlets perform an action of this type by creating an object or a group of objects based on the specialized PowerShell classes. They then provide the functions available, with the help of which, for example, the information can be routed through the pipeline and used by other commands.

Often the problem for users is to imagine something in terms of the fairly abstract concept of objects. A way better to clarify this description is to imagine each of these objects as a package of related information. An object can include, for example, the data need to describe a file: the name and size of the file, the file storage location, and other attributes.

Working with Objects

If you want to work with the data of an object, you need to call its members . These are the components that let you access and edit the information. A PowerShell object supports a whole range of members, the most famous examples being properties and methods . When you work with objects, you use the methods to perform actions, and the properties, to access information. An object's properties include, for example, values such as the file size or the date on which the file was created, whereas deleting or moving the file is one of the methods provided by the respective object.

If you want to learn and understand more about the concepts and capabilities of PowerShell, your best bet – as with any scripting and programming language – is to try the examples yourself. One of the PowerShell cmdlets that people like to use for this purpose is Get-Service. It outputs a list of the services installed on a computer. If called without any parameters, the cmdlet also outputs details about the services on the local system.

Each service that is returned by the Get-Service cmdlet is an object based on the .NET System.ServiceProcess.ServiceController class. Of course, the ServiceController object also includes a number of properties and methods that a user can draw on to access the data in the object or perform operations against the data. They include, for example, the properties of the name and the DisplayName of the system service. The value associated with the properties of DisplayName is the display name of the service. The ServiceController object also provides a number of methods: You can use the Start method to start the service represented by the object and the Stop method to stop it again.

It is unlikely that an admin could memorize all the properties, methods, or even member types of the objects to access and use them correctly. PowerShell thus provides a tool that helps you retrieve detailed information about the respective members of an object: the Get-Member cmdlet. If you want to know, for example, which members the get-service cmdlet provides, you can retrieve this information by typing:

> Get-Service | Get-Member

The objects that Get-Service returns are piped (as represented by the | character) to the input of the Get-Member cmdlet (Figure 1). The following output shows what members, methods, and properties a cmdlet provides. The list includes the name of each member, its type, and a definition. To what extent this definition is useful for you, depends to a large extent on your programming skills. In any case, you can determine in this way that Service.Controller comes with a whole bunch of members and also see their names. Also, this example shows very nicely that these are mostly methods and properties of the respective object.

Figure 1: The output of Get-Member shows what members, methods, and properties a cmdlet provides.

Detailed Information on Objects

For users, who are already familiar with the .NET classes, this output is worth a closer look. It first displays the type name of the class on which this object is based – in this case, System.ServiceProcess.ServiceController. There is another, very interesting aspect to this information: Inspection of the results returned by Get-Member shows that they only include the details of a single object, even though the Get-Service cmdlet returns an object for each service. The reason for this is the way the Get-Member cmdlet works. If it notes that several objects of the same type are returned, it only shows you one instance of these objects in the output. The developers did this to avoid redundancies. The cmdlet only returns the class on which all these objects are based.

If the command does not return more than one object type, Get-Member displays the appropriate information for each of these types. An example of this is calling the Get-ChildItem cmdlet for a directory that includes both files and subdirectories (Figure 2):

> Get-ChildItem H:\tmp | Get-Member
Figure 2: You can call Get-ChildItem for a directory that includes both files and subdirectories.

Get-Member now displays details of the classes System.IO.DirectoryInfo (for directories) and System.IO.FileInfo (for the files in the directory H:\tmp). If this directory only contained directories, Get-Member would display only the details of System.IO.DirectoryInfo. Users who want to use Get-Member thus need to ensure that they actually get to see the object types that they are really interested in.

Get-Member has still more to offer: For example, the user can display a list, consisting of a special member type, such as the properties or the methods. If you need this kind of output, you need to add the -MemberTyp parameter followed by the name of the desired type in the call. The following call ensures that only the properties of the respective object are displayed on the screen:

> Get-Service | Get-Member -MemberTyp Property

The ability to specifically request such details makes it easier to access the information within an object. It does not matter whether you are interested in a specific member or a whole list of the members of an object.

Even More Targeted and Detailed

For example, if you already know that the ServiceController class supports the properties Status and ServiceTyp, you can use this information in a targeted way to specify your own commands and their output. For example, the following command uses these properties together with the Where-Object cmdlet to filter the results as desired:

> Get-Service | Where {$_.Status -eq "Running" `-and $_.ServiceType -eq "Win32OwnProcess"}

Again Get-Service returns a set of ServiceController objects that are then routed through the pipe to the Where-Object cmdlet. I used the Where alias for this cmdlet. For each of the objects passed to the Where-Object cmdlet, you can now access its properties to develop the desired filter. This is why you need to use the $_ symbol. This is a system variable that always points to the current object in the pipeline, which makes it particularly well suited to processing these objects in sequence. This symbol must be followed by a dot, in turn followed by the name of the property; I selected the Status property here.

You can now use this to return specific data in line with your specifications. To do this, you can use Boolean expressions, which determine whether this information is true or false. In this case, I first stipulated that the Status property must have a value of Running and that the ServiceTyp property must be equal to the value of Win32-OwnProcess.

In both cases, the -eq (for "equals") operator is used. With its help, you can determine whether the required values apply. The -and operator is added to link the two expressions. Based on Boolean logic, both expressions must be "true" and the properties must contain the required value for an object to be returned. An important note about this example: The ` character at the end of the first line tells the PowerShell interpreter to continue the code on the next line. If this is missing, the PowerShell command ends at the end of the line, and you will see an error message.

This is a good example of a user's access to the information that they were originally looking for being facilitated by knowing the names of the properties that are supported by the respective object. If you want to take this example a step further, you can pass the results of the command to the Format-Table cmdlet:

> Get-Service | Where {$_.Status -eq "Running" `-and $_.ServiceType -eq "Win32OwnProcess"} | `Format-Table -Autosize

This again demonstrates the power of the pipeline mechanism.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Comparing PowerShell and Python
    Although PowerShell has its ardent advocates, many admins and users swear by Python, especially for Windows. Which scripting language is best for you? Read on for a comparison of PowerShell and Python.
  • PowerShell Part 1: Retrieving System Information

    Windows administrators, like Unix or Linux administrators, look for ways to perform their duties with ease and elegance through automation. PowerShell allows administrators to gather information, change Registry parameters, work with Active Directory, manipulate services, look at events, work with Windows Management Instrumentation (WMI), and much more. PowerShell is a Windows administrator’s best friend.

  • Platform independence with PowerShell Core
    Microsoft has broken new ground with the release of PowerShell Core 6.0, which at heart is a complete reboot in terms of architecture and objectives. For the first time, a new version is not linked to the Windows operating system.
  • Features of PowerShell loops
    Optimize your PowerShell scripts with loops when automating tasks that are repeated regularly and frequently.
  • Innovations in PowerShell 5
    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.
comments powered by Disqus