Riferimento al contesto PowerShell di SQL Agent


13

Nel mio nuovo lavoro, abbiamo più istanze denominate su ciascun server. per esempio

  • Server1 \ Dev
  • Server1 \ DevIntegrated
  • Server1 \ QA

Ho uno script SQL PowerShell nelle opere che chiama il sistema operativo, invoca Foo.exema deve passare un parametro della riga di comando (la stringa di connessione). Esisterà un processo di SQL Agent su ogni istanza, con un passaggio di tipo PowerShell, che deve sapere qual è il contesto corrente. cioè questa esecuzione è iniziata su DevIntegrated.

Non desidero che ogni sceneggiatura inizi con ...

$thisInstance = "Dev"

... soprattutto perché dovrei modificarlo quando migreremo negli ambienti (nuovi server e istanze denominate) nei prossimi mesi.

Se avvio SQLPS, posso determinare la mia istanza tagliando e tagliando i risultati di Get-Location o eseguendoli

(Invoke-Sqlcmd -Query "SELECT @@servername AS ServerName" -SuppressProviderContextWarning).ServerName

Quando SQL Agent avvia un lavoro di tipo PowerShell, si avvia in C: \ windows \ system32 e il Get-Locationpercorso non funziona poiché non si trova nel contesto SQLSERVER. Posso cambiare in quel contesto, ma sarò alla "radice" di SQL Server e non saprò in quale istanza dovrei trovarmi. L'uso del Invoke-Sqlcmdpercorso non funzionerà neanche per lo stesso motivo (tecnicamente, va in timeout in quanto lì non è un'istanza predefinita)

Per quanto ne so, ho elencato tutte le "cose" di base che posso inserire nel registro dei lavori, ma nulla sembra mostrare SQLSERVER:\SQL\Server1\DevIntegrated

Get-Processsembra che potrei usarlo e un po 'di voodoo nel cercare di mettere insieme le cose colpendo le istanze e abbinando gli spid, ma sembra proprio un maledetto hack dall'inferno. Ci deve essere qualcosa di fondamentale che mi manca, qualcuno può far luce?

Sono state studiate alternative a PowerShell

Avevo studiato utilizzando altri tipi di lavoro e non avevo ottenuto una risoluzione soddisfacente. La ricerca ha indicato che PowerShell elencato in SQL Agent era SQLPS e l'avvio di un'istanza di esso facendo clic con il pulsante destro del mouse sull'agente mi ha automaticamente portato nella posizione corretta. È stato solo quando ho incollato il mio codice interattivo nella fase di lavoro che ho appreso della differenza come precedentemente menzionato.

Il tipo di lavoro del sistema operativo mi ha messo in uno stato identico in quanto non sono riuscito a trovare un modo per determinare quale istanza mi ha lasciato cadere nella shell dei comandi. Certo, potrei sqlcmd e ottenere il valore di @@servernamema se sapessi quale connessione avviare sqlcmd, non avrei bisogno di interrogare il database;)

TSQL potrebbe probabilmente funzionare se lo abilitiamo, xp_cmdshellma non sono sicuro che abbiano attivato la funzione del governo e possono essere persnickety su impostazioni non predefinite. Anche allora, sono bloccato a vuoto con SQL dinamico e sto perdendo molta espressività e potenza che PowerShell presta.

Mentre un po 'sgraziato, ho pensato di definire una variabile nel primo passaggio e passarla ai passaggi successivi, ma la ricerca ha rivelato questo articolo Gestione di più fasi di lavoro (BOL)

Le fasi del lavoro devono essere autosufficienti. Cioè, un lavoro non può passare valori booleani, dati o valori numerici tra i passaggi del lavoro. Tuttavia, è possibile passare valori da un passaggio del processo Transact-SQL a un altro utilizzando tabelle permanenti o tabelle temporanee globali. È possibile passare valori da passaggi di lavoro che eseguono programmi eseguibili da un passaggio di lavoro a un altro passaggio di lavoro utilizzando i file.

Non posso usare trucchi comuni come una nota impostazione di file / variabili di ambiente / registro che Foo.execerca poiché ciò impedirebbe l'esecuzione simultanea tra istanze.

TL; DR:

In una fase del processo dell'agente SQL di tipo PowerShell, come è possibile determinare l'istanza di SQL Server che ha avviato il processo?


4
Powershell è un requisito per quello che stai facendo?
johndacostaa,

Il vero requisito sarebbe di avere un "qualcosa" riutilizzabile nell'agente SQL in grado di avviare un processo DOS con un parametro dell'istanza invocante. PowerShell sembrava la soluzione migliore dato ciò che non funzionava sopra. Scusate la risposta tardiva, ero fuori al campo scout.
billinkc

Risposte:


9

Se si guarda in SQL Server BOL, SQL Server Agent fornisce una serie di "token" che sostituiranno sia il testo del comando del passaggio del processo che il file di output (il successivo impedirà il funzionamento del pulsante "Visualizza" della GUI). Questi token sembrano funzionare per qualsiasi tipo di passaggio tranne T-SQL.

https://docs.microsoft.com/en-us/sql/ssms/agent/use-tokens-in-job-steps#sql-server-agent-tokens

Quindi, se si dispone di un passaggio di PowerShell per SQL 2008, è possibile avviarlo con:

$sqlInstance = "$(ESCAPE_DQUOTE(SRVR))"

Potrebbe essere necessario utilizzare invece MACH(nome macchina) e INST(solo nome istanza), perché con l'istanza predefinita SRVR == MACH, ma con istanze denominate SRVR == MACH\INST.


3

Triste a dirsi, non ho fatto molto con gli script di PowerShell chiamati all'interno di SQL Server. Né sono al computer con cui potrei giocarci adesso.

Credo che invece di usare il passaggio di tipo PowerShell che se hai usato CmdExec e hai semplicemente chiamato il tuo script come da una riga di comando "PowerShell" MyScript.ps1 ", potresti quindi passare un parametro con l'istanza da cui stai eseguendo. Come "Powershell" MyScript.ps1 "MyInstanceName".

Quindi all'inizio del tuo script hai un'impostazione param () per accettare quel valore di MyInstanceName:


param(
   [Parameter(Position=0,Mandatory=$True)]
   [string]$InstanceName
)
#so if I wanted to use sqlcmd
sqlcmd -S $InstanceName -Q "SELECT @@VERSION"

Quando hai iniziato affermando il passaggio necessario per sapere su quale istanza si trovava, in modo che lo script PowerShell potesse chiamare correttamente Foo.exe. Tuttavia, in seguito accenni di essere in grado di passare il valore ad altri passaggi. Se questo è vero, potresti voler esaminare la creazione di un piccolo pacchetto SSIS che chiama lo script di PowerShell e fa tutto il necessario. Con SSIS potresti essere in grado di impostare una variabile globale che l'intero pacchetto potrebbe usare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.