Author Posts

November 26, 2017 at 9:57 pm

I'm very new to PowerShell, and I'm watching the Microsoft VMA Videos on getting started with PowerShell. I'm looking at Chapter 5 – "The Pipleline: Deeper."

The line that they use is:

 get-adcomputer -filter * |select -property @{n="ComputerName";e={$_.name}} | Get-Service -name bits 

For me this shows the bits service running locally, but not on the remote server. For the remote service I get an error:

Get-Service: Cannot find any service with service name "bits"

I did some rather stupid things trying to troubleshoot this. As it was my lab, I built a new server, and try to rule out any network and DNS issues.

But all I needed to do for the command to work, was to use a wildcard. This command works for me:

get-adcomputer -filter * |select -property @{n="ComputerName";e={$_.name}} | Get-Service -name bits*

Now I can see 2 bits services running and no errors like in the video.

In my job, I deal more with Printing side of things so I tried with the Spooler Service.

Sure enough, this gets an error for remote server:

get-adcomputer -filter * |select -property @{n="ComputerName";e={$_.name}} | Get-Service -name spooler

Whereas this one shows both spoolers:

get-adcomputer -filter * |select -property @{n="ComputerName";e={$_.name}} | Get-Service -name spooler*

Why is this happening? Is it normal? It's not happening in the guy's video on MVA? Will I have to always use the wildcard character when running any scripts which touch remote services in future? :-\

November 27, 2017 at 6:51 am

There are some environmental issues in your environment.

Bits is the exact name of the service.
Using the '*' is of course just a wildcard that says give me anything that starts with bits.

Either approach is fine, as it should return the named service / services which match the defined name / string pattern.
So, I would not stress out over it, generally, but again, this looks to be environmental as there is really nothing special about what you are doing or how you are doing it.

The pipeline is all about passing the results (or part of it) to another item.
There are several commands that have a computername property / switch and just work on remote systems without any more real effort.Of course there are many ways to do thing on PoSH. Example, all the below do the same thing

So, this is get all AD computer base properties, select name from the properties, and create a new property called computername to match the property Get-service.
Get-ADComputer -filter * | select -property @{n="ComputerName";e={$_.name}} | Get-Service -name BITS

Here's the deal though with these two cmdlets. There is no property called ComputerName in either of them.
One has Name, and the other is called machine name. So, using computername as a match is moot.
The Pipeline will try and match by property name or by value.

See details here:
'blogs.technet.microsoft.com/heyscriptingguy/2013/03/25/learn-about-using-powershell-value-binding-by-property-name'
'mcpmag.com/articles/2015/05/20/functions-that-support-the-pipeline.aspx'

These both provide a matching value. So, that is what the pipeline will use.

(Get-ADComputer -Filter *)[0]
DistinguishedName : CN=DC01,OU=Domain Controllers,DC=contoso,DC=com
DNSHostName : DC01.contoso.com
Enabled : True
Name : DC01
ObjectClass : computer
ObjectGUID : fe693a48-96d1-4d62-a09a-2a009c707a4f
SamAccountName : DC01$
SID : S-1-5-21...
UserPrincipalName :

Get-Service -ComputerName $env-COMPUTERNAME -Name BITS | Select -Property *
Name : BITS
RequiredServices : {RpcSs, EventSystem}
CanPauseAndContinue : False
CanShutdown : False
CanStop : True
DisplayName : Background Intelligent Transfer Service
DependentServices : {}
MachineName : DC01
ServiceName : BITS
ServicesDependedOn : {RpcSs, EventSystem}
ServiceHandle : SafeServiceHandle
Status : Running
ServiceType : Win32ShareProcess
StartType : Manual
Site :
Container :

So, these two examples, return the same thing your example is designed to deliver
..as well as... No calculated properties needed. Just passing value match.

Get-ADComputer -filter * | % {Get-Service -ComputerName $_.Name -Name BITS}

Get-Service -ComputerName ((Get-ADComputer -filter *).Name) -Name BITS

If you are trying to match by property in this effort then...

get-adcomputer -filter * |select -property @{n="ComputerName";e={$_.name}} | Get-Service -name bits

...would be this...

get-adcomputer -filter * |select -property @{n="MachineName";e={$_.name}} | Get-Service -name bits

Thus converting the Name property from Get-ADCompputer to match the MachineName property in Get-Service.
Again, in this case it would not matter what you names the property, as the Pipeline will just grab matching values.

November 27, 2017 at 9:24 am

Thank you very much for your reply. I'm still reading through it, but it sure looks helpful!

I've just discovered that the reason why it's not working exactly as I expected it to is because I'm doing this via a PSSession to my VM Lab, from my local workstation (outside of the Domain). If I run the same command directly on the DC, I'm able to see running BITS service on all my ADComputers as expected, with no errors. 🙂

I notice in the MVA Video (The Pipeline:Deeper") they aren't using PSSession, so that's what's different between my attempt, and what they're doing.

November 27, 2017 at 11:13 am

Get-Service does have a -ComputerName property that's why Select-Object is used to create a property with that name

PS> Get-Command Get-Service -Syntax

Get-Service [[-Name] ] [-ComputerName ] [-DependentServices] [-RequiredServices] [-Include ] [-Exclude ] []

Get-Service -DisplayName  [-ComputerName ] [-DependentServices] [-RequiredServices] [-Include ] [-Exclude ] []

Get-Service [-ComputerName ] [-DependentServices] [-RequiredServices] [-Include ] [-Exclude ] [-InputObject ] []