【问题标题】:How to refer to a dynamically named variable with a variable?如何用变量引用动态命名的变量?
【发布时间】:2019-07-10 14:06:12
【问题描述】:

所以,我正在编写一个函数。我创建的函数参数之一称为ObjectName,我想使用它来允许用户指定函数应该创建的 PSObject 的名称,并向其中添加成员。新的 PSObject 应该以为此参数提供的任何字符串命名。

该函数的目的是从一个文件中读取一个字符串列表,这些字符串的名称和值由:分隔,用:分割字符串并将两个分割字符串用作-Name-Value 输入为 Add-Member cmdlet。

以下是输入文件的示例:

User creation report
name: John Doe
 startDate: 01/01/2019
 creationTime: 2019-01-01T18:29:56.954Z
department: Sales
 locale: 
  unit: 

代码:

function New-ObjectFromFile {

    param (
        # Specify input data from file containing employee data.
        [Parameter(
            Position            = 0,
            Mandatory           = $true,
            ValueFromPipeline   = $true,
            HelpMessage         = 'Input file required.'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $File,
        # Specify name of object to be created.
        [Parameter(
            Position            = 1,
            Mandatory           = $true,
            ValueFromPipeline   = $false,
            HelpMessage         = 'Object name required. This will be the name of the PSObject this function creates.'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $ObjectName
    )

    # Read data from -File param
    $inputData = Get-Content -Path $File
    # Remove empty lines and non-properties from array
    $inputData = $inputData | Where-Object {$_ -like '*:*'}
    # Create new empty PSObject named after -ObjectName param
    New-Variable -Name $ObjectName -Value $(New-Object -TypeName PSObject)
    # Add array items as members to object
    foreach ($line in $inputData) {
        # Split line, max string count of 2 in order to preserve values containing ':'
        $lineSplit = $line -split ':',2
        # Remove leading and trailing whitespace from name and value
        $name = $lineSplit[0].trim()
        $value = $lineSplit[1].trim()
        # Only add non-empty properties
        if ('' -ne $value) {
            $ObjectName | Add-Member -MemberType NoteProperty -Name $name -Value $value
        }
    }
}

我认为可能需要不同方法的两部分是New-Object -Name $ObjectData... 行(其中 PSObject 以一种有点 hacky 的方式创建,以便使用提供的对象名称)和 $ObjectName | Add-Member... 行添加每行的名称并将值作为对象的 NoteProperty。

我已经尝试了多种不同的方法来代替上述Add-Member的用法:

$($ObjectName.ToString()) | Add-Member -MemberType NoteProperty -Name $name -Value $value

导致$providedName(在函数调用中为-ObjectName 指定的名称)仍然是一个空对象,除了 PSObject 的默认方法(Equals、GetHashCode、GetType、ToString)之外没有任何成员

Add-Member -MemberType NoteProperty -Name $name -Value $value -InputObject $(Get-Variable -Name $ObjectName.ToString())

同样的结果。

Add-Member -MemberType NoteProperty -Name $name -Value $value -InputObject $(Get-Variable -Name $($ObjectName.ToString()))

同样的结果。

我知道 PSObject 是按预期创建的(空的),因为我已经在 shell 中逐步完成了它。 Add-Member 用法是我认为我真正需要解决方案的地方。

在这一点上,我确定我的做法是错误的。我错过了一些明显的东西吗?欢迎任何反馈或想法。

编辑:我在没有真正说明问题的情况下打了很多字。如何使用参数输入指定的$ObjectName 作为Add-Member 的输入?我想向一个对象添加成员,但我不知道对象的名称是什么,直到在调用函数时提供它。我需要将$ObjectName 传递给Add-Member,以真正传递用户提供的任何对象名称,而不是“ObjectName”而是$userSpecifiedObjectName

【问题讨论】:

  • 看看ConvertFrom-StringData。您需要删除描述行并将: 替换为=,但结果将是一个可用于构建对象的哈希表。

标签: function powershell


【解决方案1】:

不确定这是否是您要查找的内容。但这会将“:”分隔的项目(名称:John Doe)添加到您正在创建的 PSObject 中。在您的 foreach 循环中,

(Get-Variable -name $ObjectName).Value | Add-Member -MemberType NoteProperty -Name $name -Value $value

你可以引用那个对象

(Get-Variable -name $ObjectName).Value.Name

这就是你想要做的吗?如果没有,您能再解释一下吗?

【讨论】:

  • 做到了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-09-19
  • 2018-05-06
  • 2010-10-20
  • 2011-08-18
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多