Invoke-Sqlcmd to polecenie modułu PowerShell umożliwiające wykonywanie zapytań SQL bezpośrednio ze skryptu.
Rola Invoke-Sqlcmd w skryptach PowerShell
Invoke-Sqlcmd jest poleceniem dostarczanym przez moduł SqlServer dla PowerShell. Służy do uruchamiania instrukcji języka Transact-SQL na wskazanej instancji Microsoft SQL Server oraz do wykonywania poleceń zgodnych ze składnią narzędzia sqlcmd. Polecenie może zwrócić wynik zapytania do potoku PowerShell, wyświetlić komunikaty serwera albo przerwać działanie skryptu, gdy wykonanie instrukcji zakończy się błędem. Nie jest to osobny silnik bazy danych ani zamiennik SQL Server; jest to interfejs administracyjny i automatyzacyjny, który otwiera połączenie z istniejącym serwerem SQL.
Najprostsze użycie określa instancję serwera i treść zapytania, na przykład Invoke-Sqlcmd -ServerInstance "localhost" -Database "Sklep" -Query "SELECT TOP (10) * FROM dbo.Produkty". Parametr -ServerInstance może wskazywać nazwę komputera, nazwę instancji nazwanej albo adres serwera wraz z portem, jeżeli konfiguracja połączenia tego wymaga. Parametr -Database ustala bazę, w której ma zostać wykonane zapytanie. Gdy baza nie zostanie podana, połączenie korzysta z bazy domyślnej przypisanej do użytego loginu lub z ustawień klienta.
Połączenie z SQL Server i wybór sposobu uwierzytelniania
Invoke-Sqlcmd może korzystać z uwierzytelniania Windows albo z uwierzytelniania SQL Server. Przy połączeniu opartym na koncie Windows uprawnienia wynikają z tożsamości procesu uruchamiającego PowerShell. Ma to znaczenie przy zadaniach wykonywanych ręcznie, przez Harmonogram zadań lub z innego konta systemowego, ponieważ ten sam skrypt może otrzymać inne uprawnienia w zależności od użytkownika. W przypadku uwierzytelniania SQL Server dane logowania można przekazać za pomocą parametru -Credential, zwykle jako obiekt PSCredential utworzony poleceniem Get-Credential.
Przykładowe zapytanie z poświadczeniami może wyglądać następująco: $cred = Get-Credential; Invoke-Sqlcmd -ServerInstance "SQL01" -Database "Raporty" -Credential $cred -Query "SELECT DB_NAME() AS Baza". W praktycznym skrypcie nie należy wpisywać hasła wprost w kodzie ani przekazywać go jako zwykłego tekstu. Zakres operacji nadal zależy od uprawnień loginu w SQL Server: możliwość nawiązania połączenia nie oznacza automatycznie prawa do odczytu każdej tabeli, wykonywania procedur czy modyfikowania schematu. Przy połączeniach szyfrowanych trzeba również uwzględnić ustawienia certyfikatu, szyfrowania i zgodności wersji modułu SqlServer z używanym środowiskiem PowerShell.
Zapytania, pliki wejściowe i obsługa wyników
Treść wykonywanego kodu można przekazać przez -Query albo wczytać z pliku za pomocą -InputFile. Drugie rozwiązanie ułatwia utrzymywanie dłuższych skryptów T-SQL, obejmujących deklaracje zmiennych, procedury, instrukcje warunkowe i kilka poleceń wykonywanych w określonej kolejności. Invoke-Sqlcmd obsługuje także zmienne sqlcmd przekazywane parametrem -Variable. Nie należy mylić ich ze zmiennymi PowerShell: zmienna używana w tekście zapytania musi być zapisana zgodnie z regułami sqlcmd, a jej wartość musi zostać przekazana w formacie rozpoznawanym przez używaną wersję modułu.
Wynik polecenia trafia do potoku, dzięki czemu można go filtrować, sortować lub zapisać do pliku. Przykład $wynik = Invoke-Sqlcmd -ServerInstance "SQL01" -Database "Raporty" -Query "SELECT name, create_date FROM sys.databases" zapisuje zwrócone wiersze w zmiennej PowerShell. Następnie można użyć właściwości kolumn, na przykład $wynik | Where-Object name -like "Test*". Przy eksporcie do CSV warto pamiętać, że obiekty zwracane przez cmdlet są wynikiem mapowania kolumn SQL na właściwości obiektów PowerShell, a komunikaty, ostrzeżenia i błędy mogą być obsługiwane odmiennie niż zwykłe wiersze danych.
W automatyzacji istotne są parametry kontrolujące reakcję na błędy, między innymi -AbortOnError oraz ustawienia dotyczące przekazywania błędów SQL do klienta. Sam fakt, że skrypt PowerShell się uruchomił, nie dowodzi poprawnego wykonania zapytania. Skrypt powinien sprawdzać błędy, kod zakończenia i oczekiwany rezultat, szczególnie gdy wykonuje instrukcje INSERT, UPDATE, DELETE albo zmiany struktury bazy. Przy operacjach modyfikujących dane należy również świadomie rozdzielić kolejne etapy transakcji i nie zakładać, że kilka niezależnych wywołań Invoke-Sqlcmd tworzy jedną transakcję.
Diagnostyka problemów z Invoke-Sqlcmd
Jeżeli polecenie nie działa, pierwszym krokiem jest sprawdzenie, czy moduł jest dostępny w bieżącej sesji: Get-Module -ListAvailable -Name SqlServer. Następnie można załadować go poleceniem Import-Module SqlServer i sprawdzić dokładną składnię lokalnej wersji przez Get-Help Invoke-Sqlcmd -Full. Różnice między wydaniami modułu mogą dotyczyć dostępnych parametrów, domyślnego zachowania połączenia, obsługi szyfrowania oraz współpracy z Windows PowerShell i PowerShell 7. Dlatego skrypt przeznaczony do uruchamiania na kilku komputerach powinien mieć jasno określoną wersję modułu i testować połączenie w środowisku docelowym.
Błąd połączenia może wynikać z nieprawidłowej nazwy instancji, niedostępnej usługi SQL Server, wyłączonego protokołu TCP/IP, blokady portu, braku uprawnień albo problemu z uwierzytelnianiem. Pomyślne połączenie nie gwarantuje natomiast poprawności samego T-SQL: zapytanie może odwoływać się do nieistniejącej tabeli, używać niewłaściwej bazy lub zwracać dane inne niż zakładane przez skrypt. Podczas diagnostyki warto najpierw wykonać nieszkodliwe zapytanie identyfikacyjne, na przykład SELECT @@SERVERNAME AS Serwer, DB_NAME() AS Baza, SUSER_SNAME() AS Login, a dopiero później analizować właściwą operację. W przypadku laptopa lub komputera używanego do pracy z narzędziami administracyjnymi sprawdza się również instalację modułu, wersję PowerShell, dostępność sieci oraz lokalne reguły zapory. Przy awariach klienta lub środowiska PowerShell można przeprowadzić kontrolę konfiguracji i odtworzyć poprawne działanie narzędzi potrzebnych do obsługi połączeń z SQL Server.