No meu novo trabalho, temos várias instâncias nomeadas em cada servidor. por exemplo
- Server1 \ Dev
- Server1 \ DevIntegrated
- Server1 \ QA
Eu tenho um script SQL PowerShell em andamento que chama o sistema operacional, chama, Foo.exe
mas precisa passar um parâmetro de linha de comando (a cadeia de conexão). Um trabalho do SQL Agent existirá em cada instância, com uma etapa do tipo PowerShell, que precisa saber qual é o contexto atual. ie Esta execução começou no DevIntegrated.
Não desejo que todo script comece com ...
$thisInstance = "Dev"
... especialmente porque eu teria que editar isso quando migrarmos para ambientes (novos servidores e instâncias nomeadas) nos próximos meses.
Se eu iniciar o SQLPS, posso determinar minha instância cortando e cortando os resultados de Get-Location ou executando
(Invoke-Sqlcmd -Query "SELECT @@servername AS ServerName" -SuppressProviderContextWarning).ServerName
Quando o SQL Agent inicia um trabalho do tipo PowerShell, ele é iniciado em C: \ windows \ system32 e a Get-Location
rota não funciona, pois não está no contexto SQLSERVER. Posso mudar para esse contexto, mas estarei na "raiz" do SQL Server e não saberá em que instância devo estar. O uso da Invoke-Sqlcmd
rota também não funcionará pelo mesmo motivo (tecnicamente, o tempo limite é excedido. não é uma instância padrão)
De acordo com o meu conhecimento, enumerei todas as "coisas" básicas que posso acessar no registro de tarefas, mas nada parece mostrar SQLSERVER:\SQL\Server1\DevIntegrated
Get-ChildItem
Get-Host
Get-Location
Get-Process
Get-PSDrive
Get-PSProvider
Get-Service
Get-TraceSource
Get-Variable
Get-Process
Parece que eu poderia usar isso e algum vodu de tentar juntar as coisas, acertando as instâncias e os spids correspondentes, mas isso soa como um maldito hack do inferno. Deve haver algo básico que estou perdendo, alguém pode lançar alguma luz?
Alternativas ao PowerShell investigadas
Eu havia investigado o uso de outros tipos de trabalho e não obtive uma resolução satisfatória. A pesquisa indicou que o PowerShell listado no SQL Agent era SQLPS e iniciar uma instância clicando com o botão direito do mouse no agente me colocou automaticamente no local correto. Foi somente quando colei meu código interativo na etapa do trabalho que descobri a diferença, como mencionado anteriormente.
O tipo de trabalho do sistema operacional me colocou em um estado idêntico, pois não consegui encontrar uma maneira de determinar qual instância me colocou no shell de comando. Claro, eu poderia sqlcmd e obter o valor de, @@servername
mas se soubesse qual conexão iniciar o sqlcmd, não precisaria consultar o banco de dados;)
O TSQL provavelmente funcionaria se ativarmos, xp_cmdshell
mas não tenho certeza se eles estão ativados --- instalação governamental e podem ser persnickety em configurações não padrão. Mesmo assim, estou empolgado com o SQL dinâmico e perdendo muita expressividade e poder que o PowerShell empresta.
Embora tenha sido um pouco desajeitado, pensei em definir uma variável na primeira etapa e passá-la para as etapas seguintes, mas a pesquisa apareceu neste artigo Manipulando várias etapas da tarefa (BOL)
As etapas do trabalho devem ser independentes. Ou seja, um trabalho não pode transmitir valores booleanos, dados ou valores numéricos entre as etapas do trabalho. No entanto, você pode passar valores de uma etapa da tarefa Transact-SQL para outra usando tabelas permanentes ou tabelas temporárias globais. Você pode passar valores de etapas do trabalho que executam programas executáveis de um passo para outro, usando arquivos.
Não posso usar truques comuns, como uma configuração conhecida de arquivo / variáveis de ambiente / registro que Foo.exe
procura, pois isso impediria a execução simultânea entre instâncias.
TL; DR:
Em uma etapa de trabalho do agente SQL do tipo PowerShell, como você pode determinar a instância do SQL Server que iniciou o processo?