Ответ Матиаса Р. Джессена дает решение для передачи по трубам строк (имена процессов) в Stop-Process
.
ответ js2010 имеет правильное объяснение для , почему передача строк в Stop-Process
не работает (без дополнительных усилий) , а также предлагает полезную технику для отслеживания привязки параметров, но - на момент написания этой статьи - ответ содержит случайную информацию, которая немного смущает проблему.
Позвольте мне предложить более подробное объяснение :
Stop-Process
, в отличие от Stop-Service
, равно не , предназначенное для приема строк (имена процессов) в качестве конвейерного ввода.
Хотя строковый ввод в аннотации все еще может работать, а именно, если строки могут автоматически преобразовываться в один из ожидаемых типов данных по ByValue
(целому объекту) параметрам привязки к конвейеру команды это не случай с Stop-Process
потому что процесс имя (строка) не может (автоматически) быть преобразован в System.Diagnostics.Process
экземпляр (-InputObject
) [1] .
-
Когда PowerShell рассматривает привязку конвейерного ввода к параметру -Name
во время вызова, ищет объект со свойством Name
, потому что объявление параметра указывает этот конвейерный ввод принимается только , если входной объект имеет свойство, названное для параметра :
В разделах справки, например, для Stop-Process
, это выражается как ByPropertyName
.
В коде это выражается как логическое значение ValueFromPipelineByPropertyName
свойство типа System.Management.Automation.ParameterAttribute
; то есть, выраженное в коде PowerShell, объявление параметра выглядит примерно так: Обратите внимание, что ValueFromPipelineByPropertyName
- это сокращение от ValueFromPipelineByPropertyName = $true
[Parameter(ValueFromPipelineByPropertyName)] [string[]] $Name
A [string]
(System.String
), такой как "alg"
, не имеет свойства Name
- это само имя .
Следовательно, при отсутствии автомата c преобразование [1] в тип System.Diagnostics.Process
единственного ByValue
параметр -InputObject
и при отсутствии свойств Name
и Id
для параметров ByPropertyValue
вызов завершается с ошибкой со следующим сообщением об ошибке, которое, по сути, говорит о том, что конвейерный ввод недопустим (не может быть привязан ни к каким параметрам):
The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
Stop-Service
, в отличие , - это , предназначенный для приема строкового ввода , потому что его -Name
параметр (также) объявлен как принимающий строки непосредственно как объекты ввода, в целом .
В разделах справки, например, для Stop-Service
, это выражается как ByValue
.
В коде PowerShell это выражается как ValueFromPipeline
:
[Parameter(ValueFromPipeline)] [string[]] $Name
Примечание:
Хотя данный параметр может быть бот h ByValue
и ByPropertyValue
- что действительно имеет место для -Name
параметра Stop-Service
- что не типично.
Часто параметры привязки к конвейеру объявляются как скаляры , а не как массивы (например, для Sort-Object
, -InputObject <PSObject>
, а не -InputObject <PSObject[]>
), что означает, что передача нескольких аргументов поддерживается только через конвейер, а не по прямому аргументу - см. этот выпуск GitHub для справочной информации.
Изучение параметров привязки к конвейеру:
- Заданный параметр команды :
PS> Get-Help Stop-Process -Parameter Name
-Name <String[]>
Specifies the process names of the processes to stop. You can type multiple process names, separated by commas, or use wildcard characters.
Required? true
Position? named
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? true
Обратите внимание на строку Accept pipeline input?
; для параметра non -pipeline-привязки вы увидите False
во втором столбце.
- All параметры привязки к конвейеру поддерживается данной командой:
PS> (Get-Help Stop-Process -Parameter *).Where({ $_.pipelineInput -like 'True*' })
-Id <Int32[]>
Specifies the process IDs of the processes to stop. To specify multiple IDs, use commas to separate the IDs. To find the PID of a process, type
`Get-Process`.
Required? true
Position? 0
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? false
-InputObject <Process[]>
Specifies the process objects to stop. Enter a variable that contains the objects, or type a command or expression that gets the objects.
Required? true
Position? 0
Default value None
Accept pipeline input? True (ByValue)
Accept wildcard characters? false
-Name <String[]>
Specifies the process names of the processes to stop. You can type multiple process names, separated by commas, or use wildcard characters.
Required? true
Position? named
Default value None
Accept pipeline input? True (ByPropertyName)
Accept wildcard characters? false
[1] Если не объявлено, что параметр поддерживает преобразование пользовательского типа через атрибут System.Management.Automation.ArgumentTransformationAttribute
(редко), здесь применяются обычные правила преобразования PowerShell, в которых используется несколько методы, обсуждаемые в этом ответе . В случае System.Diagnostics.Process
преобразование из строки невозможно, поскольку целевой тип не имеет конструктора с одним аргументом, содержащего строку, и не имеет значения c .Parse()
метод. Быстрый тест на конвертируемость - попытка сбоя cast : [System.Diagnostics.Process] 'notepad'
. Напротив, [System.ServiceProcess.ServiceController] 'alg'
работает, потому что этот тип имеет , имеет конструктор с одним параметром, который принимает строку , но обратите внимание, что это преобразование не входит в играть во время привязки параметра при вызове Stop-Service
, например, 'alg' | Stop-Service
- там строка привязана как есть к параметру ByValue
-Name
.