Referencia de contexto de PowerShell del Agente SQL


13

En mi nuevo trabajo, tenemos varias instancias con nombre en cada servidor. p.ej

  • Servidor1 \ Dev
  • Servidor1 \ DevIntegrado
  • Servidor1 \ QA

Tengo un script SQL PowerShell en proceso que llama al sistema operativo, invoca Foo.exepero necesita pasar un parámetro de línea de comando (la cadena de conexión). Existirá un trabajo de Agente SQL en cada instancia, con un paso de tipo PowerShell, que necesita saber cuál es el contexto actual. es decir, esta ejecución comenzó en DevIntegrated.

No deseo que todos los guiones comiencen con ...

$thisInstance = "Dev"

... especialmente porque tendría que editar eso cuando migremos a entornos (nuevos servidores e instancias con nombre) en los próximos meses.

Si inicio SQLPS, puedo determinar mi instancia cortando y cortando los resultados de Get-Location o ejecutando

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

Cuando el Agente SQL inicia un trabajo de tipo PowerShell, comienza en C: \ windows \ system32 y la Get-Locationruta no funciona, ya que no está en el contexto SQLSERVER. Puedo cambiar a ese contexto, pero estaré en la "raíz" de SQL Server y no sabré en qué instancia debería estar. El uso de la Invoke-Sqlcmdruta tampoco funcionará por la misma razón (técnicamente, se agota el tiempo de espera) no es una instancia predeterminada)

Hasta donde sé, he enumerado todas las "cosas" básicas que puedo ingresar en el registro de trabajo, pero nada parece mostrar SQLSERVER:\SQL\Server1\DevIntegrated

Get-ProcessParece que podría usar eso y un poco de vudú de tratar de improvisar cosas golpeando las instancias y combinando spids, pero eso suena como un maldito truco del infierno. Debe haber algo básico que me falta, ¿alguien puede arrojar algo de luz?

Alternativas a PowerShell investigadas

Investigué con otros tipos de trabajo y no obtuve una resolución satisfactoria. La investigación indicó que el PowerShell enumerado en el Agente SQL era SQLPS y al iniciar una instancia de este haciendo clic derecho en el Agente automáticamente me dejó en la ubicación correcta. Fue solo cuando pegué mi código interactivo en el paso del trabajo que me enteré de la diferencia como se mencionó anteriormente.

El tipo de trabajo del sistema operativo me puso en un estado idéntico en el que no pude encontrar una manera de determinar qué instancia me dejó en el shell de comandos. Claro, podría sqlcmd y obtener el valor de, @@servernamepero si supiera qué conexión iniciar sqlcmd, no necesitaría consultar la base de datos;)

TSQL probablemente podría funcionar si lo habilitamos, xp_cmdshellpero no estoy seguro si lo tienen activado --- instalación gubernamental y pueden ser perspicaces en configuraciones no predeterminadas. Incluso entonces, estoy atascado con el SQL dinámico y perdiendo mucha de la expresividad y el poder que presta PowerShell.

Aunque un poco desgarbado, pensé en definir una variable en el primer paso y pasarla a los pasos sucesores, pero la investigación apareció en este artículo Manejo de múltiples pasos de trabajo (BOL)

Los pasos del trabajo deben ser independientes. Es decir, un trabajo no puede pasar valores booleanos, datos o valores numéricos entre los pasos del trabajo. Sin embargo, puede pasar valores de un paso de trabajo de Transact-SQL a otro utilizando tablas permanentes o tablas temporales globales. Puede pasar valores de pasos de trabajo que ejecutan programas ejecutables de un paso de trabajo a otro paso de trabajo mediante el uso de archivos.

No puedo usar trucos comunes como un archivo conocido / variables de entorno / configuración de registro que Foo.exebusca ya que eso evitaría la ejecución concurrente en todas las instancias.

TL; DR:

En un paso de trabajo del Agente SQL de tipo PowerShell, ¿cómo puede determinar la instancia de SQL Server que inició el proceso?


44
¿Powershell es un requisito para lo que estás haciendo?
johndacostaa

El verdadero requisito sería tener un "algo" reuasible en el agente SQL que pueda iniciar un proceso de DOS con un parámetro de la instancia de invocación. PowerShell parecía la mejor opción dado lo que no funcionó anteriormente. Perdón por la respuesta tardía, estaba en el campamento Scout.
billinkc

Respuestas:


9

Si busca en SQL Server BOL, el Agente SQL Server proporciona un conjunto de "tokens" que sustituirá tanto en el texto del comando del paso de trabajo como en el archivo de salida (lo que luego evitará que funcione el botón "ver" de la GUI). Estos tokens parecen funcionar para cualquier tipo de paso, excepto T-SQL.

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

Entonces, si tiene un paso de SQL 2008 PowerShell, puede comenzar con:

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

Es posible que deba usar MACH(nombre de máquina) y INST(solo nombre de instancia) en su lugar, porque con la instancia predeterminada SRVR == MACH, pero con instancias con nombre SRVR == MACH\INST.


3

Es triste decir que no he hecho mucho con los scripts de PowerShell que se llaman dentro de SQL Server. Tampoco estoy en una computadora con la que podría jugar ahora mismo.

Sin embargo, creo que en lugar de usar el paso de tipo PowerShell, si usó CmdExec y solo llama a su script como lo haría desde una línea de comando "powershell 'MyScript.ps1'", podría pasar un parámetro que tenga la instancia desde la que se está ejecutando. Como "Powershell 'MyScript.ps1' MyInstanceName".

Entonces, al comienzo de su script, tiene una configuración param () para aceptar ese valor de MyInstanceName:


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

Cuando comenzaste a decir que el único paso necesario era saber en qué instancia se encontraba para que el script de PowerShell pudiera llamar a Foo.exe correctamente. Sin embargo, más adelante menciona que puede pasar el valor a otros pasos. Si esto es cierto, es posible que desee considerar la creación de un pequeño paquete SSIS que llame a su script de PowerShell y haga todo lo que necesite. Con SSIS, podría configurar una variable global que podría usar todo el paquete.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.