Odwołanie do kontekstu PowerShell agenta SQL


13

W mojej nowej pracy mamy wiele nazwanych instancji na każdym serwerze. na przykład

  • Serwer1 \ Dev
  • Server1 \ DevIntegrated
  • Serwer1 \ QA

Mam skrypt SQL PowerShell w pracy, która wywołuje system operacyjny, wywołuje, Foo.exeale musi przekazać parametr wiersza polecenia (ciąg połączenia). Zadanie agenta SQL będzie istnieć w każdej instancji, z krokiem typu PowerShell, który musi wiedzieć, jaki jest obecny kontekst. tj. To wykonanie rozpoczęło się na DevIntegrated.

Nie chcę, aby każdy skrypt zaczynał się od ...

$thisInstance = "Dev"

... zwłaszcza, że ​​musiałbym to edytować, gdy przeprowadzimy migrację do środowisk (nowych serwerów i nazwanych instancji) w nadchodzących miesiącach.

Jeśli uruchomię SQLPS, mogę określić moją instancję, krojąc i krojąc wyniki Get-Location lub uruchamiając

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

Gdy SQL Agent uruchamia zadanie typu PowerShell, uruchamia się w C: \ windows \ system32 i Get-Locationtrasa nie działa, ponieważ nie jest w kontekście SQLSERVER. Mogę przejść do tego kontekstu, ale będę w „katalogu głównym” programu SQL Server i nie będę wiedział, w której instancji powinienem być. Korzystanie z Invoke-Sqlcmdtrasy nie będzie działać z tego samego powodu (technicznie rzecz biorąc, limit czasu jest tam nie jest instancją domyślną)

Według mojej najlepszej wiedzy wyliczyłem wszystkie podstawowe „rzeczy”, które mogę dostać do dziennika zadań, ale wydaje się, że nic nie pokazuje SQLSERVER:\SQL\Server1\DevIntegrated

Get-Processwygląda na to, że mógłbym użyć tego i jakiegoś voodoo próbowania łączenia rzeczy poprzez uderzanie w instancje i dopasowywanie pająków, ale to brzmi jak cholerny hack z piekła rodem. Musi być coś podstawowego, za czym tęsknię, czy ktoś może rzucić trochę światła?

Badane alternatywy dla PowerShell

Badałem przy użyciu innych rodzajów pracy i nie uzyskałem zadowalającego rozwiązania. Badania wykazały, że PowerShell wymieniony w obszarze SQL Agent to SQLPS i uruchomienie jego instancji poprzez kliknięcie prawym przyciskiem myszy na Agencie automatycznie upuściło mnie do właściwej lokalizacji. Dopiero kiedy wkleiłem mój interaktywny kod do etapu pracy, dowiedziałem się o różnicy, jak wcześniej wspomniano.

System operacyjny typu zadania wprowadził mnie w identyczny stan, ponieważ nie mogłem znaleźć sposobu, aby określić, która instancja upuściła mnie do powłoki poleceń. Jasne, mógłbym sqlcmd i uzyskać wartość, @@servernameale gdybym wiedział, jakie połączenie uruchomić sqlcmd, nie musiałbym sprawdzać bazy danych;)

TSQL może prawdopodobnie działać, jeśli włączymy, xp_cmdshellale nie jestem pewien, czy mają one włączone --- narzędzie rządowe i mogą być persnickety w ustawieniach innych niż domyślne. Nawet wtedy utknąłem w martwym punkcie z dynamicznym SQL-em i traciłem dużo ekspresji i mocy, jaką daje PowerShell.

Choć trochę niezręcznie, pomyślałem o zdefiniowaniu zmiennej na pierwszym etapie i przekazaniu jej następcom, ale badania przyniosły ten artykuł: Obsługa wielu etapów pracy (BOL)

Kroki zadania muszą być samodzielne. Oznacza to, że zadanie nie może przekazać wartości logicznych, danych lub wartości liczbowych między krokami zadania. Można jednak przekazywać wartości z jednego zadania zadania Transact-SQL do drugiego, używając tabel stałych lub globalnych tabel tymczasowych. Można przekazywać wartości z etapów zadania, które uruchamiają programy wykonywalne z jednego etapu zadania do drugiego, używając plików.

Nie mogę użyć typowych sztuczek, takich jak dobrze znane ustawienia pliku / zmiennych środowiskowych / rejestru, Foo.exeponieważ uniemożliwiłoby to jednoczesne wykonywanie w różnych instancjach.

TL; DR:

W jaki sposób w kroku Zadanie agenta SQL typu PowerShell, w jaki sposób można określić wystąpienie programu SQL Server, który uruchomił proces?


4
Czy PowerShell jest wymagany do tego, co robisz?
johndacostaa

Prawdziwym wymogiem byłoby posiadanie „agenta” w SQL, który można uruchomić, w celu uruchomienia procesu DOS z parametrem instancji wywołującej. PowerShell wydawał się najlepiej dopasowany, biorąc pod uwagę to, co nie działało powyżej. Przepraszam za spóźnioną odpowiedź, byłem na obozie harcerskim.
billinkc

Odpowiedzi:


9

Jeśli spojrzysz na SQL Server BOL, SQL Server Agent zapewnia zestaw „tokenów”, które zastąpi zarówno tekstem polecenia kroku zadania, jak i plikiem wyjściowym (później uniemożliwi działanie przycisku „widok” GUI). Te tokeny wydają się działać dla każdego rodzaju kroku oprócz T-SQL.

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

Tak więc, jeśli masz krok PowerShell SQL 2008, możesz go uruchomić:

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

Może być konieczne użycie MACH(nazwa komputera) i INST(tylko nazwa instancji), ponieważ w instancji domyślnej SRVR == MACH, ale w instancjach nazwanych SRVR == MACH\INST.


3

Z przykrością stwierdzam, że niewiele zrobiłem ze skryptami PowerShell wywoływanymi w SQL Server. Nie jestem też przy komputerze, z którym mógłbym teraz grać.

Uważam jednak, że zamiast używania kroku typu PowerShell, jeśli użyłeś CmdExec i po prostu wywołałeś swój skrypt, tak jak zrobiłbyś to z linii poleceń „powershell 'MyScript.ps1”, możesz przekazać parametr, który ma instancję, z której się uruchamiasz. Jak „Powershell” MyScript.ps1 „MyInstanceName”.

Więc na początku skryptu masz konfigurację param (), aby zaakceptować tę wartość MyInstanceName:


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

Kiedy zacząłeś od stwierdzenia, że ​​jeden krok musi wiedzieć, na którym wystąpieniu, aby skrypt PowerShell mógł poprawnie wywołać Foo.exe. Jednak później wspominasz o możliwości przekazania wartości do innych kroków. Jeśli jest to prawda, możesz rozważyć utworzenie małego pakietu SSIS, który wywołuje twój skrypt PowerShell i robi wszystko, czego potrzebujesz. Dzięki SSIS możesz ustawić zmienną globalną, z której mógłby korzystać cały pakiet.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.