【问题标题】:How to delete or log only top-level directory in Powershell?如何在 Powershell 中仅删除或记录顶级目录?
【发布时间】:2020-10-10 07:29:05
【问题描述】:

Powershell 是否必须始终遍历子文件夹并首先删除它们?它不仅可以删除顶级目录,还会删除其中的所有内容吗?我问的原因是我写了一个脚本来删除超过 120 天的文件夹并将这些文件夹输出到日志文件。

   get-childitem -directory h:\agencydata\* |
  where { (get-date) - $_.lastwritetime -gt 120. } |
  remove-item -force -recurse -Verbose 4>&1 | Add-Content H:\logs\$(Get-Date -Format dd-MM-yyyy)-auto_deletes.log

但日志也包含数百个子目录。如果我们不能强制 Powershell 只删除顶级文件夹,那么我们可以强制它在日志中只包含顶级文件夹吗?

我目前通过脚本获得的日志输出示例:

Performing the operation "Remove Directory" on target "H:\agencydata\255233".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP\Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP\Quotes\Medical Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP\Quotes\Medical Quotes\Fully Insured Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP\Quotes\Medical Quotes\Fully Insured Quotes\2011-03-01 Trustmark medical quote".
Performing the operation "Remove Directory" on target "H:\agencydata\255233\_Extracted\Broker-7671-02242020080758-49\7671\Accounts\Professional Contract Services Inc. (PCSI) - 1055312\2004 - 2016\2011\MIP\Quotes\Medical Quotes\Fully Insured Quotes\2011-03-01 Trustmark medical quote\2011-03-01 geo access reports".

我想要的示例:

Performing the operation "Remove Directory" on target "H:\agencydata\255233".
Performing the operation "Remove Directory" on target "H:\agencydata\25523323".
Performing the operation "Remove Directory" on target "H:\agencydata\25523343534".
Performing the operation "Remove Directory" on target "H:\agencydata\2552331".
Performing the operation "Remove Directory" on target "H:\agencydata\25523355".
Performing the operation "Remove Directory" on target "H:\agencydata\25523314".

【问题讨论】:

    标签: powershell scripting


    【解决方案1】:

    递归表示它的作用,重复该命令以达到调用的对象,否则,为什么要指定它。

    如果你只传递父名,没有递归,那么它将删除父级和所有子级。

    当您在没有 -Recurse 的情况下执行此操作时...

    Remove-Item -Path C:\ParentFolder -Force -WhatIf
    

    ...PowerShell 会发出警告。

    'C:\ParentFolder 处的项有子项和 Recurse 参数 未指定。如果你继续,所有的孩子都将被删除 该项目。确定要继续吗?

    如果您真的想查看您的命令/代码堆栈,请执行以下操作:

    Trace-Command

    Trace-Command -Name metadata,parameterbinding,cmdlet -Expression {Remove-Item -Path C:\ParentFolder -Force} -PSHost -Verbose
    # Results
    <#
    DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Remove-Item]
    DEBUG: ParameterBinding Information: 0 :     BIND arg [C:\ParentFolder] to parameter [Path]
    DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String[]]
    DEBUG: ParameterBinding Information: 0 :             Trying to convert argument value from System.String to System.String[]
    DEBUG: ParameterBinding Information: 0 :             ENCODING arg into collection
    DEBUG: ParameterBinding Information: 0 :             Binding collection parameter Path: argument type [String], parameter type [System.String[]], collection type Array, element type [System.String], coerceElementType
    DEBUG: ParameterBinding Information: 0 :             Creating array with element type [System.String] and 1 elements
    DEBUG: ParameterBinding Information: 0 :             Argument type String is not IList, treating this as scalar
    DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.String]
    DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
    DEBUG: ParameterBinding Information: 0 :             Adding scalar element of type String to array position 0
    DEBUG: ParameterBinding Information: 0 :         BIND arg [System.String[]] to param [Path] SUCCESSFUL
    DEBUG: ParameterBinding Information: 0 :     BIND arg [True] to parameter [Force]
    DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Management.Automation.SwitchParameter]
    DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
    DEBUG: ParameterBinding Information: 0 :         BIND arg [True] to param [Force] SUCCESSFUL
    DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Remove-Item]
    DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
    DEBUG: ParameterBinding Information: 0 :     DYNAMIC parameter object: [Microsoft.PowerShell.Commands.FileSystemProviderRemoveItemDynamicParameters]
    DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
    DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
    DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
    #>
    
    
    Trace-Command -Name metadata,parameterbinding,cmdlet -Expression {Remove-Item -Path C:\ParentFolder -Recurse -Force } -PSHost -Verbose
    # Results
    <#
    DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Remove-Item]
    DEBUG: ParameterBinding Information: 0 :     BIND arg [C:\ParentFolder] to parameter [Path]
    DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String[]]
    DEBUG: ParameterBinding Information: 0 :             Trying to convert argument value from System.String to System.String[]
    DEBUG: ParameterBinding Information: 0 :             ENCODING arg into collection
    DEBUG: ParameterBinding Information: 0 :             Binding collection parameter Path: argument type [String], parameter type [System.String[]], collection type Array, element type [System.String], coerceElementType
    DEBUG: ParameterBinding Information: 0 :             Creating array with element type [System.String] and 1 elements
    DEBUG: ParameterBinding Information: 0 :             Argument type String is not IList, treating this as scalar
    DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.String]
    DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
    DEBUG: ParameterBinding Information: 0 :             Adding scalar element of type String to array position 0
    DEBUG: ParameterBinding Information: 0 :         BIND arg [System.String[]] to param [Path] SUCCESSFUL
    DEBUG: ParameterBinding Information: 0 :     BIND arg [True] to parameter [Recurse]
    DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Management.Automation.SwitchParameter]
    DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
    DEBUG: ParameterBinding Information: 0 :         BIND arg [True] to param [Recurse] SUCCESSFUL
    DEBUG: ParameterBinding Information: 0 :     BIND arg [True] to parameter [Force]
    DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Management.Automation.SwitchParameter]
    DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
    DEBUG: ParameterBinding Information: 0 :         BIND arg [True] to param [Force] SUCCESSFUL
    DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Remove-Item]
    DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
    DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
    DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
    DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
    #>
    

    最后,尽管有 PowerShell,但您无法在任何操作系统上使用任何命令删除非空文件夹。因此,递归,即使没有指定,也隐含在破坏性命令中。

    如果您只想查看日志文件中的父项,则必须为此编写代码。

    更新 至于你的评论

    您能否指导我如何编辑日志输出以仅显示那些顶级文件夹?

    ...你可以做这样的事情。记录读取结果,而不是删除结果。

    Get-ChildItem -directory 'C:\ParentFolder*' | 
    ForEach{
        "Performing the operation on target $($PSItem.FullName)" 4>&1 | 
        Add-Content -Path "c:\logs\$(Get-Date -Format dd-MM-yyyy)-auto_deletes.log"
        $null = Remove-Item -Path $PSItem -Force
    }
    Get-Content -Path 'C:\logs\09-10-2020-auto_deletes.log'
    # Results
    <#
    Performing the operation on target C:\ParentFolder
    Performing the operation on target C:\ParentFolder - Copy
    Performing the operation on target C:\ParentFolder - Copy - Copy
    Performing the operation on target C:\ParentFolder - Copy - Copy - Copy
    #>
    

    【讨论】:

    • Python 或 Batch 怎么样?
    • 不。不要紧。这就是操作系统处理文件和文件夹管理的方式。同样,无论您使用什么语言,都无法删除非空文件夹树。这不是缺陷,而是设计使然。所以,递归是必须的。现在,如何生成有关工作量的报告取决于您。然而,接受默认输出/标准输出,你会得到操作系统给你的。
    • 好的,谢谢。您能指导我如何编辑我的日志输出以仅显示那些顶级文件夹吗?
    • 只需将结果捕获到变量中,根据需要进行更改,然后输出到文件或仅将读取输出到 loig 文件,而不是 Remove-Item 结果。请参阅我为您提供的关于后者的更新。
    猜你喜欢
    • 2012-12-18
    • 2010-09-13
    • 2021-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 2010-10-11
    • 2021-04-07
    相关资源
    最近更新 更多