Using External Programs with SQL Server Agent


The Job Activity Monitor

The Job Activity Monitor is a great tool to use for real time monitoring and administration of your SQL Server agent jobs. For Level 8 in this stairway, you are going to look back into another capability of SQL Server Agent – the ability to shell out to the operating system and run programs outside of the SQL Server environment. Some of those programs will be command line (either traditional cmd applications/scripts or PowerShell scripts), or even ActiveX scripts, but you can actually shell out and run nearly any program, as long as the program doesn’t expect direct user input. You will look at how to runcmdexec and PowerShell scripts, and we will have a brief discussion of when each subsystem would be appropriate. You will learn how to call other programs from SQL Server Agent.

Built-in Job Subsystems

There are several built-in job subsystems, as you have seen in previous articles. In this article, you will examine three of the built-in job subsystems that are capable of running scripts and/or programs within the scope of Windows Server, rather than within the context of the SQL Server environment itself. These three subsystems include:
  • Operating System (CmdExec)
  • PowerShell
  • ActiveX Script
When a program or script is launched from one of these three subsystems, a separate process is created within Windows (i.e. not directly part of SQL Server Agent), the script or program is run, and then information is passed back to the SQL Server Agent job that started the process or script.

The Operating System (CmdExec) subsystem

The first subsystem we’ll review is the Operating System (CmdExec) subsystem. The CmdExec subsystem opens up a command prompt, as if you had logged into the Windows Server machine running SQL Server. From that point you can run anything you could otherwise type yourself in a command prompt window. This includes any batch file, script, or even program that exists on your server, and of course if you could type in a UNC path and access a file, so could the CmdExec subsystem.

But what about security?

Of course, the big caveat about all of this is permissions – what will work, and under what security context? By default, when you create a job in the CmdExec subsystem (or the others, as you will see), the job will run in the security context of the SQL Server Agent Service Account (as shown in Figure 1). You may also notice that this is a drop-down form value, so other options are possible. You will examine these proxy accounts in level 10 in the Stairway. Another important note: you must be asysadmin login role member in SQL Server to be able to run jobs that impersonate (i.e. use the security rights of) the SQL Server Agent service account.
Figure 1: Job Security in a CmdExec job step

Creating a CmdExec job step

To create a CmdExec job step, create a new job (we can call it ShellOut), then add a New Job Step. As shown in Figure 1, we’ll name the step s1. Change the Type of job step to “Operating system (CmdExec)”, and leave the Run as: field at the default value (“SQL Server Agent Service Account”). For our first job, simply enter “dir c:\” as shown in Figure 1 for the command text. Click OK, then OK again to save the job. Run the job (right click on the job “ShellOut” and select “Start Job at Step”, then once the job has run right-click and select View History. Click on the job step output as shown in Figure 2 to see that a DIR was run against your C drive.
Figure 2: The Log File Viewer showing the results of a CmdExec job
As you might imagine, this is a trivial command but you could easily imagine running complex batch scripts, or as mentioned before, even start a program (for example, “start notepad” would run notepad). A word of caution is in order, however. If you launch a program such as notepad, it will be running in a virtual hidden desktop, waiting for input from a userAnd because the desktop is hidden, no user can supply any input, not even a command to exit the program. In other words, your job step won’t ever complete. You will have to find the notepad process in a program such as Task Manager, and kill the process for the job step to return. Running programs from the CmdExec subsystem enables many interesting scenarios as long as the program will naturally return control back to SQL Server Agent when it’s complete.

The PowerShell subsystem

The PowerShell subsystem was added to SQL Server with the SQL Server 2008 release. It will function with either PowerShell 1.0 or PowerShell 2.0, depending upon which version is installed on your server. When you create a job step and select the PowerShell subsystem for your job step type, you will have options similar to the CmdExec subsystem. You can enter the text of a PowerShell script, or call an existing PowerShell script (.ps1). When you start a PowerShell session from within SQL Server Agent, the SQL Server PowerShell provider and cmdlets are pre-loaded for you.
There are many additional considerations with PowerShell dealing with script signing and security, which are too extensive to go into for this article. However, you can read about them in this TechNet article from the Windows PowerShell Owner’s Manual:http://technet.microsoft.com/en-us/library/ee176949.aspx.
With that caveat, PowerShell could easily become your favorite subsystem for scripting work. For ordinary tasks within SQL Server, running a Transact-SQL script is usually simpler. However, repetitive tasks, or as in the case of CmdExec, any task that leaves the SQL Server environment is much simpler from the PowerShell subsystem.
To show an example, re-open your ShellOut job, and add a job step, s2. Select PowerShell for the Type, and then enter the following script:

$server = new-object( 'Microsoft.SqlServer.Management.Smo.Server' ) “(local)”
foreach ($database in $server.databases) {
$dbName = $database.Name
Write-Output "Database: $dbName" }

Figure 3: The Job Step for the PowerShell subsystem
This script will simply log into your local SQL Server (change the instance name if using a named instance), and then loop through and get the name of each database on the server. You can easily imagine backing up the database, or examining its properties, for example. The other thing to notice is that you had to log in and make a database connection – so nothing is stopping you from logging into any SQL Server in your organization. To try this out, click OK, the OK again. If you are prompted to, fix up the job step s1 so that it will flow properly into step s2. Run the job, and view the output as you did for the CmdExec subsystem step. You will see a list of your databases on your server has been output.
What’s really interesting about the PowerShell subsystem, however is that you can query information from the operating system, or active directory, etc. and then run just about any script you can think of to act upon your server. Do you want to query the ports SQL Server is listening on? You can use WMI through PowerShell. Do you want to get some information from the registry? You get the idea. There are many, many PowerShell scripts posted on the Internet (including many articles here at SQLServerCentral).

The ActiveX Script subsystem

The ActiveX Script subsystem allows you to run ActiveX scripts, which can use VBScript or Jscript to complete tasks in the operating system. This subsystem is included here for completeness, but you should not use ActiveX scripts from SQL Server Agent. The subsystem is deprecated, meaning it will be removed from a future version of SQL Server.

Which subsystem should I use?

If you have an existing job using one of these subsystems, you should probably continue to let it work unless you have a compelling reason to change it. However, if you are starting a new job and/or job step, the PowerShell subsystem offers the most compelling capabilities. Additionally, Microsoft has clearly moved in the direction of PowerShell as the standard scripting language for all Microsoft server products. An investment of your time learning PowerShell will pay dividends well beyond SQL Server Agent.

What’s Next

SQL Server Agent’s CmdExec, PowerShell, and ActiveX subsystems allow you to leave the confines of SQL Server to perform many tasks, including running batch files or external programs. Additionally, with PowerShell you can access and control just about any Microsoft product. PowerShell is the recommended subsystem to use for new work.

Eliminar publicidad de las aplicaciones y juegos en android con addfree


Este vídeo muestra como quitar la estorbosa publicidad de aplicaciones y juegos en Android. Saludos

Configurar Réplica Maestro - Esclavo en MySql Server


Hoy hemos tenido que montar para un cliente un servidor de réplica de MySql en el que era imperioso que los datos se espejearan de forma inmediata entre el servidor maestro y el esclavo.
Una réplica de MySql Server hace uso del fichero binario de transacciones para almacenar en el maestro todos los cambios reaizados (UPDATES, DELETES, CREATE, etc..) para que un servidor externo lo lea y replique exactamente los mismos cambios en su propia base de datos.
De este modo tenemos uno o más servidores MySql esclavos haciendo las mismas transacciones que el maestro para así tener los mismos datos en diferentes servidores cosa que se realmente útil y, no sólo ante caídas, ya que es posible configurar nuestra aplicación para compartir las SELECT entre distintos nodos de MySql y mejorar así el rendimiento.

Bueno, menos teoría y vamos al lío!.
Lo primero que debemos hacer es configurar el servidor maestro para que almacene el log binario y asignarle un identificador. Para ello editamos el my.cnf añadiendo (o editando si ya las tiene) las siguientes entradas:
?
1
2
3
4
5
6
7
8
9
#Identificador único del servidor maestro
server-id=1
#Nombre del fichero binario donde se almacenarán las transacciones
log-bin=mysql-bin
sync_binlog=1
#Tamaño del fichero de log tras lo que se truncara
max-binlog-size=500M
expire_logs_days=4
innodb_flush_log_at_trx_commit=1
Como siempre que modificamos un my.cnf hay que reiniciar el servicio de MySql para que acepte los cambios.
Luego tenemos que hacer lo propio con el (o los) esclavo(s). Modificar el my.cnf con los siguientes parámetros y luego reiniciar el servicio:
?
1
2
3
4
5
#Indentificador único del esclavo
server-id=2
relay-log=mysqld-relay-bin
max-relay-log-size=500M
relay_log_purge=1
¡Muy bien! Ya tenemos un servidor maestro y un esclavo pero ahora necesitamos crear un usuario para que el esclavo se conecte al maestro y pueda leer el log de transacciones. Para ello vamos a crear un nuevo usuario llamado "replicador" (el nombre y pass puede variar, jeje) en el master con privilegios de "REPLICATION SLAVE":
?
1
CREATE USER replicador IDENTIFIED BY 'elpassword';
Y luego le damos los permisos de REPLICATION SLAVE:
?
1
2
GRANT REPLICATION SLAVE ON *.* TO 'replicador'@'%' IDENTIFIED BY 'elpassword';
FLUSH PRIVILEGES;
Ok! Ya tenemos los servidores bien configurados y el usuario que usaremos como replicador por lo que lo próximo que tenemos que hacer es crear una copia inicial o "snapshot" de la base de datos que queremos replicar para luego poder indicar al servidor esclavo desde dónde tiene que empezar a leer.
Para hacer el snapshot primero ejecutamos las siguientes consultas:
?
1
2
3
FLUSH TABLES;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
Ten en cuenta que al hacer "READ LOCK" estamos bloqueando la tabla para que nadie cambie nada por lo que lo que viene a continuación deberíamos hacerlo lo más rápidamente posible.
El SHOW MASTER STATUS muestra dos valores que debemos anotar que son el "File" y "Position". Necesitaremos indicarselos al servidor de réplica una vez hayamos cargado la copia inicial.
?
1
2
3
4
5
6
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |     492 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
¡Muy bien! Vamos al servidor esclavo y lo terminamos de configurar.
Lo primero es cargar una copia de seguridad de base de datos que queremos replicar del master al esclavo (puedes usar el método que quieras, mysqldump, HeidSql, MySql Workbench...) y, una vez restaurada, configurar el esclavo e iniciarlo.
En este ejemplo vamos a suponer que el servidor maestro está alojado en 10.0.1.10. Fíjate que tenemos que indicar elFile y la Position que hemos obtenido antes del SHOW MASTER STATUS:
?
1
2
3
CHANGE MASTER TO MASTER_HOST='10.0.1.10', MASTER_USER='replicador', MASTER_PASSWORD='elpassword', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=492, MASTER_PORT=3306;
START SLAVE;
Para terminar volvemos al maestro y desbloqueamos de nuevo las tablas para que puedan volver a editar datos:
?
1
UNLOCK TABLES;
¡Ya está! Si no ha pasado nada raro tendremos el servidor esclavo con la carga inicial funcionando y todo cambio en el master se replicara por arte de magia.
Si queremos saber el estado del servidor de réplica podemos usar la consulta:
?
1
SHOW SLAVE STATUS\G
Que nos mostrará un listado de datos. Yo miro el valor "Seconds_Behind_Master" que indica que "retraso" tiene el servidor esclavo respecto al maestro (si es NULL es que no va. Revisa el "Slave_IO_State" y "Last_Error").
Ahora empieza a meter datos en la base de datos maestra y verás como ellos solitos aparecen en la esclava... ¡brujería! :-)

Espero que esto os sea útil.