Powershell 复制子文件夹和文件,选中“复制”;“上次修改时间”;
我制作了一个备份脚本:Powershell 复制子文件夹和文件,选中“复制”;“上次修改时间”;,powershell,backup,Powershell,Backup,我制作了一个备份脚本: 从XML文件读取源文件路径和目标文件夹路径 检查源文件和目标路径是否存在(对于每个文件) 检查目标文件夹中是否存在源文件(同名) 检查每个源文件和目标文件(如果该文件存在于目标文件夹中)的上次修改日期 如果源文件不存在,或者源文件比目标文件夹中的现有文件新,则将源文件复制到目标文件夹,否则不执行任何操作 这仅适用于源文件,如果在XML文件中指定了源文件夹,则只复制该文件夹,而不复制其任何内容 我不想使用copyitem-Recurse,因为我想检查每个项目的最后修改日期,
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的末尾,它将被覆盖\
/e/zb/copyall/dcopy:t/sl
。如果不希望遍历连接点,请添加/xj
。