2012-03-09 6 views
5

Prendere la semplice HashTable:Perché sembra che Get-Date restituisca oggetti DateTime, ma il BinarySerializer indica che restituisce un oggetto PSObject?

$data = @{ 
    First = 'Justin'; 
    Last = 'Dearing'; 
    StartDate = Get-Date '2002-03-23'; 
} 

Lo StartDate chiave sembra contenere un DateTime.

C:\Users\zippy\Documents> $data.StartDate.GetType().FullName 
System.DateTime 

Tuttavia, se si tenta di eseguire la serializzazione binario su di esso, ottengo un'eccezione lamentava che PSObject non è serializzabile.

$ms = New-Object System.IO.MemoryStream 
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 
$bf.Serialize($ms, $data) 
$ms.Close() 

Produce:

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 

Questo messaggio va via e tutto funziona se uso un cast esplicito al [DateTime] in questo modo:

$data = @{ 
    First = 'Justin'; 
    Last = 'Dearing'; 
    StartDate = [DateTime] (Get-Date '2002-03-23'); 
} 

Così è Get-Date non proprio restituendo un DateTime o altre stranezze di PowerShell al lavoro qui.

+0

Penso che tutto in PS sia impostato su 'PSObject' a meno che non si definisca esplicitamente il tipo. Effettua conversioni di tipi di dati dinamici, quindi potrebbe semplicemente restituire una stringa che interpreta come 'System.Datetime' in fase di esecuzione. – JNK

+0

@JNK ma perché Object.GetType() interpreta qualcosa come un DateTime che il formattatore binario interpreta come PSObject? –

+0

Questa è solo una supposizione, ma forse perché viene interpretata in fase di esecuzione (dal momento che si esegue il metodo 'GetType()' di un PSObject) - il formattatore binario è una classe di sistema, non una classe PS – JNK

risposta

3

Ogni oggetto in PowerShell viene effettivamente spostato per lo più in modo trasparente in uno psobject. Dico per lo più in modo trasparente perché ci sono più di alcuni bug in PowerShell che omettono di rimuovere il wrapper prima di lasciare l'oggetto in un'altra API. Questo causa tutti i tipi di problemi, proprio come quello che vedi ora. Cerca connect.microsoft.com/powershell per psobject wrapper. Credo che questo non sia più un problema in v3 con il nuovo motore basato su DLR.

+0

Appena acceso VirtualBox e il codice funziona. Grazie per il chiarimento. –

+1

Ecco un altro esempio in cui psobject avvita le cose; http://stackoverflow.com/questions/837095/why-does-powershells-return-keyword-cause-type-errors – x0n

+0

grazie per averlo indicato. Lettura interessante –

5

Base sul MSDN:

PSOobject Classe: incapsula un oggetto di base di tipo Object o digitare PSCustomObject per consentire una visione coerente di qualsiasi oggetto all'interno dell'ambiente 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 
Problemi correlati