- C'è un modo per ottenere il tipo di variabile corretto/previsto da restituire quando si chiama
Receive-Job
?
A causa dell'utilizzo di un lavoro in background, perdi la fedeltà del testo :gli oggetti che stai recuperando sono emulazione senza metodi dei tipi originali.
Ricreare manualmente i tipi originali non vale lo sforzo e potrebbe non essere nemmeno possibile, anche se forse è sufficiente lavorare con le emulazioni.
Aggiorna :Secondo la tua risposta, passando dal lavorare con System.DataSet
a System.DataTable
ha prodotto emulazioni utili per te.
Per ulteriori informazioni, vedere la sezione inferiore.
- C'è un modo migliore per eseguire query SQL con un account AD diverso, utilizzando il comando Invoke-Sqlcmd?
Hai bisogno di un in corso metodo di chiamata per mantenere la fedeltà del tipo , ma non credo che sia possibile con comandi arbitrari se vuoi impersonare un altro utente .
Ad esempio, l'alternativa in-process (basata su thread) a Start-Job
- Start-ThreadJob
- non ha una -Credential
parametro.
La soluzione migliore è quindi provare a fare Invoke-SqlCmd
-Credential
di parametro funziona per te o trova un modo in-process diverso per eseguire le tue query con le credenziali di un determinato utente.
Serializzazione e deserializzazione di oggetti in lavori in background/remoting/mini-shell:
Ogni volta che PowerShell effettua il marshalling di oggetti attraverso i limiti del processo , utilizza la serializzazione basata su XML alla fonte e deserializzazione a destinazione , utilizzando un formato noto come CLI XML (Common Language Infrastructure XML).
Ciò accade nel contesto di Remote PowerShell (ad esempio, Invoke-Command
chiama con il -ComputerName
parametro) nonché in lavori in background (Start-Job
) e le cosiddette mini-shell (che vengono utilizzati implicitamente quando si chiama l'interfaccia a riga di comando di PowerShell dall'interno di PowerShell stesso con un blocco di script; ad esempio, powershell.exe { Get-Item / }
).
Questa deserializzazione mantiene la fedeltà del tipo solo per un insieme limitato di tipi conosciuti , come specificato in MS-PSRP, la specifica del protocollo di comunicazione remota di PowerShell. In altre parole, solo le istanze di un insieme fisso di tipi vengono deserializzate come tipo originale .
Le istanze di tutti gli altri tipi vengono emulate :i tipi simili a liste diventano [System.Collections.ArrayList]
istanze, i tipi di dizionario diventano [hasthable]
istanze e altri tipi diventano senza metodo (solo proprietà) oggetti personalizzati ([pscustomobject]
istanze) , il cui .pstypenames
contiene il nome del tipo originale preceduto da Deserialized.
(ad esempio, Deserialized.System.Data.DataTable
), nonché i nomi ugualmente prefissi della base del tipo tipi (gerarchia di eredità).
Inoltre, la profondità di ricorsione per grafici oggetto di non -[pscustomobject]
istanze è limitato a 1
livello - nota che questo include l'istanza di classi personalizzate di PowerShell , creato con la class
parola chiave:Cioè, se i valori di proprietà di un oggetto di input non sono istanze di tipi noti stessi (quest'ultimo include tipi a valore singolo, inclusi tipi primitivi .NET come [int]
, a differenza dei tipi composti da più proprietà), sono sostituiti dal loro .ToString()
rappresentazioni (ad esempio, digitare System.IO.DirectoryInfo
ha un .Parent
proprietà che è un altro System.IO.DirectoryInfo
istanza, il che significa che il .Parent
il valore della proprietà viene serializzato come .ToString()
rappresentazione di quell'istanza, che è la sua stringa di percorso completa); in breve:Gli oggetti non personalizzati (scalari) vengono serializzati in modo tale che i valori delle proprietà che non sono essi stessi istanze di tipi noti vengono sostituiti dal loro .ToString()
rappresentanza ; vedere questa risposta per un esempio concreto.
Al contrario, esplicito uso della serializzazione CLI XML tramite Export-Clixml
il valore predefinito è una profondità di 2
(puoi specificare una profondità personalizzata tramite -Depth
e allo stesso modo puoi controllare la profondità se usi il sottostante System.Management.Automation.PSSerializer
digita direttamente ).
A seconda del tipo di originale, puoi essere in grado di ricostruire le istanze del tipo originale manualmente , ma non è garantito.(Puoi ottenere il nome completo del tipo originale chiamando .pstypenames[0] -replace '^Deserialized\.'
su un determinato oggetto personalizzato.)
A seconda delle tue esigenze di elaborazione, tuttavia, le emulazione degli oggetti originali potrebbe essere sufficiente.