Get-Service Behaviour, Please Explain

by DexterPOSH at 2012-08-27 08:50:08

Hi Power Users,

I have a confusion. This came up when I was showing someone in my office how cool PowerShell is.
Note: Using PowerShell version 2
File ComputerNames.txt contains two machine names.The following runs fine :

PS C:> Get-Process -ComputerName (gc .\ComputerNames.txt) -name “lsass” | select processname,machinename

ProcessName MachineName
----------- -----------
lsass server001
lsass server002

But why this behaves differently ?

PS C:> Get-Service -ComputerName (gc .\ComputerNames.txt) -name “bits” | select name,machinename

Name MachineName
---- -----------
bits server001

Get-Service only returns the Service Controller Objects for the first machine. What am I missing here ?

by FishTender27 at 2012-08-27 08:59:16
Is Bits installed on the second server?
by DexterPOSH at 2012-08-27 09:02:36
Hi FishTender27!
Thanks for the response.
Yeah ! it’s installed
Same thing happens for “wuauserv” too (for any service name).
Does that work fine with you ?

P.S. - Howerver if I use Get-Service without -name parameter it returns Objects for both machine names.
by FishTender27 at 2012-08-27 09:09:07
Can you try manually adding the names instead of pulling from a file?

Get-Service -ComputerName ‘Server001’,‘Server002’ -Name ‘bits’ | Select-Object Name,MachineName

Does that display the results correctly?
by FishTender27 at 2012-08-27 09:10:47
P.S. - Howerver if I use Get-Service without -name parameter it returns Objects for both machine names.[/quote]

This is odd. Are you using PS2 or 3?
by FishTender27 at 2012-08-27 09:15:50
Nevermind. I am on my iPhone and just saw you answer that question. I am at a doctor right now, I will see if I can replicate the issue when I leave.
by DexterPOSH at 2012-08-27 09:17:02
Hey FishTender27,

If I manually specify names with -computername parameter then also it returns the Service Objects for the first computer.
This is Odd. Other cmdlet like Get-Process work fine.
I am using PowerShell version 2.

This one works fine for me though,
get-content .\ComputerNames.txt | ForEach {Get-Service -Name wuauserv}
by DonJ at 2012-08-27 09:21:07
So, in your example code, you’re not doing anything with the piped-in information.

get-content .\ComputerNames.txt | ForEach {Get-Service -Name wuauserv -computername $_}

Would be correct. Your original example:

Get-Service -ComputerName (gc .\ComputerNames.txt) -name “bits” | select name,machinename

Should work fine, although BITS may not exist on every machine.
by FishTender27 at 2012-08-27 10:37:28
I thought the ComputerName property could take input in a comma seperated fashion, so shouldn’t the rest of the command interpret it as if they were run seperately? The commands succeed without issue if broken down like:

Get-Service -Name ‘BITS’ -ComputerName ‘Server001’ | Select-Object Name,MachineName
Get-Service -Name ‘BITS’ -ComputerName ‘Server002’ | Select-Object Name,MachineName
Get-Service -Name ‘BITS’ -ComputerName ‘Server003’ | Select-Object Name,MachineName

The issue only arrises if the ComputerName property is given a list, which does not occur with the same format given in a Get-Process. I did replicate this in my environment and did have success with the following command:

Get-Service -ComputerName ‘Server001’,‘Server002’,‘Server003’ -Include ‘BITS’ | Select-Object Name,MachineName

Name MachineName
---- -----------
by DonJ at 2012-08-27 10:41:58
It can definitely take a comma-separated list, or a list from Get-Content (provided the text file you’re using has one computer name per line - the text file itself can’t be a comma-separated list).

I’d expect the command to work the same with the comma-separated list. If it isn’t, then you’re hitting an anomaly I can’t explain.
by DexterPOSH at 2012-08-28 00:50:28
Hi Don,
I meant to say that when I use parentheses to feed the computer names to the Get-Service cmdlet it only returns objects for first computername.
Irrespective of the Service I choose to get the Service Object for.
The computernames.txt file has one computer name per line nothing else.
Get-Content .\computernames.txt

Following returns the Object for first computer name in the file:
Get-Service -ComputerName (gc .\ComputerNames.txt) -name “wuauserv” | select name,machinename

Name MachineName
---- -----------
wuauserv server001

and I noticed that -Displayname parameter also behaves the same way

Get-Service -DisplayName “Automatic Updates” -ComputerName (gc .\computernames.txt)

Status Name DisplayName
------ ---- -----------
Running wuauserv Automatic Updates

Hi FishTender27,
your example is using -include parameter, does this work with -name parameter in your machine ?
Get-Service -ComputerName ‘Server001’,‘Server002’,‘Server003’ -Include ‘BITS’ | Select-Object Name,MachineName
by poshoholic at 2012-08-28 05:37:37
Since the issue appears to happen when reading the contents of ComputerNames.txt, I recommend you verify some assumptions you are making about your ComputerNames.txt file. Make sure that it contains what you think it contains, like this:

[script=powershell]$computerNames = Get-Content .\ComputerNames.txt
"There were $($computerNames.Count) entries in the file."
for ($index = 0; $index -lt $computerNames.Count; $index++) {
“Entry ${index}: ‘$($computerNames.Count)’”
This will verify the count of the items that PowerShell reads from the file. It will also output one line per item in the file, with single quotes around the actual computer names so that you can see what PowerShell receives for each name when reading the file, including any whitespace surrounding them.

Another thing I would do when running into anomalous things like this is look at the hex contents of the file, either in a text editor or by using [System.IO.File]::ReadAllBytes, so that I can make sure I know what every single character in the file is.

Next I would try using an intermediate variable to store the contents of ComputerNames.txt and then I would step through this in a debugger so that I could inspect that variable when I ran it.

After that, if it was still failing I would use a foreach loop with a single Get-Service call per computer to make sure that works. If I’m only getting some computers and not all and no errors, I would verify that $ErrorActionPreference is properly set to Continue and specifically that it is not set to SilentlyContinue so that I receive any errors.

Each of these steps should put you one step closer to discovering what the problem is. Whenever you run into an issue where something works one way but it doesn’t work another way that should be functionally equivalent, focus on what the unexpected differences might be between the two ways you are doing things (in this case the ComputerNames.txt file) to see if that puts you closer to solving the problem
by DexterPOSH at 2012-08-28 06:55:51
Thanks Kirk for giving this tip.
I think MVP Shay Levy already found this way back.
One of my colleague shared this with me.