Centrum skryptów - Systemy operacyjne

Jak skopiować dwa pliki do każdego folderu udostępnionego znajdującego się na komputerze?

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.

Jak skopiować dwa pliki do każdego folderu udostępnionego znajdującego się na komputerze?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak skopiować dwa pliki do każdego folderu udostępnionego znajdującego się na komputerze?

-- DL

Cześć Skrypciarze! Odpowiedź

Cześć, DL. Ciężki dzień się dla mnie dziś zapowiada. Nie dlatego, żebym miał jakoś strasznie dużo pracy, w końcu zadane pytanie nie jest bardzo skomplikowane, ale wielką trudność sprawia mi siedzenie przy biurku w pozycji wyprostowanej i to w dodatku z otwartymi oczami. Nie wiem , jak ja dziś wytrzymam te osiem godzin. Miejmy nadzieję, że pisanie skryptu kopiującego pliki do każdego folderu udostępnionego znajdującego się na komputerze trochę mnie rozrusza. Jeśli nie, będę musiał zastosować strategię „na długopis”. Nie wiecie, co się za tym kryje? No dobrze, powiem wam. Ale nie mówcie o tym nikomu z szefostwa, bo nikt się więcej na to nie nabierze. Otóż strategia „na długopis” to strategia wypoczywania w godzinach pracy polegająca na tym, że bierzemy w rękę długopis i schylamy się, tak jakbyśmy go właśnie podnosili. Kładziemy wygodnie głowę obok klawiatury, zamykamy oczy i odpływamy. W razie, gdyby ktoś nas nakrył, podnosimy się żwawo trzymając w ręce długopis i mówimy, że przecież podnosiliśmy długopis. Genialne.

Tymczasem skupię się na Skrypciarz kopiującym pliki, bo widzę, że jakiś inny Skrypciarz postanowił zastosować tę strategię, a dwóch Skrypciarzy śpiących „na długopis” mogłoby wyglądać podejrzanie. Oto skrypt:

Const OverwriteExisting = TRUE



strComputer = "atl-fs-01"



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")



Set colItems = objWMIService.ExecQuery("Select * From Win32_Share Where Type = 0")



Set objFSO = CreateObject("Scripting.FileSystemObject")



For Each objItem in colItems

    strFolderName = objItem.Name

    If InStr(strFolderName, "$") = 0 Then

        strPath = "\\" & strComputer & "\" & strFolderName & "\"

        objFSO.CopyFile "C:\Scripts\Test.txt", strPath, OverwriteExisting

        objFSO.CopyFile "C:\Scripts\Test2.txt", strPath, OverwriteExisting

    End If

Next

No to zabierzmy się za wyjaśnienia dotyczące skryptu. Zaczynamy od utworzenia stałej o nazwie OverwriteExisting i nadania jej wartości True; dzięki temu skrypt będzie wiedział, ze ma nadpisać każde istniejące wystąpienie naszych dwóch plików w razie, gdyby znalazł je w którymś folderze udostępnionym. Następnie stosujemy poniższy fragment kodu w celu połączenia się z usługą WMI na docelowym komputerze (czyli na tym, na który chcemy skopiować pliki):

strComputer = "atl-fs-01"



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Po połączeniu się z usługą WMI pobieramy listę wszystkich folderów udostępnionych znajdujących się na komputerze. Do tego posłuży nam poniższy wiersz kodu:

Set colItems = objWMIService.ExecQuery("Select * From Win32_Share Where Type = 0")

Jak widzimy, wybieramy wszystkie wystąpienia klasy Win32_Share, w przypadku których właściwość Type ma wartość 0. Dlaczego klauzula Where oraz klauzula Type mają wartość 0? Jak się okazuje, klasa Win32_Share obejmuje więcej niż tylko foldery udostępnione; obejmuje także drukarki udostępnione, urządzenia udostępnione, takie jak napędy CD_ROM oraz udziały administracyjne (takie jak C$). Z uwagi na fakt, iż nas interesują tylko foldery udostępnione, ograniczamy pobierane dane do elementów udostępnionych o właściwości Type równej 0.

A to oczywiście nic innego, jak tylko same foldery udostępnione.

Po wykonaniu kwerendy otrzymujemy kolekcję folderów udostępnionych na zdalnym komputerze. Kiedy już mamy tę kolekcję, uruchamiamy pętlę For Each, która przejdzie przez wszystkie foldery udostępnione. A co jest pierwszą rzeczą, jaką robimy wewnątrz tej pętli? To proste: pobieramy wartość właściwości Name (czyli nazwę udziału) i zachowujemy ją w zmiennej o nazwie strFolderName.

Następna część naszego skryptu jest opcjonalna, ale dorzucamy ją jako bonus. Często się zdarza, że komputery (w szczególności serwery) mają ukryte udziały (takie, które nie są od razu widoczne w sieci). Ponieważ zazwyczaj użytkownicy nie korzystają z tych udziałów, możemy nie mieć zamiaru kopiować plików do ukrytych folderów. Ale jak zidentyfikować ukryte i widoczne udziały? Co ciekawe, nie ma właściwości odróżniającej udział ukryty od widocznego.

Jednak ukryte udziały zawsze mają nazwę kończącą się znakiem dolara (na przykład Public$). Za pomocą naszego następnego wiersza kodu stosujemy funkcję InStr w celu określenia, czy znak $ znajduje się w nazwie folderu:

If InStr(strFolderName, "$") = 0 Then

Jeżeli nazwa zawiera znak $, funkcja InStr przekaże nam wartość większą od 0 (technicznie rzecz biorąc, przekaże nam pozycję znaku w nazwie folderu w której ten znak wystąpił). Innymi słowy, jeżeli InStr przekaże nam coś innego niż 0, przyjmiemy, że mamy do czynienia z udziałem ukrytym i nie skopiujemy nic do tego folderu.

Z drugiej strony, jeżeli InStr przekaże nam 0, przyjmiemy, że nie mamy do czynienia z udziałem ukrytym. Dlatego też następna rzeczą jaką zrobimy będzie zastosowanie poniższego wiersza kodu:

strPath = "\\" & strComputer & "\" & strFolderName & "\"

Łącząc następujące elementy, tworzymy teraz ścieżkę dostępu UNC do folderu udostępnionego:

  • \\
  • atl-fs-01 (nazwa zdalnego komputera zachowana w zmiennej o nazwie strComputer)
  • \
  • public (nazwa folderu udostępnionego zachowana w zmiennej o nazwie strFolderName)
  • \

Po złożeniu ich razem otrzymujemy ścieżkę podobną do poniższej:

\\atl-fs-01\public\
Uwaga. Nie należy pozbywać się znaku \ znajdującego się na końcu ścieżki. W takim wypadku skrypt nie zadziała.

Kiedy już mamy ścieżkę UNC, kopiujemy nasze dwa pliki do tego folderu udostępnionego. Jak to robimy? Oto sposób skopiowania pierwszego pliku:

objFSO.CopyFile "C:\Scripts\Test.txt", strPath, OverwriteExisting

jak widać, wywołujemy tylko metodę CopyFile i przekazujemy jej trzy parametry:

  • C:\Scripts\Test.txt, ścieżkę dostępu pliku znajdującego się na lokalnym komputerze. Czy można skopiować plik z jednego zdalnego komputera na drugi? Tak, ale to trochę skomplikowane. Jeżeli jest taka potrzeba, najlepiej jest zmapować dysk do zdalnego komputera i zastosować tę ścieżkę pliku. Na przykład, jeżeli mapujemy dysk F: do folderu Scripts na \\atl-ps-05, kopiujemy po prostu plik używając ścieżki F:\Scripts\Test.txt.
  • strPath, zmienna zawierająca ścieżkę UNC do folderu udostępnionego na zdalnym komputerze.
  • OverwriteExisting, stała zdefiniowana na początku skryptu

Następnie, stosujemy podobne wywołanie metody CopyFile w celu skopiowania drugiego pliku, potem kontynuujemy działanie pętli i powtarzamy proces dla następnego folderu z kolekcji.

Jedyną rzeczą, na która należy tutaj uważać, są uprawnienia do udziałów: jeżeli nie mamy uprawnień do zmodyfikowania folderu udostępnionego poprzez sieć, skrypt nie zadziała. Chociaż teoretycznie możliwe jest określenie, a nawet zmodyfikowanie uprawnień do udziałów za pomocą skryptu, ale cóż, to wykracza poza to, co możemy zrobić na łamach tej rubryki. (i szczerze mówiąc jest to o wiele bardziej skomplikowane, niż powinno. Jeżeli chodzi o deskryptory zabezpieczeń, zalecamy pominięcie skryptów i zastosowanie narzędzia wiersza polecenie, takiego jak Cacls.exe lub Xcacls.exe.)

I to powinno załatwić całą sprawę.

Wygląda na to, że trochę się rozruszałem i wykorzystanie strategii „na długopis” zachowam na jakąś inną okazję. Nie należy stosować jej zbyt często, np. codziennie, gdyż mogłoby to wzbudzić podejrzenia.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne