在 属性 中使用哈希表键

Using a hashtable key in a property

我正在尝试将找到的脚本 here 改编为等效的 PowerShell CSOM。

function setFieldVisibility(listTitle,fieldName,properties,success,failure)
{
     var ctx = SP.ClientContext.get_current(); 
     var web = ctx.get_web(); 
     var list = web.get_lists().getByTitle(listTitle);
     var field = list.get_fields().getByTitle(fieldName);
     field.setShowInDisplayForm(properties.ShowInDisplayForm);
     field.setShowInNewForm(properties.ShowInNewForm);
     field.setShowInEditForm(properties.ShowInEditForm);
     field.set_hidden(properties.Hidden);
     field.update();
     ctx.executeQueryAsync(success,failure);
}

在概括它的过程中,我试图传入一个哈希表。我想遍历此哈希表以动态构建要编辑的属性,但我遇到了一点麻烦。我的功能和用法如下所示:

Function Set-FieldProperties{

    param(
        [Parameter(Mandatory=$true)][string]$Url,
        [Parameter(Mandatory=$true)][string]$ListTitle,
        [Parameter(Mandatory=$true)][string]$FieldName,
        [Parameter(Mandatory=$true)][hashtable]$Properties
    )
    begin {
        $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url) 
        $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($credential.UserName, $credential.Password)
    }
    process{

        $web = $context.Web
        $list = $web.Lists.GetByTitle($ListTitle)
        $field = $list.Fields.GetByTitle($FieldName)
        foreach($key in $Properties.Keys){
            $key
            $Properties[$key]
            #failing to make this part dynamic
            $field.$key($Properties[$key])

        }
        <#$field.ShowInDisplayForm($properties.ShowInDisplayForm)
        $field.ShowInNewForm($properties.ShowInNewForm)
        $field.ShowInEditForm($properties.ShowInEditForm)
        $field.Hidden($properties.Hidden)
        try{
            $field.update()
            $context.executeQuery()
            Write-Host -ForegroundColor Green "Field properties updated successfully"
        }
        catch{
            Write-Host -ForegroundColor Red $_.Exception.Message
        }
        #>
    }
    end{
     $context.Dispose()
    }

}
Set-FieldPoperties -Url "https://tenant.sharepoint.com/teams/eric" -ListTitle "CalcColumns" -FieldName "Title" -Properties @{"SetShowInDisplayForm"=$true; "SetShowInEditForm"=$false}

我的努力在于如何使这部分建立所需的输出:

 foreach($key in $Properties.Keys){
                $key
                $Properties[$key]
                #failing to make this part dynamic
                $field.$key($Properties[$key])

            }

在这种情况下,如何使用键作为 属性 来设置 $field 对象?那可能吗?我不想对所有可能的属性进行一些巨大的 if 块检查,我希望它根据用户在 $Properties 哈希表中传递的内容来构建这些属性。

你可以使用

Invoke-Expression

这将动态评估字符串。

所以它看起来像这样:

iex "`$field.$key($($Properties[$key]))"
  • 双引号允许计算包含的变量
  • 反引号对 $field 参数进行转义,以便按字面意思输出
  • $key 被评估为 $key
  • 的值
  • $() 将使封闭的表达式计算

您可以使用Invoke-Expression创建动态命令,但我们需要对一些变量进行转义,使其在执行前不展开。

@avvi 的解决方案的问题是 $Properties[$key] 将 return $true,但由于它是字符串中的子表达式,它将被转换为 True。当它被执行时,它将是一个不带引号的字符串,这使得它调用了 function/cmdlet/program-name。这将引发错误,因为名为 True 的方法不存在等。例如

"`$field.$key($($Properties[$key]))"
#Returns:
$field.test(True)

#ERROR!!
At line:17 char:13
+ $field.test(True)
+             ~


"`$field.$key(`$Properties[`$key])"
#Returns:
$field.test($Properties[$key])

#Good. Will get value from Properties on execution => Object will not be converted to string.
#This allow both $key and returned value from $Properties to be any type of object

尝试:

## START Sample data
$field = New-Object psobject
Add-Member -InputObject $field -MemberType ScriptMethod -Name "test" -Value { param($in) $in.Gettype() | Out-Host; "in = $in" }

$Properties = @{ "test"  = $true }
## END Sample data


foreach($key in $Properties.Keys){
    $key
    $Properties[$key]
    #failing to make this part dynamic
    Invoke-Expression "`$field.$key(`$Properties[`$key])"
}

输出:

#From $key and $Properties[$key]
test
True

#From invoke-expression result
IsPublic IsSerial Name    BaseType        
-------- -------- ----    --------        
True     True     Boolean System.ValueType                                                                                

in = True