Por que Get-Date parece retornar objetos DateTime, mas o BinarySerializer indica que retorna um PSObject?
-
10-12-2019 - |
Pergunta
Pegue o simples Tabela Hash:
$data = @{
First = 'Justin';
Last = 'Dearing';
StartDate = Get-Date '2002-03-23';
}
A chave StartDate parece conter um Data hora.
C:\Users\zippy\Documents> $data.StartDate.GetType().FullName
System.DateTime
No entanto, se eu tentar realizar a serialização binária nele, recebo uma exceção reclamando que PSObject não é serializável.
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $data)
$ms.Close()
Lança:
DocumentsException calling "Serialize" with "2" argument(s): "Type 'System.Management.Automation.PSObject' in Assembly 'System.Management.Automation, Versio
n=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable."
At C:\Users\jdearing\AppData\Local\Temp\b8967f99-0a24-41f7-9c97-dad2bc288bd9.ps1:12 char:14
+ $bf.Serialize <<<< ($ms, $data)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Esta mensagem desaparece e tudo funciona se eu usar uma conversão explícita para [DateTime] assim:
$data = @{
First = 'Justin';
Last = 'Dearing';
StartDate = [DateTime] (Get-Date '2002-03-23');
}
Então Get-Date não está realmente retornando um DateTime ou há alguma outra estranheza do PowerShell em ação aqui.
Solução
Cada objeto no PowerShell é, na verdade, agrupado de forma transparente em um psobject.Digo principalmente de forma transparente porque existem mais do que alguns bugs no PowerShell que omitem a remoção do wrapper antes de vazar o objeto para outra API.Isso causa todos os tipos de problemas, muito parecidos com o que você vê agora.Pesquise em connect.microsoft.com/powershell o wrapper psobject.Acredito que isso não seja mais um problema na v3 com o novo mecanismo baseado em DLR.
Outras dicas
Baseie-se no msdn:
Classe de objeto PSO:Encapsula um objeto base do tipo Object ou do tipo PSCustomObject para permitir uma exibição consistente de qualquer objeto no ambiente do Windows PowerShell.
( get-Date '2002-03-23' ) -IS [psobject]
True
( get-Date '2002-03-23' ) -IS [datetime]
True
[datetime]( get-Date '2002-03-23' ) -IS [datetime]
True
[datetime]( get-Date '2002-03-23' ) -IS [psobject]
False