Centrum skryptów - Systemy operacyjne

Co zrobić, aby skopiować wybrany plik na kilka komputerów?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

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.

Co zrobić, aby skopiować wybrany plik na kilka komputerów?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Przeprowadzam regularne aktualizacje pliku, który musi zostać skopiowany na wszystkie z moich serwerów. Czy można napisać skrypt, który będzie kopiował wybrany plik do identycznego folderu na kilku komputerach?

-- JU

Cześć Skrypciarze! Odpowiedź

Cześć, JU. Kiedy piszemy ten artykuł, jest poniedziałek, 14 maja. Oznacza to, że wczoraj w USA był Dzień Matki. Wiąże się z tym pewna ciekawostka – otóż Anna Jarvis, osoba która wymyśliła i wypromowała Dzień Matki, już po kilku latach rozpoczęła odwrotną kampanię, w której walczyła z tym świętem. Dlaczego? Otóż była niezmiernie rozczarowana, że Dzień Matki uległ komercjalizacji i w ciągu zaledwie paru lat stał się tylko jeszcze jedną okazją do sprzedaży kwiatków i pocztówek. Skrypciarze nie zgadzają się z tym podejściem – nie mamy nic przeciwko komercjalizacji. Nie oszukujmy się – poniższy skrypt, mogący skopiować wybrany plik na kilka komputerów, także napisaliśmy wyłącznie dla pieniędzy:

Const ForReading = 1

Const OverwriteExisting = TRUE



Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Computers.txt")



Do Until objFile.AtEndOfStream

    strComputer = objFile.ReadLine

    strRemoteFile = "\\" & strComputer & "\C$\Scripts\Test.doc"

    objFSO.CopyFile "C:\Scripts\Test.doc", strRemoteFile, OverwriteExisting

Loop

Zanim przejdziemy dalej, zwróćmy uwagę, że kwestię kopiowania plików na kilka komputerów można rozwiązać na wiele sposobów. Zdecydowaliśmy się na podejście, w którym odczytujemy nazwy komputerów z pliku tekstowego. Można także wybierać je z okna dialogowego, podawać jako argumenty wiersza poleceń, a nawet skopiować nazwy wszystkich komputerów w wybranej jednostce OU.

Zakładamy, że dysponujemy prostym plikiem tekstowym (C:\Scripts\Computers.txt), zawierającym nazwy wszystkich komputerów, na które chcemy skopiować plik, o którym była mowa wcześniej. Plik z nazwami komputerów będzie wyglądał mniej-więcej tak:

atl-fs-01

atl-fs-02

atl-fs-03

atl-fs-04

atl-fs-05

Nasz plan polega na otworzeniu pliku tekstowego, odczytaniu nazw komputerów i skopiowaniu interesującego nas pliku na każdy z komputerów.

Zaczynamy od zdefiniowania pary stałych – ForReading i OverWriteExisting. Stała ForReading będzie nam potrzebna, by otworzyć plik tekstowy do odczytu; stałej OverWriteExisting użyjemy do zastąpienia starszej wersji pliku docelowego, która być może znajduje się już na niektórych z komputerów zdalnych.

Uwaga. Tak, przyznajemy, że kopiowanie plików wymaga zwrócenia uwagi na wiele niuansów. Aby się w nich lepiej rozeznać, można przeczytać odpowiedni adtykuł Sesame Script (j.ang.).

Po zdefiniowaniu stałych tworzymy wystąpienie obiektu Scripting.FileSystemObject, a następnie używamy metody OpenTextFile do otwarcia pliku C:\Scripts\Computers.txt (tzn. pliku zawierającego listę nazw komputerów):

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Computers.txt")

Po otwarciu pliku tekstowego możemy go odczytać, linijka po linijce. W tym celu uruchamiamy pętlę Do Until, która będzie działać, dopóki nie dojdzie do końca pliku (tzn. dopóki właściwość AtEndOfStream nie osiągnie wartości True):

Do Until objFile.AtEndOfStream

Wewnątrz pętli najpierw używamy metody ReadLine do odczytania pierwszego wiersza pliku (czyli nazwy pierwszego komputera), a następnie zapisujemy tę wartość w zmiennej o nazwie strComputer:

strComputer = objFile.ReadLine

Teraz zaczynają się pojawiać problemy. Jak wiedzą stali czytelnicy artykułów Cześć, Skrypciarze, zawsze zwracamy uwagę, że FileSystemObject powstał przede wszystkim z myślą o pracy na komputerze lokalnym. Tak właśnie jest; nie znaczy to jednak, że praca zdalna jest niemożliwa – FileSystemObject może obsługiwać ścieżki UNC. Oznacza to, że możemy skopiować plik do folderu udostępnionego na komputerze zdalnym (np \\atl-fs-01\Public\Shared_Files). Oznacza to także, że możemy skopiować plik do dowolnego folderu na komputerze zdalnym, o ile użyjemy udziału administracyjnego (np. \\atl-fs-01\C$\Scripts). Tak właśnie zrobimy w naszym przykładzie.

Uwaga. Czy to oznacza, że skrypt przestanie działać, jeśli odłączymy udział administracyjny komputera? Owszem. Tak więc zadanie to bez poważniejszych modyfikacji można wykonać jedynie przy użyciu udziału administracyjnego lub folderu udostępnionego.

Za chwilę albo dwie użyjemy metody CopyFile do skopiowania pliku docelowego na pierwszy komputer wymieniony w pliku Computers.txt. Najpierw jednak potrzebujemy dwóch informacji – kompletnej ścieżki dostępu do pliku, który chcemy skopiować, oraz kompletnej (tzn. zawierającej także nazwę pliku) ścieżki do lokalizacji docelowej. Określenie ścieżki do pliku, który będziemy kopiować, jest łatwe; w końcu mamy go na komputerze lokalnym (w naszym przykładzie: C:\Scripts\Test.doc).

Określenie lokalizacji na komputerze zdalnym jest nieco trudniejsze; musimy użyć ścieżki UNC, a jej najważniejszy element – nazwa komputera – będzie się zmieniał wraz z każdym przejściem pętli.

Nie obawiajcie się; za drobną dopłatą Skrypciarze opracowali taki wiersz kodu, który się tym zajmie:

strRemoteFile = "\\" & strComputer & "\C$\Scripts\Test.doc"

Tworzymy tu ścieżkę UNC, podstawiając w odpowiednie miejsce wartość zmiennej strComputer (czyli nazwę komputera). Kiedy połączymy już poszczególne elementy, otrzymamy taką wartość, którą będziemy mogli przypisać zmiennej strRemoteFile:

\\atl-fs-01\C$\Scripts\Test.doc

I wiecie co? Tak się składa, że to jest właśnie ścieżka UNC, której potrzebujemy, by skopiować plik na komputer atl-fs-01. Użyjemy do tego poniższego wiersza kodu:

objFSO.CopyFile "C:\Scripts\Test.doc", strRemoteFile, OverwriteExisting

W wierszu tym nareszcie wywołujemy metodę CopyFile, podając jej trzy parametry:

  • Ścieżkę dostępu do pliku lokalnego (C:\Scripts\Test.doc) – tego, który chcemy skopiować.
  • Ścieżkę UNC do komputera zdalnego (zapisaną w zmiennej strRemoteFile).
  • Stałą OverWriteExisting (na wypadek, gdyby w folderze C:\Scripts na komputerze atl-fs-01 już istniał plik Test.doc.

Kopiujemy plik, a potem ponownie wykonujemy pętlę – i tal dalej, dopóki nie dojdziemy do końca listy. Teraz już możemy wypisać czek.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne