PowerShell. Можно ли привязать параметр New-Item -Value ByPropertyName?

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.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
76
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Можно ли привязать 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))

Затем он был немного изменен и упрощен для этого конкретного ответа.

Большое спасибо за ответ! Я только недавно начал изучать powershell, и я нахожу ваш пример New-File невероятным. Я не совсем понимаю определение функции, но она понимает цель обертывания New-Item. Еще раз спасибо!! :-)

Eduardo Fernández 23.11.2022 20:55

@EduardoFernández Я рад, что ответ был полезен, и я рад помочь. Посмотрите мое обновление, чтобы показать вам, как этот код, используемый в функции, может быть сгенерирован автоматически.

Santiago Squarzon 23.11.2022 20:56

Я понимаю. Действительно полезно! Мне есть чему поучиться :-)

Eduardo Fernández 23.11.2022 21:27

Это возможно, если значения параметра -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

Да, но содержимое будет строковой версией объекта, а не значением свойства

Santiago Squarzon 23.11.2022 14:11

LOL, ты прав, я не проверял содержимое файла! Я никогда раньше не видел, чтобы объект конвейера выполнял «двойную функцию». Живи и учись!

Keith Miller 23.11.2022 17:47

Что происходит, так это то, что параметр Path связан с PropertyName (поскольку тип параметра — System.String[]), но затем весь объект связан значением с параметром Value (поскольку его тип — System.Object)

Santiago Squarzon 23.11.2022 17:52

Точно, я не тот пример изначально написал, но у меня тоже так получилось XD

Eduardo Fernández 23.11.2022 20:45

Другие вопросы по теме