使用PowerShell脚本管理SQL Server 2008实例(上)

日期: 2009-09-14 作者:Robert Sheldon翻译:曾少宁 来源:TechTarget中国 英文

如果要在SQL Server 2008之前版本的数据库上使用Windows PowerShell脚本来管理一个SQL Server实例,我们必须基于SQL Server Management Object(SMO)模型创建访问各种服务器和数据库组件的对象。但是从SQL Server 2008开始,访问这些组件就是把服务器/数据库层次当成文件目录一样灵活访问。   在SQL Server 2008中,PowerShell支持仍然依赖于SMO模块,但是它是通过使用SQL Server 2008带的2个PowerShell插件完成的。其中ServerProviderSnapin100插件用以连接到一……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

如果要在SQL Server 2008之前版本的数据库上使用Windows PowerShell脚本来管理一个SQL Server实例,我们必须基于SQL Server Management Object(SMO)模型创建访问各种服务器和数据库组件的对象。但是从SQL Server 2008开始,访问这些组件就是把服务器/数据库层次当成文件目录一样灵活访问。

  在SQL Server 2008中,PowerShell支持仍然依赖于SMO模块,但是它是通过使用SQL Server 2008带的2个PowerShell插件完成的。其中ServerProviderSnapin100插件用以连接到一个SQL Server实例并访问SQL Server组件层次,而SqlServerCmdletSnapin100插件提供了一套SQL Server的cmdlet(PowerShell命令——拼读为com_MAND--let)。这些插件和PowerShell环境一起就能很容易地创建PowerShell脚本来实现一个SQL Server实例的自动化管理。

  为了演示创建和作用PowerShell脚本,本文将介绍一个查询特定SQL Server实例的数据信息的基本脚本。文中将介绍脚本的每一行,然后介绍如何在PowerShell中运行该脚本。虽然这里只涉及单独一个脚本,但这些概念可以应用到许多管理SQL Server的脚本中。更多关于SQL Server如何在PowerShell中支持实现的细节,请查阅SQL Server 2008 Books Online。

  创建PowerShell脚本

  PowerShell脚本是保存在扩展名为.psl的文本文件中。本文中的脚本名是DbInfo.psl,这个脚本查询一个SQL Server实例的名称、大小、空间使用情况和所有nonsystem数据库可用的空间。然后从SQL Server查询到的数据库信息会导出到一个.csv文件中。下面的代码是脚本文件的内容:

  # define parameters
  param
  (
  $Server = $(Read-Host "Server"),
  $Instance = $(Read-Host "Instance (use 'default' for default instance)"),
  $TargetFolder = $(Read-Host "Target folder")
  )
  # if necessary, add backslash to target folder
  If (!$TargetFolder.EndsWith(""))
  {
  $TargetFolder = $TargetFolder + ""
  }
  # set path and file name for output file
  $FileName = $TargetFolder + $Server + "." + $Instance + ".csv"
  # retrieve database objects
  $Path = "sqlserver:sql$Server$InstanceDatabases"
  $Databases = Get-ChildItem $Path
  # return details about each database
  $Databases |
  Select-Object Name, Size, DataSpaceUsage, IndexSpaceUsage, SpaceAvailable |
  Export-Csv -path $FileName

  这个PowerShell脚本的第一部分定义了在脚本文件调用时传入的参数。其中共有3个参数,如下代码所示:

  param
  (
  $Server = $(Read-Host "Server"),
  $Instance = $(Read-Host "Instance (use 'default' for default instance)"),
  $TargetFolder = $(Read-Host "Target folder")
  )

  参数$Server是SQL Server所安装的计算机。如果这个计算机是本地系统,那么可以在提示时用“localhost”代替计算机名。参数$Instance指的是特定的SQL Server实例。如果这是默认的实例,就用“default”。第3个参数是$TargetFolder,这是输出的.csv文件所在的位置。

  我们可以看到,param语句定义了必要的参数。参数定义是在括弧内,而且如果不只一个参数,就用逗号分开。每一个参数都会赋上一个值。这个值是基于Read-Host cmdlet,它显示一个字符串并提示用户输入。

  例如,参数$Server的Read-Host cmdlet显示单词“server”并将SQL Server计算机名作为输入。Read-Host cmdlet和它的参数都包含在括号中,前面带一个美元符号。这会告诉PowerShell先处理表达式,然后将值赋给参数$Server。结果,用户输入的服务器名会赋给$Server。

  脚本的下一部分是一个if语句,这保证$TargetFolder的值后面有一个反斜杠来连接上脚本后面的文件名:

  If (!$TargetFolder.EndsWith(""))
  {
  $TargetFolder = $TargetFolder + ""
  }

  If语句是以关键字if开头的表达式开始的,这个表达式是包含在括弧中,并且是在语句执行时计算出值。如果表达式的值为真,那么大括号里的脚本块代码就会执行。否则,脚本块的代码不会执行。

  在本例中,被估值的表达式使用$TargetFolder变量的EndsWith文件来决定指定的文件路径是否是一个反斜杠结束。因为表达式前有一个感叹号,所以表达式只有在文件路径不以一个反斜杠结束时才会是真。当表达式值为真时,脚本块会执行,并且添加一个反斜杠到变量值中。

  PowerShell脚本代码的下一行连接变量值与字符串来生成文件路径和输出数据库信息文件的名称。

  $FileName = $TargetFolder + $Server + "." + $Instance + ".csv"

  我们可以看到,文件名是基于服务器和实例名的。例如,如果SQL Server主机名为Server01,而SQL Server实例是SqlSrv2008,那么文件名就是Server01.SqlSrv2008.csv。然后这个值就赋给$FileName变量。

  PowerShell脚本尝试定义指向一个特定SQL Server实例的数据库的路径。当使用PowerShell来处理诸如数据库的SQL Server对象时,我们指定对象所在的层次,如下面代码所示:

  $Path = "sqlserver:sql$Server$InstanceDatabases"

  我们注意到这个路径看起来与目录结构的一个文件路径很相似。首先,我们指定了正确的提供者(sqlserver:sql)。这告诉PowerShell这个路径描述一个SQL Server实例中的一个位置。

  这个路径的下一部分是服务器名,它在变量$Server以脚本开头作为一个参数时保存到该变量中。在指定服务器后,我们还要指定实例。这里,我们使用$Instance变量。这个层次的一下级包含了数据库本身,它们位于Databases集合中。这个集合包含了每一个数据库的对象。换句话说,每一个SQL Server实例都有一组数据库,并且其中每一个数据库在PowerShell中都表现这一个对象。

  当在PowerShell脚本定义的路径,我使用一个双引号中的字符串,然后赋给$Path变量。然后我可以使用$Path变量从Databases集合中查询出数据库,如下代码所示:

  $Databases = Get-ChildItem $Path

  类似从一个目录查询一堆文件,Get-ChildItem cmdlet查询包含在一个容器中的对象。当调用Get-ChildItem cmdlet时,变量$Path会作为一个参数传递给它。结果,包含在指定SQL Server实例的Databases集合中所有数据库将被返回。然后数据库集合会被赋给$Databases变量。

  在将数据库集合赋给一个变量后,我们就可以使用该变量去访问集合中的每一个数据库了。在脚本的下一部分,我将数据库集合发送/传递给Select-Object cmdlet:

  $Databases |
  Select-Object Name, Size, DataSpaceUsage, IndexSpaceUsage, SpaceAvailable |
  Export-Csv -path $FileName

  注意竖线(|)跟在变量$Databases后面。这将告诉PowerShell将一个命令返回的数据向下传递到下一个命令。这里,变量$Databases的内容被下发到Select-Object cmdlet。然后Select-Object cmdlet查询指定的属性值,以及传递给它的每一个数据库。例如,如果AdventureWorks指定的SQL Server实例中的一个数据库,那么该数据库的名称、大小、数据空间使用和索引空间使用将会通过该命令返回。然后,这些属性值将被发送到Export-Csv cmdlet中,这将输出数据库属性值到.csv文件中。

  我们也可以返回数据库对象支持的任意属性值。为了查询属性列表,我们可以使用Get-Member cmdlet。这使我们能够查询到一个对象的方法和属性。 例如,下面的语句查询出与AdventureWorks数据库有关的数据库对象的属性列表。

  $Databases | Where-Object{$_.Name –eq 'AdventureWorks'} |

  该语句以调用$Databases变量开始,最后将这些值传递下去。这个过程假定我们已经给变量赋值了一个SQL Server实例的一组数据库。

  这个管道的下一个命令是一个Where-Object cmdlet。这个cmdlet 包含一个大括号中的表达式,对象将被传递到管道的下一个命令中。例如,在上面的语句中,属性Name的值必须等于“AdventureWorks”才能使表达式值为真。结果,只有AdventureWorks数据库对象被传递给Get-Member cmdlet。这里,我指定了-MemberType参数和“property”值,这样只有属性才会被返回。

翻译

曾少宁
曾少宁

TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。

相关推荐