Powershell 为什么递归在if语句中不起作用?

Powershell 为什么递归在if语句中不起作用?,powershell,Powershell,我正在尝试编写脚本,将扩展名为.txt的文件内容复制到一个。脚本正在工作,但-recurse不工作。(它不会复制子文件夹中的文件),我不知道为什么会这样。我的脚本是这样的: function UnifyConfigs { param ( $destination = "C:\temp\all.txt", [Parameter()] $files ) foreach ($config in $

我正在尝试编写脚本,将扩展名为.txt的文件内容复制到一个。脚本正在工作,但-recurse不工作。(它不会复制子文件夹中的文件),我不知道为什么会这样。我的脚本是这样的:

function UnifyConfigs {
        param (
        $destination = "C:\temp\all.txt",
        [Parameter()]
        $files
    )
  
    foreach ($config in $files) {
        If((Get-ChildItem $config -Recurse).LastWriteTime -gt (Get-Item $destination).LastWriteTime)
        {
            Clear-Content -path $destination
            Set-Content -path $destination -value (Get-Content $config) 
        }
        else {
            break
        }  
    }
}

是的:我已经用-force:-)尝试过了。

首先,您需要将
Get ChildItem-Recurse
调用移动到将输入字符串解析为文件系统中实际文件的位置:

foreach ($config in Get-ChildItem $files -Recurse) {
    if($config.LastWriteTime -gt (Get-Item $destination).LastWriteTime)
    {
        Clear-Content -path $destination
        Set-Content -path $destination -value (Get-Content $config) 
    }
    else {
        break
    }  
}
如果您只想测试任何输入文件是否比目标文件更新,然后用所有其他txt文件覆盖目标文件的内容,这实际上会变得简单一些-我们可以完全放弃外部循环:

# Discover all the files
$configFiles = Get-ChildItem $files -Recurse

# use `-gt` and the destination timestamp to "filter" all the config file timestamps
# if _any_ of them are newer that $destination, then the condition is true
if(@($configFiles.LastWriteTime) -gt (Get-Item $destination).LastWriteTime){
    # pipe every file to Get-Content, and then overwrite $destination with the whole thing
    $configFiles |Get-Content |Set-Content -Path $destination -Force
}
我还建议重构参数名称,以更好地反映预期的输入(“C:\path\to*files”是表示“路径”的字符串,而不是“文件”):


我在上面大多数地方使用
-LiteralPath
的原因是因为
$DestinationPath
只是,另一方面,
-Path
将通配符视为可扩展的,这仅适用于此函数中的
$Path

参数值,如果$config不是真正的文件路径,那么就没有什么可以递归的了。你能解释一下调用getChildItem的目的吗,以及为什么在那里使用-recurse吗?例如,$config中会有什么?你能给出一些具体的例子吗?请告诉我们如何调用
UnifyConfigs
,这也是我调用函数的方式:UnifyConfigs-files C:\PowerShell*.txt$files-将是一个目录(如上所示),所有文件*.txt都应该从中获取。$config是路径$files中的单个文件谢谢,但是在这个配置中,
foreach($config in Get ChildItem$files-Recurse)
似乎根本不起作用:/不幸的是,没有错误,所以我很难验证可能的错误。@Patrycja如果您尝试在提示符中手动执行它,它会起作用吗?例如,
Get ChildItem C:\PowerShell*.txt-Recurse
是否返回任何内容?是的,它显示此路径中的所有文件,包括子文件夹中的一个文件。问题不在于
foreach()
语句,但是内部的
if/else
语句-如果遇到的第一个文件早于
$DestinationPath
,然后它将进入
else
块并
break
跳出循环-可能会在
if
else
块的顶部添加一个
Write Host$config.FullName
语句,如果您想要直观地指示正在发生的事情。看起来您是对的,但脚本仍然无法按要求工作。现在我可以看到,它检测子文件夹中文件的修改日期,但它不接受它的内容。我可以想象,如果以后对其中任何一个文件进行了修改,那么它将获取
$files
中所有*.txt文件的内容
$DestinationPath
function Update-UnifiedConfig {
    param (
        [Parameter(Mandatory = $false)]
        [string]$DestinationPath = "C:\temp\all.txt",

        [Parameter(Mandatory = $true)]
        [string]$Path
    )

    $destinationLastModified = (Get-Item -LiteralPath $DestinationPath).LastWriteTime

  $configFiles = Get-ChildItem $files -Recurse

  if(@($configFiles.LastWriteTime) -gt $destinationLastModified){
    $configFiles |Get-Content |Set-Content -LiteralPath $DestinationPath -Force
  }
}