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.exe
ale 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-Location
trasa 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-Sqlcmd
trasy 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-ChildItem
Get-Host
Get-Location
Get-Process
Get-PSDrive
Get-PSProvider
Get-Service
Get-TraceSource
Get-Variable
Get-Process
wyglą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ść, @@servername
ale gdybym wiedział, jakie połączenie uruchomić sqlcmd, nie musiałbym sprawdzać bazy danych;)
TSQL może prawdopodobnie działać, jeśli włączymy, xp_cmdshell
ale 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.exe
ponieważ 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?
Odpowiedzi:
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ć:
Może być konieczne użycie
MACH
(nazwa komputera) iINST
(tylko nazwa instancji), ponieważ w instancji domyślnejSRVR == MACH
, ale w instancjach nazwanychSRVR == MACH\INST
.źródło
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:
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.
źródło