Zrestartuj komputer i kontynuuj skrypt
22.04.2011 | aktual.: 04.02.2012 18:00
Czasami bywa tak, że działania wykonywane przez nas wymagają restartu komputera. Systemy Windows Server z założenia nie powinny być restartowane jednak instalacja pewnych głównych modułów (Active Directory itp.) wymaga restartu. W przypadku maszyn klienckich może to być dla przykładu wpięcie hosta do domeny. A co jeśli chcemy napisać skrypt, który gdzieś w środku swojego działania będzie wymagał restartu komputera? Zadanie można wykonać w prosty sposób. 1. Dzielimy nasz skrypt na 2 pliki. Pierwszy skrypt kończy się restartem komputera a drugi wykonuje to, co powinniśmy wykonać po restarcie. 2. Prosimy Pana Windowsa o wykonanie drugiego skryptu podczas ponownego uruchamiania się systemu (dokładniej to podczas pierwszego logowania po restarcie) 3. Restartujemy
Jest taki klucz rejestru systemowego, z którego system pobiera wszystkie wpisy przy starcie systemu, wykonuje je i usuwa z tej listy. Pozwala to na jednorazowe uruchomienie aplikacji(często tak robią różne instalatory oprogramowania). Zwie się on:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
Naszym zadaniem więc jest dodanie do tego klucza wpisu, który odpali nam drugi skrypt.
Przy okazji trzeba poruszyć kwestię dostępu do rejestru w Powershell'u. Działa to na takiej samej zasadzie jak dostęp do partycji. Można przeglądać klucze tak samo jak katalogi , dzięki czemu zaciera się różnica pomiędzy zbiorami danych. Przykładowe komendy:
Aby wejść do rejestru systemu wykonujemy polecenie Set-Locatiom hklm: albo krócej cd hklm: Za pomocą tych komend możemy także wejść do poszczególnych węzłów cd Software Możemy wylistować zawartość węzła Get-Childitem Albo krócej dir Jeszcze krócej ls
Wracamy do meritum. Wpis dodajemy poleceniem:
New-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce' -Name "jakas_nazwa" -Value "sciezka\do\powershell.exe -File D:\dir\scriptname.ps1"
Mamy wszystko co potrzeba, piszemy zatem skrypt (kodujemy/kodzimy/skrytpujemy niepotrzebne skreślić) Trochę problemów sprawia przekazanie do wykonania bloku poleceń. Musi on być w nawiasach klamrowych oraz być poprzedzony ampersandem '&'
function Continue-AfterRestart{ param( [string]$Path, [ScriptBlock]$Scriptblock, [switch]$Restart ) try{ if($Path) { if(Test-Path $Path){ New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "ScriptContinuation" -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File $Path" | Out-Null } } elseif($Scriptblock){ New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "ScriptContinuation" -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command `"& `{$Scriptblock`}`"" | Out-Null } else{ Write-Host "An error occured. Please verify given parameters" Return } }catch{ Write-Host "An error occured. Please verify given parameters" Return } if($Restart){Restart-Computer} }
Przykład użycia
Continue-AfterRestart -Path "C:\Script\scrip2.ps1" -Restart Continue-AfterRestart -Scriptblock {Read-Host "Echo"}
Można zamiast hklm użyć hkcu. Skrypt także się wykona po restarcie, ale tylko wtedy, gdy zaloguje się ten sam użytkownik, który dodawał wpis.