Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Tipo di variabile imprevisto restituito da Receive-Job

  1. 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.

  1. 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.