我需要我的脚本在 -Whatif 输出中包含 "LastWriteTime" 属性
I need my script to include the "LastWriteTime" property on the -Whatif output
我需要编辑我在此处找到的脚本,以便我可以首先看到它将删除的文件的报告,包括文件名和路径以及“LastWriteTime”属性,以便我可以分析在执行之前和我将其配置为计划任务之前几个月的脚本输出:
我已经尝试使用 LastWriteTime 对象 属性 一段时间了,但我不知道还能做什么..
代码如下:
$limit = (Get-Date).AddDays(-30)
$del30 = "D:\contoso_ftp\users"
$ignore = Get-Content "C:\Users\username\Documents\Scripts\ignorelist.txt"
Get-ChildItem $del30 -Recurse |
Where-Object {$_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line |
Remove-Item -Recurse -WhatIf
到目前为止,-Whatif 输出是这样的:
假设:在目标“D:\contoso_ftp\users\ftp-contosoaccount\contoso Downloads\contosofile.zip”上执行“删除文件”操作。
所以..如您所见,我需要能够在其中获取“LastWriteTime”属性。
非常感谢任何对文章或文档的帮助或指点。
提前致谢,
//伦纳特
如您所见,-WhatIf
的输出相当简洁 - “Action: Thing” - 仅此而已。
您可以通过将报告和实际删除分开来在脚本中解决此问题:
param(
[string]$Path = "D:\banqsoft_ftp\users",
[datetime]$Limit = $((Get-Date).AddDays(-30)),
[string[]]$ignore = $(Get-Content "$env:USERPROFILE\Documents\Scripts\ignorelist.txt"),
[switch]$Force
)
$targetPaths = Get-ChildItem $del30 -Recurse |
Where-Object {$_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line
# List files that would have been affected + their timestamps
Get-ChildItem $targetPaths -Recurse -File |Select-Object FullName,LastWriteTime
if($Force){
# If -Force was specified then we remove as well
$targetPaths |Remove-Item -Recurse -Force
}
现在您可以运行它为:
PS ~> .\script.ps1
... 只需列出带有 LastWriteTime
的文件,一旦您有信心,运行 带有 -Force
:
PS ~> .\script.ps1 -Force
实际删除文件
作为 Mathias R. Jessen notes, you have no control over the target-object descriptions that cmdlets use with the common -WhatIf
parameter,PowerShell 的 dry-运行 功能。
这是一个 解决方法 ,但请注意,它是 次优 ,主要是因为使用了 ForEach-Object
调用对象执行脚本块会显着减慢命令速度:
'file1.txt', 'file2.txt' | # Stand-in for everything before your Remove-Item call
Get-Item | # transform strings into [System.IO.FileInfo] objects
ForEach-Object {
$whatIf = $true # Set this to $false later to perform actual deletion.
# Prepend the last-write timestamp *without a trailing newline*
if ($whatIf) { Write-Host -NoNewline "$($_.LastWriteTime): " }
# Let Remove-Item append its what-if message
$_ | Remove-Item -WhatIf:$whatif
}
输出将如下所示:
02/07/2021 15:44:24: What if: Performing the operation "Remove File" on target "/Users/jdoe/file1.txt".
02/07/2021 15:44:24: What if: Performing the operation "Remove File" on target "/Users/jdoe/file2.txt".
注:
如果您想从外部您的脚本控制-WhatIf
标志,您有两个选项:
Either:用 [CmdletBinding(SupportsShouldProcess)]
属性修饰脚本的 param(...)
块以打开 -WhatIf
公共参数支持:
警告:这将调用脚本中支持 -WhatIf
的 all cmdlets当您将 -WhatIf
传递给您的脚本时,它 隐含地 ,尽管您可以使用 -WhatIf:$false
选择性地抑制它;请参阅下面的替代方法以了解逆向方法。
由于 PowerShell 自动将此公共参数转换为本地 $WhatIfPreference
preference 变量,因此必须修改上面的代码:
- 使用
if ($WhatIfPreference)
测试-WhatIf
是否通过并且应该产生Write-Host
输出。
- 从
Remove-Item
调用中删除 -WhatIf:$whatIf
- 如果将 -WhatIf
传递给您的脚本,它将自动应用
或者:如果你想要更多的控制,使用自定义[switch] $WhatIf
参数声明代替 SupportsShouldProcess
的 ,并查询 $WhatIf
/ 应用 -WhatIf:$WhatIf
显式和选择性地 .
- 在这种情况下,只需从上面的代码中删除
$whatIf = $true
语句即可。
- 警告:您的脚本将不尊重
$WhatIfPreference
变量,除非您明确检查它以防万一-WhatIf
未明确通过(检查 $PSBoundParameters.ContainsKey('WhatIf')
)。
您可以通过内联 Write-Host
调用获得尽可能详细的信息,但请注意,只有当您前置 Write-Host
输出。
或者,根据对问题的评论调整 Daniel 的方法,您可以调整上面的 if
语句以完全绕过 Remove-Item -WhatIf
调用,如果$whatIf
在脚本块中设置为 $true
,并自己制作完整的假设消息:
if ($whatif) { Write-Host ... } else { $_ | Remove-Item }
请注意,-WhatIf
输出既不能被捕获也不能被抑制 - 它总是直接打印到主机(控制台)。
当 运行 为 -WhatIf
时,您无法修改 Remove-Item
的输出,但您可以将管道包装在支持 -WhatIf
并提供自己的函数中自定义 -WhatIf
输出:
function Test-Something {
[CmdletBinding(SupportsShouldProcess)] # This enables -WhatIf processing
param (
[string] $path,
[datetime] $limit,
[string] $ignore
)
Get-ChildItem $path -Recurse |
Where-Object { $_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line |
Get-ChildItem -Recurse | ForEach-Object {
# If -WhatIf is passed, output the message and skip the deletion.
# Else enter the if-block and delete the file.
if( $PSCmdlet.ShouldProcess(
"Performing the operation `"Remove File`" on target `"$_`" (LastWriteTime: $($_.LastWriteTime))",
"Are you sure you want to delete file `"$_`" ?",
"Confirm" ) ) {
Remove-Item $_
}
}
}
请注意,我不必在函数中定义 -WhatIf
参数,因为它是通过指定 SupportsShouldProcess
自动添加的。现在你可以将 -WhatIf
传递给你的函数来干 运行:
Test-Something $del30 $limit $ignore -WhatIf
示例输出:
What if: Performing the operation "Remove File" on target "C:\test\file1.txt" (LastWriteTime: 12/30/2020 19:47:10)
What if: Performing the operation "Remove File" on target "C:\test\file2.txt" (LastWriteTime: 01/12/2021 00:59:59)
我使用了带有三个参数的 $PSCmdlet.ShouldProcess
overload 来提供详细的 -WhatIf
消息。其他两个参数为相关的 -Confirm
参数提供消息和标题,函数也支持:
Test-Something $del30 $limit $ignore -Confirm
现在 PowerShell 在删除前会询问:
Confirm
Are you sure you want to delete file "C:\test\file1.txt" ?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Yes"):
您免费获得的另一个很酷的功能是详细的输出。当您使用 -Verbose
调用函数时,提供给 $PSCmdlet.ShouldProcess()
的消息将用作详细输出:
Test-Something $del30 $limit $ignore -Verbose
输出:
VERBOSE: Performing the operation "Remove File" on target "C:\test\file1.txt" (LastWriteTime: 12/30/2020 19:47:10)
VERBOSE: Performing the operation "Remove File" on target "C:\test\file2.txt" (LastWriteTime: 01/12/2021 00:59:59)
我需要编辑我在此处找到的脚本,以便我可以首先看到它将删除的文件的报告,包括文件名和路径以及“LastWriteTime”属性,以便我可以分析在执行之前和我将其配置为计划任务之前几个月的脚本输出:
我已经尝试使用 LastWriteTime 对象 属性 一段时间了,但我不知道还能做什么..
代码如下:
$limit = (Get-Date).AddDays(-30)
$del30 = "D:\contoso_ftp\users"
$ignore = Get-Content "C:\Users\username\Documents\Scripts\ignorelist.txt"
Get-ChildItem $del30 -Recurse |
Where-Object {$_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line |
Remove-Item -Recurse -WhatIf
到目前为止,-Whatif 输出是这样的:
假设:在目标“D:\contoso_ftp\users\ftp-contosoaccount\contoso Downloads\contosofile.zip”上执行“删除文件”操作。
所以..如您所见,我需要能够在其中获取“LastWriteTime”属性。
非常感谢任何对文章或文档的帮助或指点。
提前致谢,
//伦纳特
如您所见,-WhatIf
的输出相当简洁 - “Action: Thing” - 仅此而已。
您可以通过将报告和实际删除分开来在脚本中解决此问题:
param(
[string]$Path = "D:\banqsoft_ftp\users",
[datetime]$Limit = $((Get-Date).AddDays(-30)),
[string[]]$ignore = $(Get-Content "$env:USERPROFILE\Documents\Scripts\ignorelist.txt"),
[switch]$Force
)
$targetPaths = Get-ChildItem $del30 -Recurse |
Where-Object {$_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line
# List files that would have been affected + their timestamps
Get-ChildItem $targetPaths -Recurse -File |Select-Object FullName,LastWriteTime
if($Force){
# If -Force was specified then we remove as well
$targetPaths |Remove-Item -Recurse -Force
}
现在您可以运行它为:
PS ~> .\script.ps1
... 只需列出带有 LastWriteTime
的文件,一旦您有信心,运行 带有 -Force
:
PS ~> .\script.ps1 -Force
实际删除文件
作为 Mathias R. Jessen notes, you have no control over the target-object descriptions that cmdlets use with the common -WhatIf
parameter,PowerShell 的 dry-运行 功能。
这是一个 解决方法 ,但请注意,它是 次优 ,主要是因为使用了 ForEach-Object
调用对象执行脚本块会显着减慢命令速度:
'file1.txt', 'file2.txt' | # Stand-in for everything before your Remove-Item call
Get-Item | # transform strings into [System.IO.FileInfo] objects
ForEach-Object {
$whatIf = $true # Set this to $false later to perform actual deletion.
# Prepend the last-write timestamp *without a trailing newline*
if ($whatIf) { Write-Host -NoNewline "$($_.LastWriteTime): " }
# Let Remove-Item append its what-if message
$_ | Remove-Item -WhatIf:$whatif
}
输出将如下所示:
02/07/2021 15:44:24: What if: Performing the operation "Remove File" on target "/Users/jdoe/file1.txt".
02/07/2021 15:44:24: What if: Performing the operation "Remove File" on target "/Users/jdoe/file2.txt".
注:
如果您想从外部您的脚本控制
-WhatIf
标志,您有两个选项:Either:用
[CmdletBinding(SupportsShouldProcess)]
属性修饰脚本的param(...)
块以打开-WhatIf
公共参数支持:警告:这将调用脚本中支持
-WhatIf
的 all cmdlets当您将-WhatIf
传递给您的脚本时,它 隐含地 ,尽管您可以使用-WhatIf:$false
选择性地抑制它;请参阅下面的替代方法以了解逆向方法。由于 PowerShell 自动将此公共参数转换为本地
$WhatIfPreference
preference 变量,因此必须修改上面的代码:- 使用
if ($WhatIfPreference)
测试-WhatIf
是否通过并且应该产生Write-Host
输出。 - 从
Remove-Item
调用中删除-WhatIf:$whatIf
- 如果将-WhatIf
传递给您的脚本,它将自动应用
- 使用
或者:如果你想要更多的控制,使用自定义
[switch] $WhatIf
参数声明代替SupportsShouldProcess
的 ,并查询$WhatIf
/ 应用-WhatIf:$WhatIf
显式和选择性地 .- 在这种情况下,只需从上面的代码中删除
$whatIf = $true
语句即可。 - 警告:您的脚本将不尊重
$WhatIfPreference
变量,除非您明确检查它以防万一-WhatIf
未明确通过(检查$PSBoundParameters.ContainsKey('WhatIf')
)。
- 在这种情况下,只需从上面的代码中删除
您可以通过内联
Write-Host
调用获得尽可能详细的信息,但请注意,只有当您前置Write-Host
输出。或者,根据对问题的评论调整 Daniel 的方法,您可以调整上面的
if
语句以完全绕过Remove-Item -WhatIf
调用,如果$whatIf
在脚本块中设置为$true
,并自己制作完整的假设消息:if ($whatif) { Write-Host ... } else { $_ | Remove-Item }
请注意,
-WhatIf
输出既不能被捕获也不能被抑制 - 它总是直接打印到主机(控制台)。
当 运行 为 -WhatIf
时,您无法修改 Remove-Item
的输出,但您可以将管道包装在支持 -WhatIf
并提供自己的函数中自定义 -WhatIf
输出:
function Test-Something {
[CmdletBinding(SupportsShouldProcess)] # This enables -WhatIf processing
param (
[string] $path,
[datetime] $limit,
[string] $ignore
)
Get-ChildItem $path -Recurse |
Where-Object { $_.LastWriteTime -lt $limit } |
Select-Object -ExpandProperty FullName |
Select-String -SimpleMatch -Pattern $ignore -NotMatch |
Select-Object -ExpandProperty Line |
Get-ChildItem -Recurse | ForEach-Object {
# If -WhatIf is passed, output the message and skip the deletion.
# Else enter the if-block and delete the file.
if( $PSCmdlet.ShouldProcess(
"Performing the operation `"Remove File`" on target `"$_`" (LastWriteTime: $($_.LastWriteTime))",
"Are you sure you want to delete file `"$_`" ?",
"Confirm" ) ) {
Remove-Item $_
}
}
}
请注意,我不必在函数中定义 -WhatIf
参数,因为它是通过指定 SupportsShouldProcess
自动添加的。现在你可以将 -WhatIf
传递给你的函数来干 运行:
Test-Something $del30 $limit $ignore -WhatIf
示例输出:
What if: Performing the operation "Remove File" on target "C:\test\file1.txt" (LastWriteTime: 12/30/2020 19:47:10)
What if: Performing the operation "Remove File" on target "C:\test\file2.txt" (LastWriteTime: 01/12/2021 00:59:59)
我使用了带有三个参数的 $PSCmdlet.ShouldProcess
overload 来提供详细的 -WhatIf
消息。其他两个参数为相关的 -Confirm
参数提供消息和标题,函数也支持:
Test-Something $del30 $limit $ignore -Confirm
现在 PowerShell 在删除前会询问:
Confirm
Are you sure you want to delete file "C:\test\file1.txt" ?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Yes"):
您免费获得的另一个很酷的功能是详细的输出。当您使用 -Verbose
调用函数时,提供给 $PSCmdlet.ShouldProcess()
的消息将用作详细输出:
Test-Something $del30 $limit $ignore -Verbose
输出:
VERBOSE: Performing the operation "Remove File" on target "C:\test\file1.txt" (LastWriteTime: 12/30/2020 19:47:10)
VERBOSE: Performing the operation "Remove File" on target "C:\test\file2.txt" (LastWriteTime: 01/12/2021 00:59:59)