如何将 TimeSpan 参数传递给脚本?

Abr*_* 66 3 powershell

我是 powershell 的新手,还只使用过 string 类型的脚本参数。现在我尝试创建一个脚本来删除早于给定时间跨度的备份,类似于这个:

Param(
    [parameter(Mandatory=$true)]
    [string] $BackupFolder,
    [parameter(Mandatory=$true)]
    [Timespan] $StorageDuration
)
$BackupFolder | ls -ad |? { (New-TimeSpan -Start $_.CreationTime -End Get-Date) -ge $StorageDuration} |% {$_|rm -Confirm:$false -Recurse}
Run Code Online (Sandbox Code Playgroud)

有没有办法让来自 PS 命令行的调用者传递一个时间跨度参数,例如 'New-TimeSpan -Days 7' ?我做了一个解决方法,其中仅将天数作为参数传递,但我不喜欢此限制,并且更愿意将整个时间跨度作为单个参数传递,可能包括天数、分钟数、小时数等。

我的脚本中还有两个我不明白的小问题。也许你也可以回答这些来帮助我提高我的 powershell 知识:

  1. MSDN说 d 和 ad 是 Directory 参数的别名。但是当我使用 d 而不是 ad 时,我收到一条错误消息,指出没有指定参数深度的参数。他们在那里混合了一些东西吗?

  2. 为什么我必须在 -Confirm 和 $false 之间写一个冒号?当我省略它时,它告诉我没有位置参数采用值 false。

mkl*_*nt0 5

  • 要将[timespan]值作为参数传递- 或者实际上是任何表达式 - 将其包含在(...).
    请参阅此答案以了解 PowerShell 如何解析命令参数。

    # Pass a [timespan] to cmdlet Get-Foo
    Get-Foo (New-TimeSpan -Days 7)
    
    Run Code Online (Sandbox Code Playgroud)
  • -d不被接受为别名-Directory是一个错误

    • -d被错误地解释为-Depth参数的前缀形式,即使-d显式声明为-Directory(as is -ad)的别名。
    • 正确的行为是始终按原样接受参数别名- 即使它们的名称恰好是不同参数的前缀(例如-Depth在这种情况下)。

      • 顺便说一句:如果-d别名存在,PowerShell 通常会明智地报告parameter name 'd' is ambiguous错误,因为指定的名称前缀不够长,无法唯一标识目标参数。[1]
    • 请参阅此 GitHub 问题

  • -Confirm是一个switch参数,它通常不带参数:(除了[2])它是一个 switch 的缺失或存在决定了它的值。

    • 因为 switch 参数不带参数,所以跟在它们后面的任何标记都被认为是下一个参数。
    • 因此,您必须:在 switch 名称之后使用来告诉 PowerShell 下面的标记是switch的参数。
      • 顺便说一句:该:语法甚至适用于非开关参数,即那些总是需要参数的参数,但在这种情况下很少使用。

[1] PowerShell 通常只允许您使用参数名称的前缀,只要该前缀在给定命令支持的所有参数中是唯一的。采用这种快捷方式的能力是 PowerShell 所谓的弹性语法,它旨在用于交互使用(在命令行上)。你应该避免在脚本中使用弹性语法,因为如果一个命令引入了一个参数,使得以前唯一的名称前缀不再唯一,这样的脚本将来可能会中断。

[2]您的使用情况中,-Confirm:$false示出了一个这样的例外:它标志着明确意图不要求确认,这是一样省略-Confirm开关:前者无条件选择退出提示的,而后者品牌取决于行为目标命令声明的影响级别和$ConfirmPreference偏好变量的当前值。