PowerShell ForEach/Piping混乱

hex*_*ate 11 powershell foreach piping tfs2010

我在PowerShell中使用TFS PowerTools Cmdlet尝试从我的服务器获取有关Changeset和相关WorkItem的一些信息.我把问题归结为我不理解的行为,我希望它不是TFS特定的(所以有人可能能够向我解释这个问题:))

这是我可以开始工作的唯一命令:

Get-TfsItemHistory C:\myDir -recurse -stopafter 5 | % { Write-Host $_.WorkItems[0]["Title"] }

它做了我所期望的 - Get-TfsItemHistory返回一个包含5个ChangeSet的列表,并将它们传递给foreach,它打印出第一个关联WorkItem的Title.那我的问题是什么?我正在尝试编写一个大型脚本,我更喜欢将事物编写为更像C#程序(powershell语法让我哭泣).每当我尝试以任何其他方式执行上述操作时,WorkItems集合为空.

以下命令(我解释为在逻辑上等效)不起作用(WorkItems集合为null):

$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5
$items | ForEach-Object { Write-Host $_.WorkItems[0]["Title"] }

我真的更喜欢的那个:

$items = Get-TfsItemHistory C:\myDir -recurse -stopafter 5
foreach ($item in $items)
{
    $item.WorkItems[0]["Title"]
    # do lots of other stuff
}

我读了一篇关于'foreach'运算符和ForEach-Object Cmdlet之间差异的文章,但这似乎更像是一场性能争论.这似乎是关于何时使用管道的问题.

我不确定为什么这三种方法都不起作用.任何见解都表示赞赏.

Kei*_*ill 13

这确实令人困惑.现在,解决方法是抓住这样的项目:

$items = @(Get-TfsItemHistory . -r -Stopafter 25 | 
           Foreach {$_.WorkItems.Count > $null; $_})
Run Code Online (Sandbox Code Playgroud)

这会访问WorkItems集合,这似乎会导致填充此属性(我知道 - WTF?).我倾向于@()在我想使用foreach关键字的情况下生成数组.使用foreach关键字的事情是它将迭代包含$ null的标量值.因此,如果查询没有返回任何内容,则$items分配$ null,foreach将循环迭代一次,$item设置为null.现在PowerShell通常非常好地处理空值.但是,如果将该值交还给.NET Framework,通常不会那么宽容.这@()将保证一个数组中包含0,1或N个元素.如果它为0,那么foreach循环将根本不执行它的主体.

BTW你最后的方法 - foreach ($item in $items) { ... }应该工作得很好.