在属性中使用哈希表键

时间:2016-04-22 14:37:58

标签: powershell hashtable office365 csom

我正在尝试将找到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哈希表中传递的内容来构建它们。

2 个答案:

答案 0 :(得分:1)

您可以使用

Invoke-Expression

这将动态评估字符串。

所以它看起来像这样:

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

答案 1 :(得分:1)

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

@ avvi的解决方案的问题是$Properties[$key]将返回$true,但由于它是字符串中的子表达式,因此它将转换为True 。执行此操作时,它将是一个不带引号的字符串,使其成为函数/ ​​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