Help New-item -parameter "Value"
покажите нам -Value <System.Object> может быть привязан ByPropertyName или ByValue. Вопрос в том:
** Возможен ли канал ByPropertyName? **
Поскольку ByValue имеет приоритет над ByPropertyName, я не могу найти ни одного примера, позволяющего сделать этот канал. Все, что я пишу слева, является объектом и связано ByValue, даже если этот объект имеет атрибут -Value.
Спасибо
Пример:
$customObject = [PSCustomObject]@{
Value = "Lorem ipsum"
}
$customObject | New-Item -Name BPN_value.txt
Содержимое BPN_value.txt — это @{Value = "Lorem ipsum"}, потому что $customObject является объектом (очевидно) и привязывается byValue к параметру Value New_Item.





Можно ли привязать
New-Item -ValueпараметрByPropertyName?
Нет, потому что, как вы уже заметили, тип параметра — System.Object , и, поскольку все объекты наследуются от этого класса, каждый ввод из конвейера связан с ValueFromPipeline вместо ValueFromPipelineByPropertyName.
System.Object?Нет, потому что это будет конфликтовать с другими провайдерами. Например, определение новой функции больше невозможно:
$null = New-Item -Path function:Say-Hello -Value {
'hey there'
}
Say-Hello
-Value для привязки по имени свойства?Вероятно, нет, потому что он никогда не может быть связан им.
У вас может быть ProxyCommand или функция-оболочка вокруг New-Item, которая изменяет тип параметра с System.Object на System.String, таким образом, функция сможет работать правильно, принимая ValueFromPipeline и ValueFromPipelineByPropertyName. Затем вы можете сохранить эту оболочку в своем $PROFILE и иметь ее доступной для вас каждый раз, когда начинается новый сеанс.
По причинам, изложенным ранее, эта оболочка будет работать только с провайдером файловой системы и жестко закодирована для ItemType = File.
function New-File {
[CmdletBinding(DefaultParameterSetName='pathSet', SupportsShouldProcess=$true, ConfirmImpact='Medium', HelpUri='https://go.microsoft.com/fwlink/?LinkID=2096592')]
param(
[Parameter(ParameterSetName='pathSet', Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName='nameSet', Position=0, ValueFromPipelineByPropertyName=$true)]
[string[]]
${Path},
[Parameter(ParameterSetName='nameSet', Mandatory=$true, ValueFromPipelineByPropertyName=$true)]
[AllowNull()]
[AllowEmptyString()]
[string]
${Name},
[Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('Target')]
[string]
${Value},
[switch]
${Force}
)
begin {
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref] $outBuffer)) {
$PSBoundParameters['OutBuffer'] = 1
}
$PSBoundParameters['ItemType'] = 'File'
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\New-Item', [System.Management.Automation.CommandTypes]::Cmdlet)
$scriptCmd = { & $wrappedCmd @PSBoundParameters }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
process {
try {
$steppablePipeline.Process($Value)
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
end {
try {
$steppablePipeline.End()
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
<#
.ForwardHelpTargetName Microsoft.PowerShell.Management\New-Item
.ForwardHelpCategory Cmdlet
#>
}
[PSCustomObject]@{ Value = "Lorem ipsum" } | New-File .\BPN_value.txt -Force
"Lorem ipsum" | New-File .\BPN_value2.txt -Force
Для справки, определение кода, использованного выше, было сгенерировано автоматически с использованием:
[System.Management.Automation.ProxyCommand]::Create((Get-Command New-Item))
Затем он был немного изменен и упрощен для этого конкретного ответа.
@EduardoFernández Я рад, что ответ был полезен, и я рад помочь. Посмотрите мое обновление, чтобы показать вам, как этот код, используемый в функции, может быть сгенерирован автоматически.
Я понимаю. Действительно полезно! Мне есть чему поучиться :-)
Это возможно, если значения параметра -Path или -Name также являются свойством объекта в пайплайне:
[PSCustomObject]@{
name = 'TestFile'
value = 'Hello World'
} | New-Item
Захват консоли:
PS ScratchPad> [PSCustomObject]@{
>> Name = 'TestFile'
>> value = 'Hello World'
>> } | New-Item
Directory: C:\ScratchPad
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/23/2022 12:07 AM 35 TestFile
Или:
PS ScratchPad> [PSCustomObject]@{
>> Path = "$Home\Documents\TestFile.txt"
>> value = 'Hello World'
>> } | New-Item
Directory: C:\Users\keith\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/23/2022 12:27 AM 64 TestFile.txt
Но почему-то не любит -Path + -Name:
PS ScratchPad> [PSCustomObject]@{
>> Path = "$Home\Documents"
>> Name = 'TestFile'
>> value = 'Hello World'
>> } | New-Item
New-Item : Access to the path 'C:\Users\keith\Documents' is denied.
At line:5 char:5
+ } | New-Item
+ ~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Users\keith\Documents:String) [New
-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Comm
ands.NewItemCommand
Да, но содержимое будет строковой версией объекта, а не значением свойства
LOL, ты прав, я не проверял содержимое файла! Я никогда раньше не видел, чтобы объект конвейера выполнял «двойную функцию». Живи и учись!
Что происходит, так это то, что параметр Path связан с PropertyName (поскольку тип параметра — System.String[]), но затем весь объект связан значением с параметром Value (поскольку его тип — System.Object)
Точно, я не тот пример изначально написал, но у меня тоже так получилось XD
Большое спасибо за ответ! Я только недавно начал изучать powershell, и я нахожу ваш пример New-File невероятным. Я не совсем понимаю определение функции, но она понимает цель обертывания New-Item. Еще раз спасибо!! :-)