当键是字符串时,从数组中迭代获取值的正确方法是什么?

时间:2014-07-25 14:20:11

标签: powershell

我尝试将某些列表从Sharepoint导出到CSV文件中。我的目标是创建一个足够灵活的单个函数,以获取列表名称,CSV文件的标识符和要导出的FieldValues列表,然后生成CSV文件。这就是我到目前为止所拥有的:

function getTableData($_ctx, [string]$_colName)
{
    $list = $_ctx.Web.Lists.GetByTitle("$_colName")

    $camlQuery = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(100)
    $colItems = $list.GetItems($camlQuery)
    $_ctx.Load($colItems)
    $_ctx.ExecuteQuery();

    return $colItems
}

# More will go into this array, but for now a single entry is sufficient for testing purposes
$mstLists = @("GroupMst", "Groups", @("Title", "GroupCode"))

$cols = @()
foreach($col in $mstLists[0][2])
{
    $cols += @{Name=$col;expression={$_[$col];}}
}
$cols

# Grab all items from a list
getListData $ctx $mstLists[0][0] |
%{ select-object -input $_ -prop $cols } |
    Export-Csv -Path ($export_path + '\' + $current_date + '_' + $mstLists[0][1] + '.csv') -Encoding UTF8 -NoTypeInformation

我遇到的问题是在填充$ cols的循环中。基本上,每个项目都需要看起来像@{Name="Title";expression={$_["Title"];}}select-object中的ForEach才能从列表中获取正确的字段。不幸的是$cols最终看起来像这样:

Name                           Value
----                           -----
expression                     $_[$col];
Name                           Title
expression                     $_[$col];
Name                           GroupCode

哪个(以某种方式)生成如下所示的CSV文件:

"Title","GroupCode"
"LA","LA"
"NY","NY"
"TK","TK"

当输出需要如下所示:

"Title","GroupCode"
"Los Angeles","LA"
"New York","NY"
"Tokyo","TK"

我知道字段名称是正确的 - 如果我像这样硬编码...

# Grab all items from a list
getListData $ctx $mstLists[0][0] |
%{ select-object -input $_ -prop `
@{Name="Title";expression={$_["Title"];}}, `
@{Name='GroupCode';expression={$_["GroupCode"];}}; } |
    Export-Csv -Path ($export_path + '\' + $current_date + '_' + $mstLists[0][1] + '.csv') -Encoding UTF8 -NoTypeInformation

...然后我得到所需的CSV输出。我无法弄清楚如何让$_[$col]返回$_["Title"]

2 个答案:

答案 0 :(得分:2)

不确定$ mstLists [0] [2]的含义是什么,但下面的代码似乎给出了你想要的东西......

$mstLists = @("GroupMst", "Groups", @("Title", "GroupCode"))

$cols = @()
foreach($col in $mstLists[2])
{
    $cols += @{Name=$col; Expression = [scriptblock]::Create('$_["{0}"]' -f $col)}
}
$cols

给出了......

Name                           Value                                                                                                                                                      
----                           -----                                                                                                                                                      
Name                           Title                                                                                                                                                      
Expression                     $_["Title"]                                                                                                                                                
Name                           GroupCode                                                                                                                                                  
Expression                     $_["GroupCode"] 

答案 1 :(得分:1)

在您对评论中对andyb的回复中,您说数组的每个项目都将遵循格式

@("ListName", "CSVFileID", @("Field1", "Field2", "Etc..."))

并且$mstLists[0][2]"指的是数组中第一项中的字段列表。"

问题是它没有引用数组第一项中的字段列表,因为数组的第一项不是任何列表,它是字符串GroupMst。索引到字符串时,将获得索引指示的字符。由于 $ mstLists [0] 是一个字符串, $ mstLists [0] [2] 会返回该字符串的第三个字符,即o

我想你是否期望@运算符会使括号中的数组成为单个项目,这将成为 $ mstLists 的第一个元素?它没有。所有@ does都确保括号中的表达式被计算为数组而不是标量。因此,对于$a = ('string') $ a 是一个字符串,而对于$a = @('string') $ a 是一个包含单个字符串元素的数组。

但是,由于("GroupMst", "Groups", @("Title", "GroupCode"))无论如何都要对数组进行求值,因此将@放在前面是多余的。无论哪种方式,你仍然为变量分配一个文字数组。 $ mstLists 是一个包含三个元素的数组:

  • 元素0是字符串GroupMst
  • 元素1是字符串Groups
  • 元素2是字符串TitleGroupCode
  • 的数组

您要做的是使用,作为一元运算符:

$mstLists = , ("GroupMst", "Groups", @("Title", "GroupCode"))

现在 $ mstLists 是一个单项的数组,其值是上面项目符号列表中描述的数组,$mstLists[0][2]计算为字符串数组TitleGroupCode一样,正如你所期待的那样。

请注意,,用作返回操作数数组的一元或二元运算符。要返回单元素数组,可以将其用作该元素前面的一元运算符。如果您要将多个文字数组分配给 mstLists ,则只需在它们之间使用逗号,而不是前面的逗号:

$mstLists = ("ListName", "CSVFileID", @("Field1", "Field2", "Etc...")), ("ListName2", "CSVFileID2", @("Field1", "Field2", "Etc..."))

解决了主要问题。这仍然不能给你你想要的东西,因为 $ col 不会在表达式脚本块中进行插值,所以表达式将始终是字面$_[$col]。但是,为了弄清楚如何做你真正想做的事情,看一下 $ ctx 的内容样本会很有帮助。