Powershell 获取服务参数绑定未按预期工作

Powershell 获取服务参数绑定未按预期工作,powershell,parameterbinding,Powershell,Parameterbinding,我正在学习PowerShell,对参数绑定有一个问题。这可能是个简单的问题,但我不知所措 如果我键入: get-adcomputer -filter 'name -eq "serverone"' | select @{name='computername';e={$_.name}} | get-process 这给了我一个“serverone”上的进程列表,效果很好。但如果我输入: get-adcomputer -filter 'name -eq "serverone"' | se

我正在学习PowerShell,对参数绑定有一个问题。这可能是个简单的问题,但我不知所措

如果我键入:

get-adcomputer -filter 'name -eq "serverone"' |
  select @{name='computername';e={$_.name}} |
  get-process
这给了我一个“serverone”上的进程列表,效果很好。但如果我输入:

get-adcomputer -filter 'name -eq "serverone"' |
  select @{name='computername';e={$_.name}} |
  get-service
然后我得到以下错误:

get-service : Cannot find any service with service name
'@{computername=SERVERONE}'. At line:1 char:93
+ ... e={$_.name}} | get-service
+                    ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{computername=SERVERONE}:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

为什么会这样?
Get Process
Get Service
都接受computername,并且此参数的帮助文件看起来相同。有趣的是,如果我键入相同的代码,但将
-Name位
添加到上面的
获取服务
命令中,它会返回服务详细信息。因此,
Get Service
似乎正在尝试将对象绑定到服务名称,但在语法上非常相似的
Get Process
中不会发生这种情况

在没有任何其他参数的情况下,将管道输入馈送到
Get Service
,因此管道对象被传递到接受它们的第一个参数,即
-Name
。由于对象没有属性
名称
,它们被完整地传递并转换为字符串,因此它们显示为
@{computername=SERVERONE}
<代码>获取服务然后查找具有该名称的服务,这当然会失败,导致您观察到的错误

获取服务的参数定义(相关特征以斜体显示):

PS C:\>获取帮助获取服务-参数名称
-名字
指定要检索的服务的服务名称。通配符
是允许的。默认情况下,Get Service获取上的所有服务
电脑。
必修的?假的
位置?1.
所有服务的默认值
接受管道输入?true(ByPropertyName,ByValue)
是否接受通配符?真的
PS C:\>获取帮助获取服务-参数ComputerName
-计算机名
获取在指定计算机上运行的服务。默认值
是本地计算机。
键入NetBIOS名称、IP地址或完全限定的域
远程计算机的名称。要指定本地计算机,请键入
计算机名,点(.)或“localhost”。
此参数不依赖于Windows PowerShell远程处理。你
可以使用Get Service的ComputerName参数,即使您的
计算机未配置为运行远程命令。
必修的?假的
位置?命名
默认值本地计算机
接受管道输入?true(ByPropertyName)
是否接受通配符?错误
获取过程的参数定义(相关特征以斜体显示):

PS C:\>获取帮助获取进程-参数名称
-名字
按进程名称指定一个或多个进程。你可以打字
多个进程名称(用逗号分隔)并使用通配符
人物。参数名称(“名称”)是可选的。
必修的?假的
位置?1.
默认值
接受管道输入?true(ByPropertyName)
是否接受通配符?真的
PS C:\>获取帮助获取流程-参数ComputerName
-计算机名
获取在指定计算机上运行的进程。默认值
是本地计算机。
键入NetBIOS名称、IP地址或完全限定的域
一台或多台计算机的名称。要指定本地计算机,请键入
计算机名、点(.)或“localhost”。
此参数不依赖于Windows PowerShell远程处理。你
即使您的
计算机未配置为运行远程命令。
必修的?假的
位置?命名
默认值本地计算机
接受管道输入?true(ByPropertyName)
是否接受通配符?错误
如您所见,两个cmdlet之间的
-Name
参数的定义存在差异<代码>获取服务
不仅按属性名称,而且按值接受
-Name
的管道输入,而
获取过程
不接受管道输入。这就是为什么
Get-Process
会按预期处理管道输入,而
Get-Service
不会

要避免此问题,您需要指定要获取的服务。对所有服务使用
*
。指定了
-Name
参数后,计算机名称将按您想要的属性名称传递给
-ComputerName
参数:

Get-ADComputer-Filter'Name-eq“serverone”'|
选择@{n='ComputerName';e={$\u.Name}|
获取服务名称*

cmdlet具有参数集(1个或多个)

获取服务有3个:默认值显示名称输入对象

不幸的是,您没有使用它们中的任何一个,这就解释了为什么PowerShell会抱怨某些事情

可以通过以下方式使用可用的参数集:

  • InputObject:它需要一个
    ServiceController
    类型的对象,这不是您的情况
  • DisplayName:这要求您明确地指定参数名,,如:
1 |

选择{l='computername';e={$env:computername}}}

gsv-DisplayName“您的服务的-display-name”

  • 默认值:这可能是与您的代码匹配的代码。此参数集允许您将ComputerName参数作为对象属性或位置参数传递。例如:
1-作为位置参数:

1 |

选择{l='computername';e={$env:computername}}}

gsv-alg#“alg”是服务名称;您可以选择其他一些

2-作为对象参数: