Jak za pomocą apletu polecenia Test-Path sprawdzać dostępne zasoby?
Skrypciarze odpowiadają na Wasze pytania
Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy. |
Jak za pomocą apletu polecenia Test-Path sprawdzać dostępne zasoby?
Cześć, Skrypciarze! Ignorowanie błędów lub wyświetlanie ich użytkownikowi skryptu w oknie wydaje się niezbyt wydajne. Chodzi mi o to, że chyba lepiej byłoby ich w ogóle unikać? Jestem dopiero początkującym autorem skryptów i może czegoś nie rozumiem, ale czemu nie można pisać kodu, który po prostu nie generuje błędów?
-- KE
Cześć, TS! Czołem, tutaj skrypciarz Ed Wilson. Jedną z wad dnia pełnego spotkań jest fakt, że zaburza to harmonogram, rytm pracy i przepływ Mocy w biurze. Nie żeby spotkania były czymś z założenia niedobrym, ale mają one swój koszt, który trudno ująć po prostu w czasie pracy. Przed spotkaniem trzeba się do niego przygotować, a po spotkaniu — przepracować płynące z niego wnioski. Jest też koszt związany z koniecznością przestawienia się z pracy nad jakimś zadaniem i potem z powrotem. Cały wczorajszy dzień spędziłem na spotkaniach, a teraz moje biurko wydaje się obce, mój Zune HD wydaje się zaniedbany, a czajnik od herbaty gdzieś się zapodział. Pomyślałem, że najłatwiejszym sposobem powrotu do zwykłego rytmu pracy będzie sprawdzenie poczty przesłanej na adres scripter@microsoft.com.
Masz rację, KE. Zapobieganie błędom jest dużo skuteczniejsze niż radzenie sobie z nimi. Niekiedy jest to dość łatwe. Czasem jednak może być z tym problem. Istnieje wiele sytuacji, w których kilka prostych testów pozwoli zwiększyć niezawodność skryptu.
Jednym z moich ulubionych apletów poleceń jest Test-Path. Używam go przed działaniami na plikach i rejestrze. W powłoce programu Windows PowerShell można użyć apletu polecenia Test-Path, aby sprawdzić, czy plik działa. Ten aplet polecenia zwraca wartość logiczną, a wartość true oznacza, że pik istnieje. Jeśli plik nie istnieje, zostanie zwrócona wartość false. Widać to poniżej:
PS C:\> test-path -Path c:\fso\test.txt
True
PS C:\>
Chcąc opracować skrypt zapisujący dane w pliku test.txt, który znajduje się w folderze C:\fso, muszę odpowiednio wcześnie zdecydować się na wybór odpowiedniej opcji. Najprostszym rozwiązaniem byłoby usunięcie pliku, jeśli już on istnieje, i utworzenie nowego. Takie rozwiązanie nie zawsze jest jednak do przyjęcia. Być może korzystniej byłoby dołączyć dane do pliku lub utworzyć nowy plik o zbliżonej nazwie. Wybór odpowiedniego rozwiązania zależy od sytuacji i użytkownika, ale zawsze wymagane jest wykrycie, czy plik już istnieje. W tym celu właśnie można użyć apletu polecenia Test-Path.
A skoro pierwszym zadaniem jest określenie, czy plik istnieje, czy też nie, należy użyć instrukcji if. W praktyce chcemy tylko wiedzieć, czy plik jeszcze nie istnieje. Jeśli nie istnieje, możemy go utworzyć. Ze względu na to, że aplet polecenia Test-Path zwraca wartość true lub false w zależności od tego, czy plik istnieje, podczas gdy nam zależy na określeniu, czy plik nie istnieje, używamy operatora not, aby odwrócić logikę. Widać to poniżej:
if(!(Test-Path -Path $path))
Jeśli plik nie istnieje, chcemy go utworzyć przy użyciu apletu polecenia New-Item. Widać to poniżej:
new-item -Path $path -Value "new file" –itemtype file
Jeśli plik istnieje, zostanie włączona klauzula Else. Teraz musimy podjąć decyzję, co zrobić, jeśli plik istnieje. W naszym przykładzie dołączamy dane do pliku tekstowego, używając apletu polecenia Add-Content. Widać to poniżej:
Add-Content -Path $path -Value "`r`n Dodatkowa zawartość"
CheckForFileAndAddContent.ps1
$path = "c:\fso\test.txt"
if(!(Test-Path -Path $path))
{
new-item -Path $path -Value "new file" –itemtype file
}
else
{
Add-Content -Path $path -Value "`r`n Additional content"
}
Każde uruchomienie skryptu powoduje dodanie słów „Dodatkowa zawartość” u dołu pliku Test.txt. Jest to ukazane poniżej.
Analogiczną technikę należy stosować podczas pracy z rejestrem. Jak widać w skrypcie CheckForRegistryKeyAndUpdate.ps1, nie trzeba używać wykrzyknika (!) jako operatora not. Można użyć formy –not. Dzięki temu skrypt jest bardziej czytelny. Ja jednak rzadko korzystam z takiego rozwiązania, ponieważ gdy tylko mogę, unikam konieczności wpisywania z klawiatury. Podczas pracy z rejestrem należy pamiętać, że aplet polecenia Test-Path nie zgłasza prawidłowych danych dotyczących wpisów rejestru (właściwości klucza rejestru). Zawsze zwracana jest wartość false. Jednak dane dotyczące samych kluczy rejestru są zgłaszane prawidłowo. Odpowiedni fragment kodu widać poniżej (użyte ścieżki warto porównać ze ścieżkami widocznymi w kolejnym obrazie w niniejszym artykule):
PS C:\> Test-Path -Path HKCU:\Software\ScriptingGuys\Test\update
False
PS C:\> Test-Path -Path HKCU:\Software\ScriptingGuys\Test
True
PS C:\>
Używamy apletu polecenia Test-Path w celu sprawdzenia ścieżki do klucza rejestru, a jeśli taka ścieżka nie istnieje, tworzymy zarówno klucz rejestru, jak i właściwość klucza rejestru. Widać to poniżej:
If(-not(Test-Path -Path $path))
{
New-Item -Path $path -Force
New-ItemProperty -Path $path -Name Update -Value "Zaktualizowano"
}
Jeśli klucz rejestru istnieje, nie możemy określić, czy istnieje właściwość klucza rejestru. Dlatego też używamy apletu polecenia Set-ItemProperty. Spowoduje to utworzenie właściwości klucza rejestru lub zaktualizowanie klucza, jeśli już on istnieje, co powinno wystarczyć na nasze potrzeby. Polecenie to widać poniżej:
Set-ItemProperty -Path $path -Name Update -Value "Nowa aktualizacja"
Pełen skrypt CheckForRegistryKeyAndUpdate.ps1 widać poniżej.
CheckForRegistryKeyAndUpdate.ps1
$path = "HKCU:\Software\ScriptingGuys\Test"
If(-not(Test-Path -Path $path))
{
New-Item -Path $path -Force
New-ItemProperty -Path $path -Name Update -Value "Zaktualizowano"
}
Else
{
Set-ItemProperty -Path $path -Name Update -Value "Nowa aktualizacja"
}
Po uruchomieniu skryptu wyświetlane są wpisy rejestru widoczne na poniższym obrazie.
Dużą zaletą apletu polecenia Test-Path jest to, że współdziała on z innymi dostawcami programu Windows PowerShell. Można np. przed utworzeniem nowego aliasu użyć apletu polecenia Test-Path, by sprawdzić, czy alias już istnieje. Widać to poniżej:
PS C:\> Test-Path -Path alias:\gc
True
PS C:\>
Kodu tego można użyć w skrypcie, tak jak to widać w skrypcie CheckForAliasAndCreate.ps1. Jak widać, skrypt ten działa w sposób zbliżony do innych omówionych dziś skryptów.
CheckForAliasAndCreate.ps1
$path = "Alias:\gc"
if(!(Test-Path -Path $path))
{
New-Alias -Name gc -Value Get-Credential
}
else
{
"Alias $path już istnieje"
}
Jeśli chcemy sprawdzić istnienie funkcji, należy użyć dysku funkcji z apletem polecenia Test-Path. Widać to poniżej:
PS C:\> Test-Path -Path Function:\TabExpansion
True
PS C:\>
Za pomocą apletu polecenia Test-Path można sprawdzić istnienie zmiennych, dokonując inspekcji odpowiedniego dysku. Widać to poniżej:
PS C:\> Test-Path -Path Variable:\PSBoundParameters
True
PS C:\>
Działa to również w wypadku dysku środowiskowego, tak jak to widać poniżej:
PS C:\> Test-Path -Path Env:\ALLUSERSPROFILETruePS C:\>
PS C:\> Test-Path -Path Env:\ALLUSERSPROFILE
True
PS C:\>
Jeśli chcemy sprawdzić, czy dany użytkownik ma określony certyfikat w magazynie certyfikatów, możemy użyć dysku certyfikatu. Widać to poniżej:
PS C:\> Test-Path -Path cert:\CurrentUser\AuthRoot\C31EB1E720E33C8102BADC37D44DE5D4674752A8
True
PS C:\>
Jak widać, używanie apletu polecenia Test-Path z dyskiem certyfikatu jest nieco trudniejsze, ponieważ trzeba podać odcisk palca certyfikatu.
I to już wszystkie sekrety sprawdzania zasobów przy użyciu apletu polecenia Test-Path przed podjęciem działania. Zapraszamy jutro na kolejny artykuł z serii poświęconej obsłudze błędów.
Skrypciarze Ed Wilson i Craig Liebendorfer
Do początku strony |