На моей новой работе у нас есть несколько именованных экземпляров на каждом сервере. например
- Сервер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-ChildItem
Get-Host
Get-Location
Get-Process
Get-PSDrive
Get-PSProvider
Get-Service
Get-TraceSource
Get-Variable
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, который запустил процесс?
Ответы:
Если вы посмотрите на 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, вы можете запустить его с:
Возможно, вам придется использовать
MACH
(имя машины) иINST
(просто имя экземпляра) вместо этого, потому что с экземпляром по умолчаниюSRVR == MACH
, но с именованными экземплярамиSRVR == MACH\INST
.источник
К сожалению, я мало что сделал со скриптами PowerShell, вызываемыми внутри SQL Server. Также я не за компьютером, чтобы я мог играть с ним прямо сейчас.
Однако я полагаю, что вместо использования шага типа PowerShell, если вы использовали CmdExec и просто вызывали свой сценарий, как если бы вы делали это из командной строки «powershell 'MyScript.ps1'", вы могли бы затем передать параметр, из которого запущен экземпляр. Например, «Powershell» MyScript.ps1 «MyInstanceName».
Итак, в начале вашего скрипта у вас есть настройка param () для принятия этого значения MyInstanceName:
Когда вы начинали, указав один шаг, необходимо знать, на каком экземпляре он находится, чтобы скрипт PowerShell мог правильно вызывать Foo.exe. Однако позже вы упомянете о возможности передачи значения другим шагам. Если это так, возможно, вы захотите взглянуть на создание небольшого пакета служб SSIS, который вызывает ваш скрипт PowerShell и выполняет все, что вам нужно. С помощью SSIS вы можете установить глобальную переменную, которую может использовать весь пакет.
источник