如何删除或仅记录 Powershell 中的顶级目录?
How to delete or log only top-level directory in Powershell?
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:\agencydata5233".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-49".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 1055312".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 2016".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes11-03-01 Trustmark medical quote".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes11-03-01 Trustmark medical quote11-03-01 geo access reports".
我想要的示例:
Performing the operation "Remove Directory" on target "H:\agencydata5233".
Performing the operation "Remove Directory" on target "H:\agencydata523323".
Performing the operation "Remove Directory" on target "H:\agencydata523343534".
Performing the operation "Remove Directory" on target "H:\agencydata52331".
Performing the operation "Remove Directory" on target "H:\agencydata523355".
Performing the operation "Remove Directory" on target "H:\agencydata523314".
recurse就是这个意思,重复调用reach对象的命令,否则,为什么要指定它。
如果你只传递父名,没有递归,那么它会删除父级和所有子级。
当你在没有 -Recurse 的情况下执行此操作时...
Remove-Item -Path C:\ParentFolder -Force -WhatIf
...PowerShell 会警告您。
'The item at C:\ParentFolder has children and the Recurse parameter
was not specified. If you continue, all children will be removed with
the item. Are you sure you want to continue'
如果您真的想查看 command/code 的堆栈,请执行以下操作:
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,您无法在任何操作系统上使用任何命令删除 non-empty 文件夹。因此,即使未指定递归,也隐含在破坏性命令中。
如果您只想在日志文件中看到父级,则必须为此编写代码。
更新
至于你的评论
你能指导我如何编辑我的 log-output 以仅显示那些 top-level 文件夹吗?
...你可以这样做。记录读取结果,而不是删除结果。
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-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
#>
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:\agencydata5233".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-49".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 1055312".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 2016".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes11-03-01 Trustmark medical quote".
Performing the operation "Remove Directory" on target "H:\agencydata5233\_Extracted\Broker-7671-02242020080758-4971\Accounts\Professional Contract Services Inc. (PCSI) - 105531204 - 201611\MIP\Quotes\Medical Quotes\Fully Insured Quotes11-03-01 Trustmark medical quote11-03-01 geo access reports".
我想要的示例:
Performing the operation "Remove Directory" on target "H:\agencydata5233".
Performing the operation "Remove Directory" on target "H:\agencydata523323".
Performing the operation "Remove Directory" on target "H:\agencydata523343534".
Performing the operation "Remove Directory" on target "H:\agencydata52331".
Performing the operation "Remove Directory" on target "H:\agencydata523355".
Performing the operation "Remove Directory" on target "H:\agencydata523314".
recurse就是这个意思,重复调用reach对象的命令,否则,为什么要指定它。
如果你只传递父名,没有递归,那么它会删除父级和所有子级。
当你在没有 -Recurse 的情况下执行此操作时...
Remove-Item -Path C:\ParentFolder -Force -WhatIf
...PowerShell 会警告您。
'The item at C:\ParentFolder has children and the Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want to continue'
如果您真的想查看 command/code 的堆栈,请执行以下操作:
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,您无法在任何操作系统上使用任何命令删除 non-empty 文件夹。因此,即使未指定递归,也隐含在破坏性命令中。
如果您只想在日志文件中看到父级,则必须为此编写代码。
更新 至于你的评论
你能指导我如何编辑我的 log-output 以仅显示那些 top-level 文件夹吗?
...你可以这样做。记录读取结果,而不是删除结果。
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-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
#>