Centrum skryptów - Systemy operacyjne

Jak raportować informacje o przydziale dysku dla zalogowanego użytkownika?

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 raportować informacje o przydziale dysku dla zalogowanego użytkownika?

Cześć Skrypciarze! Pytanie

Cześć Skrypciarze! Jak za pomocą skryptu logowania raportować informacje o przydziale dysku (takich jak pojemność wykorzystana oraz pojemność pozostała) dla zalogowanego użytkownika?

-- HY

Cześć Skrypciarze! Odpowiedź

Cześć, HY. Wiecie, dzisiaj szykuje się kolejny wyczerpujący dzień. Przykładowo, w czasie kiedy piszę ten artykuł jestem także zajęty delektowaniem się cappuccino w ogródku kafejki przy Piazza San Marco w Wenecji, przeglądając włoską gazetę i czekając na aż cała rodzina rozpocznie zwiedzanie bazyliki Świętego Marka. Stamtąd udadzą się pewnie do jakiegoś pałacu. Potem pewnie zjem jakiegoś gelato, przejdę się wzdłuż Kanału Grande i zjem jeszcze trochę gelato. To na pewno będzie ciężki dzień. Kelner, un altro cappuccino, per favore.

Uwaga! Jak zwykle myślicie sobie pewnie, jak ci Skrypciarze ciężko pracują. Dlatego też ja, piszący te słowa Skrypciarz, naprawdę zasłużyłem na takie wakacje, no sami przyznajcie. Korzystam więc ile tylko się da.

Jasny jest chyba fakt, że nie jest mi łatwo pisać artykuły do tej rubryki. Ale to nic: w końcu Wenecja to pułapka dla turystów, co do tego nie ma wątpliwości. A to oznacza, że na każdej ulicy są uliczni sprzedawcy, sprzedający absolutnie wszystko, nawet skrypt raportujący informacje o przydziałach dyskowych dla zalogowanego użytkownika:

strComputer = "."



Set objNetwork = CreateObject("Wscript.Network")

strUser = objNetwork.UserName

strDomain = objNetwork.UserDomain



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



Set colDisks = objWMIService.ExecQuery _

    ("Select * from Win32_QuotaSetting Where State = 1")



For Each objDisk in colDisks

    strDrive = objDisk.VolumePath

    strDrive = Replace(strDrive, "\", "")



    Set objQuota = objWMIService.Get _

        ("Win32_DiskQuota.QuotaVolume='Win32_LogicalDisk.DeviceID=" & chr(34) & strDrive & chr(34) & "'," & _

            "User='Win32_Account.Domain=" & chr(34) & strDomain & chr(34) & _

                ",Name=" & chr(34) & strUser & chr(34) & "'")



    Wscript.Echo "Drive: " & objDisk.VolumePath

    Wscript.Echo "Disk Space Used: " & Int(objQuota.DiskSpaceUsed / 1048576) & " megabytes"

    Wscript.Echo "Quota Limit: " & Int(objQuota.Limit  / 1048576) & " megabytes"

    Wscript.Echo "Disk Space Remaining: " & Int((objQuota.Limit - objQuota.DiskSpaceUsed) / 1048576) & _

        " megabytes"

    Wscript.Echo

Next

Zanim posuniemy się dalej muszę zauważyć, że po włosku mówię jeszcze gorzej niż po angielsku i dlatego nie jest mi łatwo tłumaczyć wyjaśnienia dotyczące skryptu. Żaden ze sprzedawców nie mówi po angielsku i nikt nie może mi w tej materii pomóc. Tak czy siak, poradzę sobie, bez obaw.

Uwaga! Udało mi się dowiedzieć, że ten skrypt działa tylko w Windows XP i późniejszych wersjach systemu Windows. Jeżeli istnieje konieczność wykonania tego zadania na komputerze z zainstalowanym oprogramowaniem Windows 2000, polecam zajrzeć do przewodnika Microsoft Windows 200 Scripting Guide (j.ang.) i samemu postarać się znaleźć rozwiązanie tego problemu. Jeżeli się nie uda, dajcie znać, być może zajmiemy się tym tematem w przyszłości.

Jeżeli natomiast chodzi o system Windows Vista, skrypt zadziała jedynie po uruchomieniu z podwyższonymi uprawnieniami. To oznacza, że należy uruchomić skrypt z wiersza polecenia, jednak na początku trzeba kliknąć prawym klawiszem myszy i wybrać opcję Uruchom jako administrator.

Na początek tworzymy wystąpienie obiektu Wscript.Network, a następnie stosujemy poniższe dwa wiersze kodu w celu pobrania wartości właściwości UserName oraz UserDomain i zachowanie ich odpowiednio w zmiennych strUser oraz strDomain:

strUser = objNetwork.UserName

strDomain = objNetwork.UserDomain

Jak pewnie wiecie, zmienna UserNAme daje nam nazwę logowanie użytkownika (np. kenmyer), natomiast UserDomain przekazuje nam nazwę domeny tego użytkownika (np. fabrikam). Dobrze się składa, ponieważ podczas próby uzyskania przydziału dysku będziemy potrzebowali zarówno nazwy użytkownika, jak i nazwy odpowiedniej domeny.

Pobrawszy nazwę użytkownika oraz nazwę domeny, łączymy się z usługą WMI na lokalnym komputerze. Czy możemy zastosować skrypt także w przypadku zdalnego komputera? Pewnie tak, ale trzeba by zapytać sprzedawcy, który mi wcisnął ten skrypt.

Sprzedawca powiedział: Certamente (oczywiście). Jeżeli potrzebujemy informacji na temat przydziału dysku użytkownika zalogowanego na zdalnym komputerze, po prostu przypisujemy nazwę tego komputera do zmiennej strComputer:

strComputer = "atl-fs-01"

Musimy jednak mieć jedną rzecz na uwadze, a mianowicie: zdalne zastosowanie usługi WMI wymaga uprawnień lokalnego administratora na zdalnym komputerze. Z uwagi na fakt, że ma to być skrypt logowania, zalogowany użytkownik (np. Ken Meyer) musi być lokalnym administratorem na każdym zdalnym komputerze, z którym łączy się skrypt. Tak więc uzyskanie informacji na temat przydziału dysku na zdalnym komputerze być może będzie możliwe, a być może nie.

Teraz przechodzimy do następującego wiersza kodu:

Set colDisks = objWMIService.ExecQuery _

    ("Select * From Win32_QuotaSetting Where State = 1")

Naszym celem jest sprawdzenie informacji dotyczących przydziałów dysku dla wszystkich dysków na lokalnym komputerze. Jasne, że przydział dysku może nie być uruchomiony na wszystkich dyskach; jeżeli tak jest, skrypt przekaże nam mylne informacje. (Załóżmy na przykład, że na dysku nie ma włączonego przydziału dysku. W takim przypadku skrypt powie nam, że użytkownik ma 0 megabajtów powierzchni przydziału. Dzieje się tak dlatego, że technicznie rzecz biorąc brak przydziałów oznacza, że nikt nie ma powierzchni przydziału.) Z tego powodu dodaliśmy zdanie Where - WhereState = 1; dzięki czemu otrzymamy jedynie informacje o napędach dla których przydział jest włączony.

Uwaga! Jeżeli mamy zapotrzebowanie na większą ilość informacji na temat przydziału dysku, zalecam zajrzeć do tego artykułu (j.ang.) w sekcji Centrum Skryptów dotyczącej Windows Server 2003.

Teraz uruchamiamy pętlę For Each, która przejdzie przez wszystkie dyski przekazane przez naszą kwerendę WQL. (Czyli wszystkie dyski, w przypadku których przydział dysku został włączony.) Co robimy najpierw wewnątrz tej pętli? Stosujemy poniższe dwa wiersze kodu:

strDrive = objDisk.VolumePath

strDrive = Replace(strDrive, "\", "")

Dlaczego właśnie te dwa wiersze kodu? Cóż, na początek chcemy uzyskać literę dysku, co pozwoli nam pobrać informacje o przydziale dysku dla zalogowanego użytkownika. (To ma sens, w końcu jeżeli nie będziemy znali litery dysku, to skąd skrypt ma wiedzieć, za który dysk się zabrać?) Tak się składa, że właściwość VolumePath zawiera literę dysku, zatem pobieramy wartość tej właściwości i zachowujemy ją w zmiennej o nazwie strDrive.

Niestety tutaj pojawia się mały problem. Właściwość VolumePath zachowuje litery dysku w sposób następujący: C:\. Wszystko pięknie, tylko, że klasa Win32_DiskQuota musi pracować z literami dysku w tym formacie: C: (bez znaku \). Dlatego też nasz drugi wiersz kodu wykorzystuje funkcję Replace w celu zastąpienia wystąpień znaku \ 'niczym':

strDrive = Replace(strDrive, "\", "")

Następnie… no cóż, wpadamy na coś takiego:

Set objQuota = objWMIService.Get _

    ("Win32_DiskQuota.QuotaVolume='Win32_LogicalDisk.DeviceID=" & chr(34) & strDrive & chr(34) & "'," & _

        "User='Win32_Account.Domain=" & chr(34) & strDomain & chr(34) & _

            ",Name=" & chr(34) & strUser & chr(34) & "'")

Macie rację: to może być najbardziej straszna kwerenda WQL, jaką kiedykolwiek utworzono. (Co oni sobie myślą, ci sprzedawcy!!) Nie mam zamiaru wyjaśniać dzisiaj szczegółowo tej kwerendy; więcej informacji znajduje się w naszym artykule (j.ang.) dotyczącym przydziału dysku. Na teraz musi nam wystarczyć uwaga, że łączy nas ona z pierwszym napędem dysku znajdującym się w kolekcji; dokładniej rzecz biorąc, do wystąpienia klasy Win32_DiskQuota, w której, tak się składa, właściwość QuotaVolume jest wystąpieniem klasy Win32_LogicalDisk, w której z kolei właściwość DeviceID ma wartość równą wartości zmiennej strDrive.

Chwila, teraz to muszę złapać oddech.

No dobra, już. Następnie, po połączeniu z odpowiednią klasą Win32_DiskQuota pobieramy informacje na temat przydziału dla wystąpienia klasy Win32_Account, w której właściwość Domain ma wartość domeny użytkownika, a właściwość Name ma wartość nazwy użytkownika.

Podsumowując, załóżmy, że pierwszy napęd dysku w naszej kolekcji dysków z włączonym przydziałem to dysk C; załóżmy także, że zalogowany użytkownik to fabrikam\kenmyer. W takim przypadku, otrzymamy informacje o przydziale dysku dla fabrikam\kenmyer dla dysku C na lokalnym komputerze. Teraz zastosujemy poniższe wiersze kodu w celu wywołania echa tej informacji:

Wscript.Echo "Drive: " & objDisk.VolumePath

Wscript.Echo "Disk Space Used: " & Int(objQuota.DiskSpaceUsed / 1048576) & " megabytes"

Wscript.Echo "Quota Limit: " & Int(objQuota.Limit  / 1048576) & " megabytes"

Wscript.Echo "Disk Space Remaining: " & Int((objQuota.Limit - objQuota.DiskSpaceUsed) / 1048576) & _

        " megabytes"

Zdaję sobie sprawę, że niektóre z tych wierszy również wyglądają odstraszająco. Jest tak dlatego, że przed wywołaniem echa naszych wartości właściwości stosujemy trochę matematyki i trochę formatowania. Domyślnie, informacje dotyczące przydziału dysku są przekazywane jako bajty. W ten sposób dowiemy się, że Ken Meyer ma 543271897 bajtów przestrzeni dysku. Co to ma znaczyć? Nie mam pojęcia: dlatego też bierzemy wartość właściwości DiskSpaceUsed i dzielimy ją przez 1048576, konwertując w ten sposób bajty na megabajty:

objQuota.DiskSpaceUsed / 1048576

Przez to otrzymujemy wartość podobną do następującej:

518.10445499420166015625

A ponieważ nie chcemy tak naprawdę oglądać wszystkich tych miejsc po przecinku, stosujemy funkcję Int w celu przekształcenia otrzymanego wyniku na liczbę całkowitą (518). Następnie robimy to samo z właściwością Limit, co da nam informacje na temat limitu przydziału dysku użytkownika.

Skąd zatem mamy wiedzieć, ile pojemności dysku ma Ken Meyer do dyspozycji? To proste: bierzemy przekazane informacje na temat przydziału (Limit) i odejmujemy pojemność dysku, którą już wykorzystał (DiskSpaceUsed). A robimy to tak:

Wscript.Echo "Disk Space Remaining: " & Int((objQuota.Limit - objQuota.DiskSpaceUsed) / 1048576) & _

        " megabytes"

Teraz kontynuujemy działanie pętli i powtarzamy cały proces dla następnego napędu dysku w kolekcji.

To powinno załatwić sprawę, HY. Jeżeli będą jeszcze jakieś problemy, daj nam znać.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne