我正在尝试编写一个 PowerShell 脚本,该脚本将生成一个包含两列的信息表:名称和日期(将从第三方应用程序中检索 - 在本例中为 svn.exe)。
整个脚本运行良好,但我很难获取服务器发送回数据表的日期。这是我的脚本的简化版本:
# Set up a DataTable and initialise columns
$table = New-Object system.Data.DataTable “Test Table”
$col1 = New-Object system.Data.DataColumn Name,([string])
$col2 = New-Object system.Data.DataColumn DateFromServer,([DateTime])
$table.columns.add($col1)
$table.columns.add($col2)
# Create a new row and add the data
$row = $table.NewRow()
$row.Name = "Test"
$lastCommit = GetDateFromExternalApp
$lastCommit.GetType() # this returns DateTime as I would expect
$row.DateFromServer = $lastCommit # this throws up an error
$table.Rows.Add($row)
# Output the table
$table | Format-Table -AutoSize
# This function simulates what the actual function does
# (the real one goes to SVN and pulls down data, but it
# ends up with the same resulting date)
Function GetDateFromExternalApp
{
$externalAppDate = "2012-09-17T16:33:57.177516Z"
return [DateTime]($externalAppDate)
}
问题(在上面脚本的注释中指出)是,虽然该函数似乎很乐意返回 DateTime 实例,但当我尝试将其添加到表行的 DateFromServer 列中时,它会抛出错误:
Exception setting "DateFromServer": "Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.IConvertible'.Couldn't store <18/09/2012 2:33:57 AM> in DateFromServer Column. Expected type is DateTime." At line:13 char:6
+ $row. <<<< DateFromServer = $lastCommit
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
但是,对 $lastCommit.GetType() 的调用表明这确实是一个 DateTime - 事实上,如果我在脚本中的某个位置添加此行:
$lastCommit
然后我可以看到一个格式良好的日期时间,表明它确实正在解析它并正确转换它:
Date : 18/09/2012 12:00:00 AM
Day : 18
DayOfWeek : Tuesday
DayOfYear : 262
Hour : 2
Kind : Local
Millisecond : 177
Minute : 33
Month : 9
Second : 57
Ticks : 634835324371775160
TimeOfDay : 02:33:57.1775160
Year : 2012
DateTime : Tuesday, 18 September 2012 2:33:57 AM
因此,我很困惑为什么会出现上述异常。我意识到 PowerShell 的函数返回值与 C# 不同,但在我看来,该函数返回了正确的类型!
最佳答案
这里的问题是由于 PowerShell 类型适配系统中的错误造成的(如果您还没有这样做,我建议 reporting this to Microsoft)。
当您在 PowerShell 中使用对象时,您实际上正在使用 PSObject
wrapper 。大多数调用(如 GetType
)都会转发到底层对象,但您可以添加不与对象本身交互的其他成员:
PS> Get-Date | Add-Member NoteProperty Yowza 'for example' -PassThru | Format-List y*
Yowza : for example
Year : 2012
通常这不是问题,因为 PowerShell 具有广泛的类型强制功能。以DataRow
为例但是,用于支持属性访问语法的 DataRowAdapter
类型似乎存在错误。如果您使用the indexer直接使用 $row['DateFromServer'] = $lastCommit
而不是 $row.DateFromServer
,该值在发送到 .NET 类型之前已正确解包。
您还可以通过自己解开该值来解决此问题,可以使用强制转换(如 vonPryz already showed : [DateTime]$lastCommit
),或者通过检索 BaseObject
($lastCommit.PSObject.BaseObject
)。
关于PowerShell 中的日期时间解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12488879/