Zdalne wykonywanie poleceń Powershell
Powershell to genialne narzędzie w rękach Administratora Windows: z poziomu konsoli lub za pomocą skryptów można wykonywać rozmaite czynności administracyjne (na przykład instalacja funkcji, zmiana IP, wysłanie maila itd. Itp.. ). Oczywistym wymogiem każdego dobrego narzędzia administracyjnego jest możliwość łączenia z komputerami zdalnymi. Choć niektóre CMDlet’y posiadają wbudowany przełącznik umożliwiający podanie nazwy maszyny zdalnej (np. Get-service), to wypada poznać metodę łączenia się do zdalnej konsoli PS i wykonywania tam dowolnych komend i skryptów. Czy jest to możliwe? Oczywiście że tak, i choć wymaga nieco więcej pracy na etapie „przygotowania” komputera, to później praca z konsolami zdalnymi jest równie przyjemna i efektywna co w PSEXEC.EXE we Wierszu Poleceń. I o tym właśnie będzie dzisiejszy artykuł.
Testowanie zdalnego połączenia w Powershell
Do testowania zdalnych sesji PS służy Cmdlet Test-WsMan:
Test-WsMan nazwa _komputera
Jeśli połączenie działa, i komputer docelowy pozwala na zdalne wykonywanie poleceń Powershell, to zobaczymy coś w stylu:
Jeśli łączenie zdalne nie jest skonfigurowane poprawnie, przywita nas złowrogi komunikat podobny do tego:
Konfigurujemy zdalne wykonywanie poleceń w Powershell
W środowisku domenowym, na komputerze łączącym się i docelowym użyjemy:
Enable-PSRemoting –Force
To polecenie uruchamia usługę WinRM (ustawia w tryb uruchamiania automatycznego) i tworzy odpowiednią regułę na Firewallu. Efekt będzie podobny do tego:
W środowisku bez domeny, oprócz powyższego, musimy wykonać dodatkowe kroki, a mianowicie definiujemy zaufane komputery – gwiazdka oznacza „wszystkie”. Zamiast niej możemy podać nazwę zaufanego hosta lub wymienić kilka po przecinku.
Set-Item wsman:\localhost\client\trustedhosts *
Następnie restartujemy usługę WinRM na komputerze z którego chcemy się łączyć i komputerze zdalnym na przykład poleceniem:
Restart-Service WinRM
Zdalne wykonywanie poleceń w Powershell: Invoke-command
Skoro już przygotowaliśmy komputer zdalny i komputer z którego chcemy się łączyć, możemy wykonać zdalne polecenie. Podstawowy CMDLet pozwalajacy wykonać zdalne polecenie to Invoke-Command.
Invoke-command tworzy nietrwałe sesje. Poszczególne komendy nie będą mogły przekazywać sobie danych. Jeśli jedna komenda przypisze coś do zmiennej, kolejne invoke-comamnd nie pozwoli nam tej zmiennej rozpoznać. Invoke command najlepiej nadaje się do prostych jednorazowych czynności. Składnia wygląda następująco:
Invoke-Command -ComputerName nazwa_komputera -scriptblock {komenda którą chcemy wykonać} -credential nazwa_uzytkownika
W tym momencie najczęściej zostaniemy poproszeni o podanie hasła dla użytkownika. Możemy podać konto lokalne, lub domenowe (podajemy nazwę użytkownika, a nie \\domena\użytkownik)
Możemy wykonać polecenia na wielu komputerach na raz podając ich nazwy po przecinku:
Invoke-Command -ComputerName computer_zdalny1, computer_zdalny 2, computer_zdalny 3 -scriptblock {polecenie }
Zdalne wykonywanie poleceń w Powershell: Enter-Pssession
Jeśli mamy w planie wykonywać więcej niż jedno polecenie, znacznie bardziej użyteczne będzie polecenie Enter-Pssession. Dzięki niemu, możemy zainicjować sesję która, pozwoli wpisywać poszczególne komendy na zdalnej konsoli tak, jakbyśmy robili to na swojej lokalnej konsoli. Podobnie jak w przypadku invoke-command, gdy powtórzymy połączenie z tym samym komputerem, sesja zostaje utworzona na nowo – dane z poprzednich połączeń (na przykład wartości zmiennych) nie będą zapamiętane.
Id Name ComputerName State ConfigurationName Availability
— —- ———— —– —————– ————
4 Session4 nazwa _komputera Opened Microsoft.PowerShell Available
Wyjście ze zdalnej konsoli i powrót do swojego lokalnego okienka możemy wykonać poleceniem:
Exit-pssession
Sesje stałe
Sesje stałe pozwalają zachowywać dane (na przykład przypisać coś do zmiennej) i widzieć te dane nawet gdy wyszliśmy z sesji i połączyliśmy się z inną sesją.
Nową sesję stałą nawiążemy poleceniem:
new-pssession -computername komputer_zdalny
Kilka nowych sesji na raz:
new-pssession -computername komputer_zdalny1, komputer_zdalny2
Listę obecnie aktywnych sesji podejrzymy poleceniem:
Get-pssession
Do sesji o konkretnym ID (na przykład 7) podepniemy się poleceniem:
enter-pssession -id 7
Sesję opuścimy poleceniem:
Exit-pssession
Sesję o konkretnym ID (np. 4) zamkniemy poleceniem:
remove-pssession -id 4
Możemy połączyć się z kilkoma komputerami na raz i wykonać na nich polecenie:
Invoke-command -session $sesja -scriptblock {jakieś polecenie}
Możemy wykonać szereg komend jedna po drugiej korzystając z jednorazowo nawiązanej sesji:
Invoke-Command -Session $sesja -ScriptBlock {$services = Get-Service}
Invoke-Command -Session $sesja -ScriptBlock {$services | Where-Object {$_.Status -eq „Started”}}
Remove-PSSession $sesja
Zdalne uruchamianie skryptów
Na deser jedna z bardziej przydatnych czynności, czyli uruchamianie skryptów na zdalnych maszynach:
Invoke-Command -ComputerName nazwa_komputera -FilePath C:\skrypty\tajemniczy_skrypt.ps1
To jak, komu z Was przyda się to pracy?
przyda się 🙂 .. bardzo fajny artykuł
Rewelacja. Nasuwa się pytanie: jak to zabezpieczyć? Jeśli mam komputer na którym uruchamiam usługę WinRM to mogę się łączyć z tym komputerem z dowolnego innego (chyba w ramach tej samej podsieci).
Jak ustawić np. hasło albo jakąś listę uprzywilejowanych hostów?
Przede wszystkim do wykonywania zdalnych poleceń trzeba mieć uprawnienia administratora na zdalnym hoście. Blokowanie dostępu per host możesz zrobić na firewallu.
Możesz dodawać hosty które są dozwolone za pomocą polecenia (to jest opcja dla zdalnych serwerów/komputerów które nie pracują pod kontrolą Active Directory, dla Active directory – nie będąc administratorem nie wykonasz zdalnie New-PSSesion):
winrm set winrm/config/client @{TrustedHosts=”NazwaTwojegoKomputera”}
Powinno być „Exit-PSSession” zamiast „Exit-Session”
Enable-PSRemoting –Force – Jak za pomocą cmd lub PowerShell odwrócić to polecenie na komputerze zdalnym?
Mateusz, racja, dzięki!
@s78: Disable-PSRemoting –Force
Znalazłem ten artykuł i bardzo się przydał, tylko utknąłem w jednym miejscu. Robię instalację drukarki sieciowej zdalnie. Napisałem sobie jeden pliczek, w którym Invoke odwołuje się do kolejnego pliku ps1. W tym drugim uruchamiam pnputil /add-driver C:\sterownik\oemsetup.inf /install. Wywala błąd składni pnputil. Jest jakaś alternatywa, która wrzuci mi plik sterownika do driver strore na zdalnym komputerze?