Function PowerShell:函数没有正确的返回值

Function PowerShell:函数没有正确的返回值,function,powershell,compareobject,Function,Powershell,Compareobject,我编写了一个powershell脚本来比较两个文件夹的内容: $Dir1 ="d:\TEMP\Dir1" $Dir2 ="d:\TEMP\Dir2" function Test-Diff($Dir1, $Dir2) { $fileList1 = Get-ChildItem $Dir1 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name $fileList2 = G

我编写了一个powershell脚本来比较两个文件夹的内容:

$Dir1 ="d:\TEMP\Dir1"
$Dir2 ="d:\TEMP\Dir2"

function Test-Diff($Dir1, $Dir2) {
    $fileList1 = Get-ChildItem $Dir1 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name
    $fileList2 = Get-ChildItem $Dir2 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name

    if($fileList1.Count -ne $fileList2.Count) {
        Write-Host "Following files are different:"
        Compare-Object -ReferenceObject $fileList1 -DifferenceObject $fileList2 -Property Name -PassThru | Format-Table FullName
        return $false
    }

    return $true
}

$i = Test-Diff $Dir1 $Dir2

if($i) { 
    Write-Output "Test OK" 
} else { 
    Write-Host "Test FAILED" -BackgroundColor Red
}
如果我在Compare对象上设置了一个断点,并在控制台中运行这个命令,我将得到差异列表。如果我运行整个脚本,就不会得到任何输出。为什么?

我在PowerGUI脚本编辑器中工作,但我也尝试了普通的ps控制台

编辑:

问题在于脚本末尾的检查

$i = Test-Diff $Dir1 $Dir2

if($i) { 
   Write-Output "Test OK" 
...
如果我在没有$I=check的情况下调用Test Diff,它会工作

Test Diff返回一个对象数组,而不是预期的bool值:

[DBG]: PS D:\>> $i | ForEach-Object { $_.GetType() } | Format-Table -Property Name
 Name                                                                                                                        
 ----                                                                                                                        
 FormatStartData                                                                                                             
 GroupStartData                                                                                                              
 FormatEntryData                                                                                                             
 GroupEndData                                                                                                                
 FormatEndData                                                                                                               
 Boolean         
如果我用Compare对象注释掉该行,返回值将是一个布尔值,正如预期的那样


问题是:为什么?

我已经修改了您的脚本,使其按您希望的方式运行。我不确定您是否只想通过.Count属性比较文件,但这不在这个问题的范围之内。如果这不是你想要的,请发表评论,我会尝试编辑这个答案。基本上,据我所知,您希望在函数之后运行条件检查,而它可以在函数内部轻松实现

$Dir1 ="C:\Dir1"
$Dir2 ="C:\Users\a.pawlak\Desktop\Dir2"

function Test-Diff($Dir1,$Dir2)
{
$fileList1 = Get-ChildItem $Dir1 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name
$fileList2 = Get-ChildItem $Dir2 -Recurse | Where-Object {!$_.PsIsContainer} | Get-Item | Sort-Object -Property Name

if ($fileList1.Count -ne $fileList2.Count)
{
Write-Host "Following files are different:"
Compare-Object -ReferenceObject $fileList1 -DifferenceObject $fileList2 -Property FullName -PassThru | Format-Table FullName
Write-Host "Test FAILED" -BackgroundColor Red

}
else 
{ 
return $true
Write-Output "Test OK" 
}
}

Test-Diff $Dir1 $Dir2
如果有什么不清楚的地方,请告诉我


AlexP

我在这里找到了答案:

功能如下:

Function bar {
 [System.Collections.ArrayList]$MyVariable = @()
 $MyVariable.Add("a")
 $MyVariable.Add("b")
 Return $MyVariable
}
使用PowerShell方式返回对象:@0,1,a,b,而不是@a,b

要使此函数按预期工作,您需要将输出重定向到null:

Function bar {
 [System.Collections.ArrayList]$MyVariable = @()
 $MyVariable.Add("a") | Out-Null
 $MyVariable.Add("b") | Out-Null
 Return $MyVariable
}
在我们的例子中,函数必须按照Koliat的建议进行重构。

这是在每个命令后添加Null的一种替代方法,但最后一种方法是:

$i = (Test-Diff $Dir1 $Dir2 | select -last 1)

PowerShell函数始终将函数中执行的所有命令的结果作为对象[]返回,除非将命令管道输出为Null或将结果存储在变量中,但return语句后面的表达式始终是最后一个,并且可以使用select-last 1提取。

请在脚本上下文中显示该命令,因为该命令本身已成功运行。我提取了脚本中有问题的部分,它也可以从脚本中工作。我完全糊涂了…如果是最后的问题。如果我{Write Output Test OK…你能解释一下脚本的用途吗?最后的测试失败了吗?目的:比较目录。不,如果我检查返回值,测试永远不会失败。是的,它可以工作,但为什么返回原始函数一个数组而不是bool值呢?Test Diff函数由两个commands而不是简单的Bool值。Test Diff函数是一个由6个命令组成的数组,其中最后一个命令是Bool类型。将原始代码更改为if$i[5]并查看结果。$i | Get Member和$i.GetType查看详细信息。如果调用此数组中的最后一个对象,则返回的是所需的bool函数。不过,感谢您提出的问题,我做了一些研究并扩展了自己的理解:-在我看来,如果显式编写“return$false”,这不是例外行为。我认为$I应该是$true或$false,而不是一个命令数组。就我所见,$I是一个由多种类型组成的函数,而不是一个简单的$I=$true |$false。但是,我没有足够的经验来说明某个东西是否按设计工作或存在错误。我给出的解决方案是否清晰?是的,谢谢,很清楚。只有“返回”选项else分支中的$true'不清楚。这可能是复制粘贴错误。在我的情况下,我认为如果我想从函数返回失败,可靠的方法是抛出错误,而不是返回$false。Koliat是谁?在该页面上找不到具有该名称的人。