Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Tipo de variável inesperado retornado por Receive-Job

  1. Existe uma maneira de obter o tipo de variável correto/esperado a ser retornado ao chamar Receive-Job ?

Devido ao uso de um trabalho em segundo plano, você perde a fidelidade de tipo :os objetos que você está recuperando são emulações sem métodos dos tipos originais.

Recriar manualmente os tipos originais não vale o esforço e pode nem ser possível - embora talvez trabalhar com as emulações seja suficiente.

Atualizar :De acordo com sua própria resposta, alternando do trabalho com System.DataSet para System.DataTable resultou em emulações úteis para você.

Consulte a seção inferior para obter mais informações.
  1. Existe uma maneira melhor de executar consultas SQL em uma conta diferente do AD, usando o comando Invoke-Sqlcmd?

Você precisa de um em processo método de invocação para manter a fidelidade de tipo , mas não acho que isso seja possível com comandos arbitrários se você quiser personificar outro usuário .

Por exemplo, a alternativa em processo (baseada em thread) para Start-Job - Start-ThreadJob - não tem uma -Credential parâmetro.

Sua melhor aposta é, portanto, tentar fazer com que Invoke-SqlCmd 's -Credential funcionem para você ou encontre uma maneira diferente em processo de executar suas consultas com as credenciais de um determinado usuário.

Serialização e desserialização de objetos em trabalhos em segundo plano/remoting/mini-shells:


Sempre que o PowerShell empacota objetos em limites do processo , ele emprega serialização baseada em XML na fonte e desserialização no destino , usando um formato conhecido como CLI XML (XML de infraestrutura de linguagem comum).

Isso acontece no contexto de Remoto do PowerShell (por exemplo, Invoke-Command chamadas com o
-ComputerName parâmetro), bem como em trabalhos em segundo plano (Start-Job ) e os chamados mini-conchas (que são usados ​​implicitamente quando você chama a CLI do PowerShell de dentro do próprio PowerShell com um bloco de script; por exemplo, powershell.exe { Get-Item / } ).

Esta desserialização mantém a fidelidade de tipo apenas para um conjunto limitado de tipos conhecidos , conforme especificado no MS-PSRP, a Especificação do Protocolo Remoto do PowerShell. Ou seja, apenas instâncias de um conjunto fixo de tipos são desserializados como seu tipo original .

As instâncias de todos os outros tipos são emuladas :tipos de lista se tornam [System.Collections.ArrayList] instâncias, os tipos de dicionário se tornam [hasthable] instâncias e outros tipos tornam-se sem método (somente propriedades) objetos personalizados ([pscustomobject] instâncias) , cujo .pstypenames contém o nome do tipo original prefixado com Deserialized. (por exemplo, Deserialized.System.Data.DataTable ), bem como os nomes igualmente prefixados da base do tipo tipos (hierarquia de herança).

Além disso, a profundidade de recursão para gráficos de objeto de não -[pscustomobject] instâncias é limitada a 1 nível - observe que isso inclui instância de classes personalizadas do PowerShell , criado com a class palavra-chave:Ou seja, se os valores de propriedade de um objeto de entrada não são instâncias de tipos conhecidos (o último inclui tipos de valor único, incluindo tipos primitivos .NET como [int] , ao contrário de tipos compostos de várias propriedades), eles são substituídos por seus .ToString() representações (por exemplo, digite System.IO.DirectoryInfo tem um .Parent propriedade que é outro System.IO.DirectoryInfo instância, o que significa que o .Parent valor da propriedade é serializado como .ToString() representação dessa instância, que é sua string de caminho completo); resumindo:objetos não personalizados (escalares) serializam de tal forma que os valores de propriedade que não são instâncias de tipos conhecidos são substituídos por seus .ToString() representação ; veja esta resposta para um exemplo concreto.
Por outro lado, explícito uso de serialização CLI XML via Export-Clixml o padrão é uma profundidade de 2 (você pode especificar uma profundidade personalizada via -Depth e você pode controlar a profundidade da mesma forma se usar o System.Management.Automation.PSSerializer subjacente digite diretamente ).

Dependendo do tipo original, você pode ser capaz de reconstruir instâncias do tipo original manualmente , mas isso não é garantido.(Você pode obter o nome completo do tipo original chamando .pstypenames[0] -replace '^Deserialized\.' em um determinado objeto personalizado.)

Dependendo de suas necessidades de processamento, no entanto, as emulações dos objetos originais pode ser suficiente.