我制作了一个备份脚本:
这仅适用于源文件,如果在XML文件中指定了源文件夹,则只复制该文件夹,而不复制其内容。
我不想使用Copy-Item -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.
即。我想在复制它之前检查每个文件,但是如果说文件夹没有被修改但是文件里面的文件应该被复制它仍然可以工作,并保留相同的文件夹结构。
有什么想法吗? :)
答案 0 :(得分:2)
正如Ansgar Wiechers所说,你正在重新发明轮子,RoboCopy将更容易做到这一点。 RoboCopy也可以复制安全权限和创建/修改日期,这很棒。相关的RoboCopy讨论:https://superuser.com/a/445137/67909
尽管如此,它并不像自己写的那么有趣,是吗?我想出了这个:
# 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
}
NB。副本是-WhatIf
所以它不会做任何激烈的事情。它有两个直接的问题:
.Replace()
因为-replace
将文件路径中的\
视为正则表达式的一部分而不起作用。可能有一个转义字符串命令行程序来解决这个问题,但我没有找到它。\
放在$ xmlSrc或$ xmlDestPath的末尾,它将会崩溃。