开发者问题收集

在 powershell 中传递空日期时间参数

2019-10-16
8421

因此,我有一个 powershell 脚本,该脚本将区域和日期时间作为输入,并在脚本内部调用存储过程。

存储过程需要两个输入 - 区域和日期时间戳;日期时间戳始终为空。我该如何解析它?

function Reset {

param ([string]$region,[nullable[Datetime]]$statustimestamp)

        $conn = New-Object System.Data.SqlClient.SqlConnection("Server=SQL,15010; Database='STG';User ID=SVC;Password=password;Integrated Security=FALSE")
        $conn.Open()
        $cmd = $conn.CreateCommand()
        $cmd.CommandText = "dbo.Reset'$region' ,'$statustimestamp'"
        $adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd)
        $dataset = New-Object System.Data.DataSet
        [void]$adapter.Fill($dataset)
        $dataset.tables[0]
        $cmd.CommandText    
        $dataset.Tables[0] | Export-CSV M:\MyReport.csv -encoding UTF8 -NoTypeInformation    
        Write-Host 'New report M:\MyReport.csv has been successfully generated' 
    }

我将其执行为

Rest -region IN -statustimestamp NULL

并收到以下错误

Reset : Cannot process argument transformation on parameter 'statustimestamp'. Cannot convert value "NULL" to type "System.DateTime".
Error: The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.
At line:1 char:59
+ Reset -region AU -statustimestamp NULL
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Reset], ParameterBindingArgumentTransformationException
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,Reset

2个回答

补充 dee-see 的有用答案

注意:无论您的参数是如何声明的,脚本/函数内的 $PSBoundParameters.ContainsKey('<parameter-name>') 都会告诉您参数是否 显式传递 给给定参数( 默认值 不算);例如,对于您问题中的调用(如果成功), $PSBoundParameters.ContainsKey('statustimestamp') 将指示 $true

如果您希望参数值为 $null 省略

将您的参数简单地声明为 [Datetime] $statustimestamp 并且在调用时 不向其传递任何参数 $statustimestamp 隐式 $null

# Declare a parameter in a script block (which works like a function)
# and invoke the script block without an argument for that parameter:
PS> & { param([Datetime] $statustimestamp) $null -eq $statustimestamp }

True  # $statustimestamp was $null

如果您想要支持 显式传递 $null 作为参数:

如果您声明一个 强制 参数,但又想要允许 $null 作为应使用默认值的明确信号,那么这可能是必要的。

不幸的是, 参数声明的具体细节目前取决于参数的数据类型是 引用类型 (例如 [string][System.IO.FileInfo] )还是 值类型 (例如 [int][datetime] )
您可以检查给定类型的 .IsValueType 属性,以了解它是值类型 ( $true) 还是引用类型 ( $false );例如: [datetime].IsValueType 得出 $true )。

如果 参数类型是 引用类型 ,则可以使用 [AllowNull()] 属性:

PS> & { 
  param(
    [AllowNull()]
    [Parameter(Mandatory)]
    [System.IO.FileInfo] $Foo  # System.IO.FileInfo is a *reference type*
  )
  $null -eq $Foo 
} -Foo $null

True  # $Foo was $null

不幸的是, 同样的技术不适用于 值类型 ,例如 [DateTime] ,因此您的 参数确实必须输入为 [Nullable[DateTime] ,就像您的问题中那样:

PS> & { 
  param(
    [Parameter(Mandatory)]
    [AllowNull()] # Because the parameter is mandatory, this is *also* needed.
    [Nullable[DateTime]] $Foo  # System.DateTime is a *value type*
  )
  $null -eq $Foo 
} -Foo $null

True  # $Foo was $null

注意:这些要求 - 需要注意值类型和引用类型之间的区别,并且需要使用 [Nullable[T]] 类型 - 对于PowerShell。

取消这些要求 ,转而采用统一的方法(使其适用于值类型,就像它已经适用于引用类型一样) GitHub 上的此提案 的主题。

mklement0
2019-10-17

PowerShell 中的 Null 由 $null 表示,而不是 NULL ,这就是为什么错误消息说字符串 NULL 无法转换为(可空) DateTime

Rest -region IN -statustimestamp $null

您也可以完全省略 -statustimestamp 参数。

dee-see
2019-10-16