Ссылка на контекст PowerShell агента SQL

13

На моей новой работе у нас есть несколько именованных экземпляров на каждом сервере. например

  • Сервер1 \ Dev
  • Сервер1 \ DevIntegrated
  • Сервер1 \ QA

У меня есть сценарий SQL PowerShell в работах, который вызывает к ОС, вызывает, Foo.exeно должен передать параметр командной строки (строка подключения). Задание агента SQL будет существовать в каждом экземпляре с шагом типа PowerShell, который должен знать текущий контекст. т.е. это исполнение началось на DevIntegrated.

У меня нет желания начинать каждый сценарий с ...

$thisInstance = "Dev"

... тем более, что мне придется редактировать это, когда мы перейдем к средам (новым серверам и именованным экземплярам) в ближайшие месяцы.

Если я запускаю SQLPS, я могу определить свой экземпляр, нарезав и нарезав результаты Get-Location или выполнив

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

Когда агент SQL запускает задание типа PowerShell, он запускается в C: \ windows \ system32, и Get-Locationмаршрут не работает, поскольку он не находится в контексте SQLSERVER. Я могу перейти в этот контекст, но я буду в «корне» SQL Server и не буду знать, в каком экземпляре я должен быть. Использование Invoke-Sqlcmdмаршрута не будет работать либо по той же причине (технически это истекло, так как не является экземпляром по умолчанию)

Насколько мне известно, я перечислил все основные «вещи», которые я могу получить в журнале работы, но, кажется, ничего не показывает SQLSERVER:\SQL\Server1\DevIntegrated

Get-ProcessПохоже, я мог бы использовать это и какое-то вуду, пытаясь связать вещи друг с другом, ударяя по инстансам и подбирая спиды, но это звучит как кровавый хак из ада. Там должно быть что-то основное, что я пропускаю, кто-нибудь может пролить свет?

Исследованы альтернативы PowerShell

Я исследовал, используя другие типы работы, и не получил удовлетворительного разрешения. Исследования показали, что PowerShell, указанный в разделе «Агент SQL», был SQLPS, и запуск его экземпляра с помощью щелчка правой кнопкой мыши на агенте автоматически привел меня в нужное место. Только когда я вставил свой интерактивный код в шаг работы, я узнал о разнице, как упоминалось ранее.

Тип работы ОС привел меня в идентичное состояние, так как я не мог найти способ определить, какой экземпляр бросил меня в командную оболочку. Конечно, я мог бы получить sqlcmd и получить значение, @@servernameно если бы я знал, какое соединение запустить sqlcmd, мне бы не пришлось запрашивать базу данных;)

TSQL, вероятно, может работать, если мы включим, xp_cmdshellно я не уверен, что он включен - государственное учреждение, и они могут быть привередливы при нестандартных настройках. Даже в этом случае я застрял на динамическом SQL и потерял много выразительности и мощности, которые дает PowerShell.

В то время как немного неловко, я подумал определить переменную на первом шаге и передать ее последующим шагам, но исследование подняло эту статью Обработка нескольких рабочих мест (BOL)

Рабочие шаги должны быть автономными. Таким образом, задание не может передавать логические значения, данные или числовые значения между этапами задания. Однако вы можете передавать значения из одного шага задания Transact-SQL в другой, используя постоянные таблицы или глобальные временные таблицы. С помощью файлов можно передавать значения из шагов задания, которые запускают исполняемые программы, с одного шага задания на другой шаг задания.

Я не могу использовать общие приемы, такие как общеизвестные переменные файла / среды / настройки реестра, которые Foo.exeищут, поскольку это предотвратит одновременное выполнение между экземплярами.

TL; DR:

На шаге Задание агента SQL типа PowerShell как определить экземпляр SQL Server, который запустил процесс?

billinkc
источник
4
PowerShell является требованием для того, что вы делаете?
johndacostaa
Истинным требованием было бы иметь повторно используемое «что-то» в агенте SQL, который может запускать процесс DOS с параметром вызывающего экземпляра. PowerShell выглядел как нельзя лучше, учитывая то, что не сработало выше. Извините за запоздалый ответ, я был в лагере скаутов.
billinkc

Ответы:

9

Если вы посмотрите на SQL Server BOL, агент SQL Server предоставит набор «токенов», которые он будет подставлять как в текст команды шага задания, так и в выходной файл (последний помешает работе кнопки «просмотр» GUI). Эти токены, кажется, работают для любого типа шага, кроме T-SQL.

https://docs.microsoft.com/en-us/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

К сожалению, я мало что сделал со скриптами PowerShell, вызываемыми внутри SQL Server. Также я не за компьютером, чтобы я мог играть с ним прямо сейчас.

Однако я полагаю, что вместо использования шага типа PowerShell, если вы использовали CmdExec и просто вызывали свой сценарий, как если бы вы делали это из командной строки «powershell 'MyScript.ps1'", вы могли бы затем передать параметр, из которого запущен экземпляр. Например, «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 вы можете установить глобальную переменную, которую может использовать весь пакет.


источник