A Workaround for Using PowerShell’s Get-Service with the ComputerName Parameter

Without a doubt, one of the features in PowerShell that makes it so compelling is the pipeline. You run a cmdlet or script, and PowerShell spits out objects that are formatted on the screen for your viewing pleasure. With that said, sometimes the output is less than friendly. One quirk that always frustrates me is the Get-Service command. The command will display service information for remote computers, but the associated property name is MachineName rather than the traditional Computername parameter. In this article, I’ll show you a workaround for working with PowerShell’s Get-Service cmdlet.

Get-Service bits -computername chi-core01,chi-fp02,chi-hvr2,chi-dc04 | Select Status,Name,Machinename

Displaying the MachineName property (Image Credit: Jeff Hicks)
Displaying the MachineName property (Image Credit: Jeff Hicks)

I suppose that’s not completely unbearable, but I like using Computername, which is frequently used in PowerShell. This typically means resorting to a hashtable with Select-Object to rename the property.

Get-Service bits -computername chi-core01,chi-fp02,chi-hvr2,chi-dc04 | Select Status,Name,@{Name="Computername";Expression={$_.Machinename}}

Using Select-Object to rename a property (Image Credit: Jeff Hicks)
Using Select-Object to rename a property (Image Credit: Jeff Hicks)

That’s a lot to remember to type, so why not have PowerShell do the work for me?
PowerShell has always had an extensible type system. This means that you can extend what an object looks like. In earlier PowerShell versions, this mean relying on a complicated XML file. But now we can make changes practically on the fly. In this particular scenario, I want to create a property called Computername that will have the value from MachineName. In other words, I want to create an alias property.
First, I’m going to need to know the type name for the objects that Get-Service uses. I can discover this with Get-Member.
Getting type information for service objects (Image Credit: Jeff Hicks)
Getting type information for service objects (Image Credit: Jeff Hicks)

I’ve highlighted the type name. You’ll notice that there are already a few alias properties. PowerShell adds these automatically from included type extension XML files. But we’re not going to mess with them. Instead we’ll use a simple cmdlet called Update-TypeData.
I’ll need to specify the object type name, the type of member I intend to add, what I want to call it, and the value I want to assign.

Update-TypeData -TypeName System.ServiceProcess.ServiceController -MemberType AliasProperty -MemberName Computername -Value Machinename –Force

I typically also use the –Force parameter to overwrite any existing values. In this situation, I’m not changing anything that Microsoft defines, so I should be good. Let’s look at Get-Member again.

The revised object properties (Image Credit: Jeff Hicks)
The revised object properties (Image Credit: Jeff Hicks)


It is now defined. Like any other property in PowerShell, if it is defined, then I can use it.

Get-Service bits -computername chi-core01,chi-fp02,chi-hvr2,chi-dc04 |
Format-Table Status,Name,Computername -AutoSize

Using the alias property (Image Credit: Jeff Hicks)
Using the alias property (Image Credit: Jeff Hicks)

This property will only last for as long as my PowerShell session is running. To make it more permanent, I can put the Update-TypeData expression in my PowerShell profile script.
If you’re still not convinced, then here’s one more scenario. Many of you like to query Active Directory for computer accounts. Ideally, it would be nice to then pipe those results to other commands like Get-CimInstance, which will connect incoming objects with a Computername property to the command’s Computername parameter.
The ComputerName parameter for Get-CimInstance (Image Credit: Jeff Hicks)
The ComputerName parameter for Get-CimInstance (Image Credit: Jeff Hicks)

But when you run Get-ADComputer, there is no Computername parameter.
The AD Computer object (Image Credit: Jeff Hicks)
The AD Computer object (Image Credit: Jeff Hicks)

So why not add an alias property here as well?

Update-TypeData -TypeName Microsoft.ActiveDirectory.Management.ADComputer -MemberType AliasProperty -MemberName Computername -Value Name -Force

Now I can get a bunch of computers.

$c = Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=Globomantics,DC=Local"

And they now have a Computername property.

Using the new Computername property (Image Credit: Jeff Hicks)
Using the new Computername property (Image Credit: Jeff Hicks)

Going back to my Get-CimInstance thought, normally I would use a command like this:

$c | Get-CimInstance Win32_logicaldisk -filter "DeviceID='c:'" -ErrorAction SilentlyContinue

But because of some weird quirk of the AD Computer object with Get-Cimstance, this will fail. So in this particular case, I need to tweak the command a bit:

$c | Select * | Get-CimInstance Win32_logicaldisk -filter "DeviceID='c:'" -ErrorAction SilentlyContinue

Although since I’m select properties, I could just select Computername only.

$c | Select computername | Get-CimInstance Win32_logicaldisk -filter "DeviceID='c:'" -ErrorAction SilentlyContinue

Either way, I get results.

Pipelined results (Image Credit: Jeff Hicks)
Pipelined results (Image Credit: Jeff Hicks)

By the way, this is merely for demonstration purposes. I’ve set the error action to SilentlyContinue to ignore errors for offline computers. Normally you would want to handle errors with Try/Catch.
Finally, to circle around back to the beginning I can use the collection of AD computers with the Computername property to get service statuses and display the results with a Computername property:

$c | Get-Service bits -ErrorAction SilentlyContinue | Select Computername,Name,Status

Getting remote services in the pipeline (Image Credit: Jeff Hicks)
Getting remote services in the pipeline (Image Credit: Jeff Hicks)


Think about how you use PowerShell or how you would like to. How could you create easier PowerShell expressions? Perhaps you just need a new name and as you’ve seen it is very easy to do.