4

我正在学习 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计算机名,并且此参数的帮助文件看起来相同。有趣的是,如果我键入相同的代码但添加-Name bits到上面的Get-Service命令中,它会返回服务详细信息。所以看起来像是Get-Service试图将对象绑定到服务名称,但这不会发生Get-Process在语法上看起来非常相似的情况?!

4

2 回答 2

5

您将管道输入提供给Get-Service没有任何其他参数,因此管道对象被传递给接受它们的第一个参数,即-Name. 由于对象没有属性Name,因此它们被整体传递并转换为字符串,因此它们显示为@{computername=SERVERONE}. Get-Service然后查找具有该名称的服务,这当然会失败,从而导致您观察到的错误。

Get-Service(斜体的相关特征)的参数定义:

PS C:\> Get-Help Get-Service -Parameter Name

-Name 
    Specifies the service names of services to be retrieved. Wildcards
    are permitted. By default, Get-Service gets all of the services on
    the computer.

    Required?                    false
    Position?                    1
    Default value                All services
    Accept pipeline input?       true (ByPropertyName, ByValue)
    Accept wildcard characters?  true

PS C:\> Get-Help Get-Service -Parameter ComputerName

-ComputerName 
    Gets the services running on the specified computers. The default
    is the local computer.

    Type the NetBIOS name, an IP address, or a fully qualified domain
    name of a remote computer. To specify the local computer, type the
    computer name, a dot (.), or "localhost".

    This parameter does not rely on Windows PowerShell remoting. You
    can use the ComputerName parameter of Get-Service even if your
    computer is not configured to run remote commands.

    Required?                    false
    Position?                    named
    Default value                Local computer
    Accept pipeline input?       true (ByPropertyName)
    Accept wildcard characters?  false

Get-Process(斜体的相关特征)的参数定义:

PS C:\> Get-Help Get-Process -Parameter Name

-Name 
    Specifies one or more processes by process name. You can type
    multiple process names (separated by commas) and use wildcard
    characters. The parameter name ("Name") is optional.

    Required?                    false
    Position?                    1
    Default value
    Accept pipeline input?       true (ByPropertyName)
    Accept wildcard characters?  true

PS C:\> Get-Help Get-Process -Parameter ComputerName

-ComputerName 
    Gets the processes running on the specified computers. The default
    is the local computer.

    Type the NetBIOS name, an IP address, or a fully qualified domain
    name of one or more computers. To specify the local computer, type
    the computer name, a dot (.), or "localhost".

    This parameter does not rely on Windows PowerShell remoting. You
    can use the ComputerName parameter of Get-Process even if your
    computer is not configured to run remote commands.

    Required?                    false
    Position?                    named
    Default value                Local computer
    Accept pipeline input?       true (ByPropertyName)
    Accept wildcard characters?  false

如您所见,两个 cmdlet 之间的参数定义存在差异不仅可以按属性名称接受管道输入,还可以按值接受管道输入,但不接受。这就是为什么按预期处理您的管道输入,而没有。-NameGet-Service-NameGet-ProcessGet-ProcessGet-Service

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

Get-ADComputer -Filter 'Name -eq "serverone"' |
  select @{n='ComputerName';e={$_.Name}} |
  Get-Service -Name *
于 2015-05-19T22:15:33.810 回答
0

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

Get-Service 有 3 个:DefaultDisplayNameInputObject

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

您可以通过这种方式使用可用的参数集:

  • InputObject:它需要一个ServiceController类型对象,这不是你的情况。
  • DisplayName:这需要您明确指定参数名称例如:

1 |
select @{l='computername';e={$env:COMPUTERNAME}} |
gsv -DisplayName 'your-service's-display-name'

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

1-作为位置参数:

1 |
select @{l='computername';e={$env:COMPUTERNAME}} |
gsv alg # 'alg' is the service name; you can choose some other(s)

2-作为对象参数:

1 |
select @{l='name';e={'alg'}},@{l='computername';e={$env:COMPUTERNAME}} |
gsv

请注意,最后一个非常类似于您的代码。重要的区别是我定义了你不是对象的属性Name(除了ComputerName)。

于 2015-05-20T02:03:13.003 回答