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

时间:2019-04-07 13:59:13

标签: powershell

我是Powershell的新手,仅使用过字符串类型的脚本参数。现在,我尝试创建一个脚本,该脚本删除比给定时间跨度更早的备份,类似于以下内容:

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}

有没有一种方法可以使调用方从PS命令行传递时间跨度参数,例如“ New-TimeSpan -Days 7”? 我做了一个变通方法,其中仅将天作为参数传递,但我不喜欢此限制,而是希望将整个时间范围作为单个参数传递,可能包括天,分钟,小时等。

我的脚本中还有两个我不理解的小问题。也许您也可以回答这些问题,以帮助我提高对Powershell的了解:

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

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

1 个答案:

答案 0 :(得分:4)

  • 要将[timespan]值作为自变量传递-或者实际上是 any 表达式-将其包含在(...)中。 br /> 有关PowerShell如何解析命令参数的信息,请参见this answer

    # Pass a [timespan] to cmdlet Get-Foo
    Get-Foo (New-TimeSpan -Days 7)
    
  • -d不被接受为-Directory的别名是 bug

    • -d被错误地解释为-Depth参数的前缀形式,即使-d被显式声明为-Directory的别名({{1}也是这样) })。
    • 正确的做法是使参数别名始终按原样接受 -即使它们的名称恰好是不同参数的前缀(例如如-ad)。

      • 顺便说一句:如果没有-Depth别名 ,PowerShell通常会明智地报告一个-d错误,因为指定的名称前缀不够长,无法唯一标识目标参数。 [1]
    • 请参见this GitHub issue

  • parameter name 'd' is ambiguous是一个 switch 参数,该参数通常不使用 argument :(( [2]除外))决定其值的是交换机的不存在或存在

    • 因为switch参数不带参数,所以紧随其后的任何标记都被视为 next 参数。
    • 因此,必须在开关名称后使用-Confirm来告知PowerShell以下令牌是 switch 的参数。
      • 顺便说一句::语法甚至适用于非开关参数,即始终需要参数的参数,但在这种情况下很少使用。

[1] PowerShell通常允许您仅使用参数名称的前缀,只要该前缀在给定命令支持的所有参数中都是唯一的即可。 PowerShell称为 弹性语法 的就是采用这种快捷方式的功能,并且旨在用于 interactive (在命令行)。您应该避免使用 scripts 中的弹性语法,因为如果命令引入了一个使先前唯一的 new 参数,此类脚本将来可能会中断。名称前缀不再唯一。

[2]您的用例:显示了一个这样的异常:它表示不要求确认的明确意图,这与不相同。省略-Confirm:$false开关:前者无条件退出提示,而后者使行为取决于目标命令的声明影响级别和{{ 1}}首选项变量。