Powershell 复制子文件夹和文件,选中“复制”;“上次修改时间”;

Powershell 复制子文件夹和文件,选中“复制”;“上次修改时间”;,powershell,backup,Powershell,Backup,我制作了一个备份脚本: 从XML文件读取源文件路径和目标文件夹路径 检查源文件和目标路径是否存在(对于每个文件) 检查目标文件夹中是否存在源文件(同名) 检查每个源文件和目标文件(如果该文件存在于目标文件夹中)的上次修改日期 如果源文件不存在,或者源文件比目标文件夹中的现有文件新,则将源文件复制到目标文件夹,否则不执行任何操作 这仅适用于源文件,如果在XML文件中指定了源文件夹,则只复制该文件夹,而不复制其任何内容 我不想使用copyitem-Recurse,因为我想检查每个项目的最后修改日期,

我制作了一个备份脚本:

  • 从XML文件读取源文件路径和目标文件夹路径
  • 检查源文件和目标路径是否存在(对于每个文件)
  • 检查目标文件夹中是否存在源文件(同名)
  • 检查每个源文件和目标文件(如果该文件存在于目标文件夹中)的上次修改日期
  • 如果源文件不存在,或者源文件比目标文件夹中的现有文件新,则将源文件复制到目标文件夹,否则不执行任何操作
  • 这仅适用于源文件,如果在XML文件中指定了源文件夹,则只复制该文件夹,而不复制其任何内容

    我不想使用
    copyitem-Recurse
    ,因为我想检查每个项目的最后修改日期,如果它不符合上述条件,我根本不想复制它

    这使我想到了
    Get ChildItem-Recurse
    来列出所有内容,但我在想出适用于此示例的内容时遇到了困难:

    C:\powershell\test\ (XML specified source)
    
    基础结构:

    C:\powershell\test\xmltest2.xml
    C:\powershell\test\test2\xmltest.xml
    C:\powershell\test\test3\test4\xmltest3.xml
    etc.
    
    i、 e.我想在复制之前检查每个文件,但如果说一个文件夹没有被修改,但其中的一个文件应该被复制,它应该仍然工作,并保留相同的文件夹结构


    有什么想法吗?:)

    正如Ansgar Wiechers所说,你正在重新发明轮子,机器人技术将更容易做到这一点。RoboCopy还可以复制安全权限和创建/修改日期,这很好。相关机器人技术讨论:

    不过,这不像自己写的那么有趣,是吗?我想到了这个:

    # Assuming these two come from your XML config, somehow
    $xmlSrc = "c:\users\test\Documents\test1"
    $xmlDestPath = "c:\users\test\Documents\test2"
    
    #==========
    # Functions
    #==========
    function process-file ($item) {
        #$item should be a string, full path to a file
        #e.g. 'c:\users\test\Documents\file.txt'
    
        # Make the destination file full path
        $destItem = $item.ToLower().Replace($xmlSrc, $xmlDestPath)
    
        if (-not (Test-Path $destItem)) {  #File doesn't exist in destination
    
            #Is there a folder to put it in? If not, make one
            $destParentFolder = Split-Path $destItem -Parent
            if (-not (Test-Path $destParentFolder)) { mkdir $destParentFolder }
    
            # Copy file
            Copy-Item $item -Destination $destParentFolder -WhatIf
    
        } else {  #File does exist
    
            if ((Get-Item $item).LastAccessTimeUtc -gt (Get-Item $destItem).LastAccessTimeUtc) {
    
                #Source file is newer, copy it
                $destParentFolder = Split-Path $destItem -Parent
                Copy-Item $item -Destination $destParentFolder -Force -WhatIf
            }
        }
    }
    
    function process-directory($dir) {
        # Function mostly handles "copying" empty directories
        # Otherwise it's not really needed
    
        # Make the destination folder path
        $destDir = $dir.ToLower().Replace($xmlSrc, $xmlDestPath)
    
        # If that doesn't exist, make it
        if (-not (Test-Path $destDir)) { mkdir $destDir -whatif }
    }
    
    #==========
    # Main code
    #==========
    if ((Get-Item $xmlSrc).PsIsContainer) {
    
        # You specified a folder
        Get-ChildItem $xmlSrc -Recurse | ForEach { 
            if ($_.PsIsContainer) {
                process-directory $_.FullName
            } else {
                process-file $_.FullName
            }
        }|Out-Null
    
    } else {
    
        # You specified a file
        process-file $xmlSrc
    }
    
    注意。副本是
    -WhatIf
    ,所以它不会做任何激烈的事情。它有两个紧迫的问题:

    • 它使一切都小写。否则必须正确匹配大小写,因为.Replace()区分大小写。
      • 我使用了
        .Replace()
        ,因为
        -Replace
        将文件路径中的
        \
        视为正则表达式的一部分,不起作用。可能有一个转义字符串commandlet来解决这个问题,但我还没有找到
    • 如果您将
      \
      放在$xmlSrc或$xmlDestPath的末尾,它将被覆盖

    是的。删除XML配置并使用。对,我很害怕。看看这个,它会是什么:robocopy C:\powershell\source C:\powershell\test/e/XO出于备份目的,我建议
    /e/zb/copyall/dcopy:t/sl
    。如果不希望遍历连接点,请添加
    /xj