SQL Agent Powershell上下文参考


13

在我的新工作中,每个服务器上都有多个命名实例。例如

  • Server1 \ Dev
  • Server1 \ DevIntegrated
  • 服务器1 \质量检查

我的作品中有一个SQL PowerShell脚本,可以调用OS,调用它,Foo.exe但需要传递命令行参数(连接字符串)。每个实例上都将存在一个SQL Agent作业,其步骤为PowerShell类型,该步骤需要知道当前上下文是什么。此执行从DevIntegrated开始。

我不希望每个脚本都以...开头

$thisInstance = "Dev"

...特别是因为在接下来的几个月中,当我们迁移到环境(新服务器和命名实例)时,我必须对其进行编辑。

如果启动SQLPS,则可以通过将Get-Location的结果切片和切块或运行来确定实例

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

当SQL Agent启动PowerShell类型的作业时,它将在C:\ windows \ system32中启动,并且该Get-Location路由不起作用,因为它不在SQLSERVER上下文中。我可以更改为该上下文,但是我将位于SQL Server的“根目录”,并且不知道我应该在哪个实例中使用。Invoke-Sqlcmd由于相同的原因,使用路由也不起作用(从技术上讲,它在那里超时了)不是默认实例)

据我所知,我已经列举了所有可以进入工作日志的基本“内容”,但似乎没有任何显示 SQLSERVER:\SQL\Server1\DevIntegrated

Get-Process似乎我可以使用它以及通过敲击实例和匹配spid来拼凑事物的一些巫术,但这听起来像是来自地狱的血腥骇客。我必须缺少一些基本的东西,有人可以阐明吗?

研究了PowerShell的替代方法

我调查了其他工作类型,但没有得到满意的解决方案。研究表明,SQL代理下列出的PowerShell为SQLPS,并通过右键单击该代理来启动它的实例,从而自动将我放到正确的位置。如前所述,只有当我将交互式代码粘贴到工作步骤中时,我才知道其中的区别。

作业类型的OS使我进入了相同的状态,因为我无法找到确定哪个实例将我放入命令外壳的方法。当然,我可以sqlcmd并获取的值,@@servername但是如果我知道启动sqlcmd的连接,则无需查询数据库;)

如果启用了TSQL,TSQL可能会起作用,xp_cmdshell但是我不确定它们是否已启用---政府工具,并且在使用非默认设置时可能会感到困惑。即便如此,我仍然沉迷于动态SQL,并失去了PowerShell提供的许多表达能力。

虽然有点麻烦,但我认为第一步要定义一个变量,然后将其传递给后续步骤,但是研究发现这篇文章处理多个作业步骤(BOL)

作业步骤必须是独立的。也就是说,作业无法在作业步骤之间传递布尔值,数据或数字值。但是,您可以使用永久表或全局临时表将值从一个Transact-SQL作业步骤传递到另一步骤。您可以使用文件将运行可执行程序的作业步骤中的值从一个作业步骤传递到另一作业步骤。

我不能使用常见的技巧,例如Foo.exe寻找众所周知的文件/环境变量/注册表设置,因为那样会阻止跨实例的并发执行。

TL; DR:

在PowerShell类型的SQL Agent Job步骤中,如何确定启动该过程的SQL Server实例?


4
Powershell是否对您的工作有要求?
johndacostaa 2011年

真正的要求是在SQL代理中有一个可重新定义的“内容”,该内容可以使用调用实例的参数启动DOS进程。鉴于以上无法解决的问题,PowerShell似乎是最合适的选择。对不起,迟到的回应,我当时在童子军营地。
billinkc 2011年

Answers:


9

如果您查看SQL Server BOL,则SQL Server代理会提供一组“令牌”,它将替换为作业步骤命令文本和输出文件(后者将阻止GUI“视图”按钮起作用)。这些令牌似乎适用于除T-SQL之外的任何类型的步骤。

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

因此,如果您有一个SQL 2008 PowerShell步骤,则可以使用以下步骤启动它:

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

您可能需要改用MACH(计算机名称)和INST(仅实例名称),因为对于默认实例SRVR == MACH,但是对于命名实例SRVR == MACH\INST


3

可悲的是我还没有被称为在SQL Server内部的PowerShell脚本多少事。我现在也不在可以使用它的计算机上。

我相信,虽然您可以使用CmdExec并像在命令行“ powershell'MyScript.ps1'”中那样调用脚本,而不是使用PowerShell类型的步骤,但是可以传递一个包含您正在运行的实例的参数。就像“ Powershell'MyScript.ps1'MyInstanceName”。

因此,在脚本的开头,您有一个param()设置来接受MyInstanceName的值:


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

当您开始陈述第一步时,需要知道它在哪个实例上,以便PowerShell脚本可以正确调用Foo.exe。但是,稍后您会提到能够将该值传递给其他步骤。如果是这样,您可能希望创建一个小的SSIS程序包,该程序包调用PowerShell脚本并执行您需要执行的其他任何操作。使用SSIS,您可以设置整个程序包可以使用的全局变量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.