SQL Server代理是所有实时数据库的核心。代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的。这系列文章会通俗介绍它的很多用法。
在这个系列的上篇文章里,你学习如何使用SQL Server代理作业活动监视器监视作业活动和查看作业历史。对于你的SQL Server代理作业进行实时监视和管理,作业活动管理器是个强大的工具。在这个系列的第8篇文章里,你会回顾SQL Server代理的另一个功能——运行操作系统命令行,在SQL Server外围环境运行程序。一些程序是命令行(传统的cmd应用程序/脚本或PowerShell脚本),或者甚至ActiveX脚本,但实际上你可以运行系统命令行,几乎可以运行任何程序,只要程序不需要用户的直接输入。你会学到如何运行cmdexec和PowerShell脚本,我们会简单讨论下什么时候用这些子系统会更合适。你学到如何从SQL Server代理调用其它程序。
如你在以前的文章所见,有很多内建的子系统。在这篇文章里,你会检查可以在操作系统里运行脚本或程序的3个内建子系统,而不是在SQL Server环境本身的上下文。这3个包括:
但一个程序或脚本从这个3个系统启动时,在操作系统里会创建新的进程(例如不是SQL Server代理的一部分),脚本或程序运行,信息传回启动进程或脚本的SQL Server代理作业。
第一个我们要谈的是操作系统(CmdExec)子系统。CmdExec子系统打开一个命令行,犹如已经登录到运行SQL Server的操作系统。从那点来说,你可以运行一切,在命令行里输入。这包括任何的批处理文件,脚本,甚至你服务器上存在的程序,当然你可以在输入UNC路径来访问文件,这是CmdExec子系统可以做的。
当然,所有关于这个的重要提醒是权限——会正常工作么,在什么安全上下文下?默认情况下,当你在CmdExec子系统里创建一个作业(或其他的,一会就会看到),作业会在SQL Server代理服务账号的安全上下文运行(如插图1所示)。你也会留意到这是个下拉的值,因此也有其它选项。在这个系列的第10篇,你会用到代理账号。另一个要注意的重点:你必须是SQL Server的sysadmin组成员,才可以运行SQL Server代理服务账号运行的作业。
插图1:在CmdExec作业步骤里的作业安全
为了创建CmdExec作业步骤,创建新的作业(我们命名为Shellout),然后添加新的作业步骤。如插图1所示,我们命名步骤为S1,修改作业步骤类型为“操作系统(CmdExec)”,保持运行身份为默认(”SQL Server 代理服务账号“)。对于我们的第一个作业,简单的输入”dir c:/",如插图1所示命令文本。点击【确定】,然后点击【确定】保存作业。运行作业(右击作业“Shellout”,选择【作业开始步骤】),一旦作业完成运行,右击选择【查看历史记录】。点击作业步骤的输出,如插图2所示,已经对应C盘执行了dir命令。
插图2:日志文件查看起显示的CmdExec作业执行结果
如你所想象的,这个是一个简单的命令,你很容易想到运行复杂的批处理脚本,或者如刚才描述的,甚至启动一个程序(例如,启动“记事本”)。 提醒一句,如果你启动例如记事本的程序,它会运行在虚拟隐藏的桌面,等待用户输入。因为桌面是隐藏的,没有用户可以输入,甚至退出程序的命令也不行。换句话说,你的作业步骤永远不会结束。你需要在例如任务管理器里找到记事本的进程,杀掉进行来让作业步骤返回。从CmdExec子系统运行程序会有很多有趣的场景,只要程序会正常返回控制给SQL Server代理,才会结束。
PowerShell自SQL Server 2008发布的时候加入。它支持PowerShell 1.0 或 PowerSher 2.0,取决与你服务器上安装的版本。当你创建了一个作业步骤,选择了PowerShell子系统作为你的作业步骤类型,你会有和CmdExec子系统类似的选项。你可以输入PowerShell脚本的文本,或调用现存的PowerShell脚本。当你从SQL Serverdialing里启动PowerShell会话,SQL Server的PowerShell会提前为你加载。
当使用PowerShell脚本签名和安全时,有很多要考虑的事情,这个话题太大,在这里就不讨论了。但你可以参阅下它的用户手册: https://technet.microsoft.com/en-us/library/ee176949.aspx
顺便提下,PowerShell会很容易成为你的脚本工具。对于SQL Server里常规操作,例如运行T-SQL会更简单。
不管怎样,重复的工作,或者在CmdExec情况下的操作,从PowerShell子系统离开SQL Server环境的任何操作都更简单。
为了展示一个例子,重新打开你的ShellOut作业,增加一个作业步骤S2。选择PowerShell作为作业类型,例如下列脚本:
1 $server = new-object( 'Microsoft.SqlServer.Management.Smo.Server' ) “(local)” 2 3 foreach ($database in $server.databases) 4 { 5 $dbName = $database.Name 6 Write-Output "Database: $dbName" 7 }
插图3:PowerShell子系统的作业步骤
这个脚本会直接登录到你的本地SQL Server(如果要指定服务器就修改实例名称),然后在服务器上循环获得每个数据库的名称。你很容易会想到数据库备份,例如检查它们的属性等。另外要注意的是你已经登录并连接到数据库——因此在你的组织里你可以登录到任意的SQL Server。为了试验这个,点击确定,再次点击确定。如果出现提示,修正作业步骤1这样它会正确走向下一步。运行作业,和查看CmdExec子系统步骤的输出一样的方法。你会看到输出有服务器上的数据库名称列表。
PowerShell子系统真正有趣的是,你可以从操作系统、活动目录查询信息,然后可以运行你想要对你服务器操作的任何脚本。你想查询SQL Server监听的端口号么?你用通过PowerShell查询WMI。你想从注册表获取信息?也是可以的。在网络上有很多PowerShell脚本,你可以自己依据需要搜索下。
ActiveX脚本子系统允许你运行运行ActiveX脚本,在操作系统里可以使用VBScript或Jscript。这里包括这个子系统是作为补充,但你不应该从SQL Server代理使用ActiveX脚本。这个子系统已经剥离,就是说以后的SQL Server将会移除这个功能。
如果现存的作业使用其中一个子系统,你应该继续使用它,除非你有足够的理由来修改它。不管怎样,如果你启动一个新的作业或作业步骤,PowerShell子系统提供你足够强大的功能。另外,微软已经将PowerShell脚本作为微软所有产品的标准脚本。花时间学习下PowerShell会让你的SQL Server代理非常强大!
SQL Server代理的CmdExec,PowerShell和ActiveX子系统允许你与SQL Server代理进行很多任务,包括运行批处理文件或外部程序。另外,使用PowerShell你可以访问和控制任何微软产品。对于新的任务,推荐使用PowerShell子系统。
在下篇文章里,我们会谈论下SQL Server代理安全。到目前为止,这系列文章都假定你是sysadmin服务组成员,下一步会从SQL Server代理的非sysadmin组成员角度谈论下SQL Server代理,还有深入谈下作业的安全上下文。