ArVie
ArVie

Reputation: 155

How to get the output of a powershell command into an array

I am trying to get the output of a powershell command into an array, but it seems not to work. In fact I want to address the output with a row and a column index. e.g.

$a=Get-Service

With output (part)

Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  AeLookupSvc        Application Experience                
Stopped  ALG                Application Layer Gateway Service     
Stopped  AppIDSvc           Application Identity                  
Running  Appinfo            Application Information               
Stopped  AppMgmt            Application Management    

I want to address for the second line the DisplayName, e.g.

$a[2][2]

And it should give then

Application Layer Gateway Service

But this does not seem to work.

Can anybody help?

Upvotes: 9

Views: 66858

Answers (4)

Simon Elms
Simon Elms

Reputation: 19818

To follow on from the answers that mention using property names:

To discover the property names of the objects coming out of the pipeline, pipe the output of the cmdlet into Get-Member. For example:

Get-Service | Get-Member

This will give you the type of the objects coming out of the pipeline, as well as a list of the properties, methods and events of those objects. If you're only interested in the property names of the objects you can filter the output of Get-Member using Get-Member -MemberType Property, AliasProperty.

For example:

> Get-Service | Get-Member -MemberType Property, AliasProperty

   TypeName: System.Service.ServiceController#StartupType

Name                MemberType    Definition
----                ----------    ----------
Name                AliasProperty Name = ServiceName
RequiredServices    AliasProperty RequiredServices = ServicesDependedOn
BinaryPathName      Property      System.String {get;set;}
CanPauseAndContinue Property      bool CanPauseAndContinue {get;}
CanShutdown         Property      bool CanShutdown {get;}
CanStop             Property      bool CanStop {get;}
Container           Property      System.ComponentModel.IContainer Container {get;}
DelayedAutoStart    Property      System.Boolean {get;set;}
DependentServices   Property      System.ServiceProcess.ServiceController[] DependentServices {get;}
Description         Property      System.String {get;set;}
DisplayName         Property      string DisplayName {get;set;}
MachineName         Property      string MachineName {get;set;}
ServiceHandle       Property      System.Runtime.InteropServices.SafeHandle ServiceHandle {get;}
ServiceName         Property      string ServiceName {get;set;}
ServicesDependedOn  Property      System.ServiceProcess.ServiceController[] ServicesDependedOn {get;}
ServiceType         Property      System.ServiceProcess.ServiceType ServiceType {get;}
Site                Property      System.ComponentModel.ISite Site {get;set;}
StartType           Property      System.ServiceProcess.ServiceStartMode StartType {get;}
StartupType         Property      Microsoft.PowerShell.Commands.ServiceStartupType {get;set;}
Status              Property      System.ServiceProcess.ServiceControllerStatus Status {get;}
UserName            Property      System.String {get;set;}

Note that Get-Member gives details of each object coming through the pipeline, not of the whole collection of objects. So, in the output displayed from Get-Service, Get-Member gives details of the object representing a single service installed on the machine. It does not represent the collection of all services.

You can then use these property names with the Select-Object cmdlet to specify which properties you want to display.

For example:

> Get-Service | Select-Object ServiceName, Status, StartType

ServiceName                   Status StartType
-----------                   ------ ---------
ALG                          Stopped    Manual
AppHostSvc                   Running Automatic
AppIDSvc                     Stopped    Manual
Appinfo                      Running    Manual
AppMgmt                      Stopped    Manual

Upvotes: 0

FoxDeploy
FoxDeploy

Reputation: 13567

This type of question makes me think that you're probably coming from a Unix background, and are accustomed to having to deal with indicies and column index, that sort of thing.

Fundamentally, PowerShell is an object-oriented scripting language. You simply don't need to do what you're asking about here.

For instance, if you want to capture the results, then grab a property for one of the objects, here's how that's done.

First, capture the output.

$a=Get-Service

Now, you want a particular property of a particular entity. To get that, index into the object you want.

>$a[2]
Status   Name               DisplayName                           
------   ----               -----------                           
Stopped  AJRouter           AllJoyn Router Service                

To select the .DisplayName, all you have to do is append that to the end of your previous command.

> $a[2].DisplayName
AllJoyn Router Service

If you want to select multiple values, you could use this approach instead.

#Select multiple values from one entity
$a[2] | select DisplayName, Status

>DisplayName                        Status
-----------                        ------
Application Layer Gateway Service Stopped

#Select multiple values from each in the array
$a | select DisplayName, Status

>DisplayName                                               Status
-----------                                               ------
Adobe Acrobat Update Service                             Running
AllJoyn Router Service                                   Stopped
Application Layer Gateway Service                        Stopped
Application Identity                                     Stopped

Upvotes: 23

henrycarteruk
henrycarteruk

Reputation: 13237

The output from Get-Service that you see in the Console may look like an array (as it is formatted as a table when sent to the Console), but it is actually an 'System.ServiceProcess.ServiceController' object.

Rather than using row and column designations, you need to use the name of the property to retrieve it, so for your example:

$a[2].DisplayName will return Application Layer Gateway Service

Upvotes: 5

Joey
Joey

Reputation: 354874

This is not possible without a mapping from property names to array indices. Note that what you see in the output is just a partial list of properties (defined in an XML file somewhere). So there isn't even an easy way to convert those to array indices.

However, I also don't quite understand your need here. You can get the second service with $a[1], as expected. And then you can get its DisplayName property value with $a[1].DisplayName. PowerShell uses objects throughout. There is simply no need to fall back to text parsing or cryptic column indices just to get your data. There's an easier way.

Upvotes: 7

Related Questions