根据Powershell 3.0中的各种条件移动文件

时间:2013-10-25 15:09:04

标签: date exception powershell recursion powershell-v3.0

我看过https://stackoverflow.com/questions/ask/advicePowershell Move-Item Rename If File Exists http://social.technet.microsoft.com/Forums/scriptcenter/en-US/c347ce7a-3e23-4476-90c2-37b79785ac2f/moving-files-based-on-modified-date Powershell: Move Files recursively http://blogs.technet.com/b/heyscriptingguy/archive/2009/09/22/hey-scripting-guy-september-22-2009.aspx以及大约二十多篇文章。

我很抱歉,虽然我喜欢学习它以及它提供的可能性,但我对脚本知之甚少。除了使用Windows CMD的批处理文件之外,我之前的职位不需要我编写脚本。我最近接受了一个网络管理员职位,我的主管让我写一个脚本,根据几个标准移动文件。我正在使用Powershell来实现这一目标。

  1. 将一天以上的文件移动 - 不复制 - 从$ path移至$ destination
  2. 排除适用于必须保持不变的callpilot.dev
  3. 必须移动位于源文件夹中的文件以及位于所有子文件夹中的文件
  4. 源文件夹结构必须保留在原位
  5. 目标顶部文件夹必须包含实际日期减去1天
  6. 必须使用与源结构相同的名称创建所有子文件夹结构
  7. 应删除剩余的源文件(callpilot.dev除外)
  8. 这是我的测试文件夹结构:

        c:\temp\others\callpilot 
        c:\temp\others\ftps 
        c:\temp\others\mysql 
        c:\temp\others\rss-enterprise 
        c:\temp\others\rss-sql2k8 
        c:\temp\others\tree.txt 
        c:\temp\others\callpilot\example2.gz 
        c:\temp\others\callpilot\backup.gz 
        c:\temp\others\callpilot\barnak.bak 
        c:\temp\others\callpilot\callpilot.dev 
        c:\temp\others\callpilot\IPESystemBackup 131022 2000.bkp 
        c:\temp\others\ftps\www.123.com 
        c:\temp\others\ftps\www.123.com\backup-10.22.2013_00-00-08_123.tar.gz 
        c:\temp\others\ftps\www.123.com\backup-10.23.2013_00-00-08_123.tar.gz 
        c:\temp\others\ftps\www.123.com\backup-10.4.2013_00-00-07_123.tar.gz 
        c:\temp\others\mysql\sql.txt 
        c:\temp\others\rss-enterprise\enterprise.txt 
        c:\temp\others\rss-sql2k8\data 
        c:\temp\others\rss-sql2k8\data\New Bitmap Image.bmp 
        c:\temp\others\rss-sql2k8\data\New Journal Document.jnt 
        c:\temp\others\rss-sql2k8\data\New Microsoft PowerPoint Presentation.pptx 
        c:\temp\others\rss-sql2k8\data\New Microsoft Visio Drawing.vsd
    

    这是我的剧本:

    $date = get-date 
    $path = "C:\temp\others\*.*"
    $destination = new-item "c:\temp\others\$($date.toshortdatestring().replace("/","-"))" -type directory
    Foreach($file in (Get-ChildItem $path -file -recurse -exclude "callpilot.dev")) 
    { 
        If($file.LastWriteTime -gt (Get-Date).adddays(-1).date) 
        { 
            Move-Item -Path $file.fullname -Destination $destination 
        } 
    }
    

    我错过了#6和#7。你能帮我找一下吗?


    我得到了你的回复,谢谢你。有些东西仍然无法正常工作。

    这是我的剧本:

    $date = get-date
    $path = "C:\temp\others\*.*"
    $destination = new-item "c:\temp\others\$($date.toshortdatestring().replace("/","-"))" -type directory
    
    Foreach($file in (Get-ChildItem $path -file -recurse -exclude "callpilot.dev"))
    {
        If($file.LastWriteTime -gt (Get-Date).adddays(-2).date)
    {
            $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root.ToString())
            New-Item $destination -Type Directory -ea SilentlyContinue
            Move-Item $file $destination
        } else {
            Remove-Item $file
    }
    }
    

    文件已移动但未创建任何文件夹。错误是:

    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    
    Move-Item : Cannot create a file when that file already exists.
    At C:\temp\organize_final222.ps1:11 char:9
    +         Move-Item $file $destination
    +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\temp\others\...sio Drawing.vsd:FileInfo) [Move-Item], IOException
    + FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
    
    Method invocation failed because [System.IO.DirectoryInfo] doesn't contain a method named 'op_Addition'.
    At C:\temp\organize_final222.ps1:9 char:9
    +         $destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
    

    我是否在正确的位置插入了线条?

1 个答案:

答案 0 :(得分:0)

您可以使用$file.DirectoryName.TrimStart($file.Directory.Root.ToString())获取没有驱动器名称的源文件夹路径,因此这将处理#6:

$destination += '\' + $file.DirectoryName.TrimStart($file.Directory.Root.ToString())
New-Item $destination -Type Directory -ea SilentlyContinue
Move-Item $file $destination

一些注意事项:

  • 第一行将原始路径(不包括驱动器号)附加到 $ destination
  • 第二行创建目标目录(如果它不存在)。如果目标目录已存在,-ea SilentlyContinue可以防止它抱怨。你可能是肛门并做if (! (Test-Path $destination)) {New-Item ...,但我认为这是浪费时间。
  • 您可以省略参数名称 -Path -Destination ,因为它们隐含在位置(Google“powershell位置参数”以获取更多信息)。< / LI>
  • 您无需阅读 FullName 属性。如果为字符串参数提供非字符串参数,PowerShell会自动在参数上调用 ToString()方法。因此,Move-Item $file $destMove-Item $file.ToString() $dest相同,并且在FileInfo对象上调用 ToString()方法会为您提供 FullName 属性(这是由对象类定义指定)。这看起来似乎是一个小问题,但是一旦你习惯了,你会发现自己做了很多不必要的打字。一般的规则是,如果直觉看起来它应该工作,它可能会(因为,直觉,你应该能够告诉它移动文件对象而不做任何花哨的东西,如指定对象的属性 - - 所以你可以。)

对于#7,只需添加 else 子句即可删除与条件不匹配的源文件:

if ($file.LastWriteTime -gt (Get-Date).AddDays(-1).Date) {
  Move-Item $file "$destination\$($file.DirectoryName.TrimStart($file.Directory.Root.ToString()))"
} else {
  Remove-Item $file
}

为了安全起见,我建议您使用Remove-Item -WhatIf $file进行测试,以确保获得所需的结果。更好的方法是在脚本开头声明[CmdletBinding(SupportsShouldProcess=$true)]并使用 -WhatIf 运行整个脚本,但这可能比您现在想要的更高级。重要的是在让脚本进行大量不可逆转的更改之前始终进行非破坏性测试。