Jak uzyskać pojemność dysku i wolne miejsce na komputerze zdalnym

118

Mam ten jeden wiersz:

get-WmiObject win32_logicaldisk -Computername remotecomputer

a wynik jest taki:

DeviceID     : A:
DriveType    : 2
ProviderName :
FreeSpace    :
Size         :
VolumeName   :

DeviceID     : C:
DriveType    : 3
ProviderName :
FreeSpace    : 20116508672
Size         : 42842714112
VolumeName   :

DeviceID     : D:
DriveType    : 5
ProviderName :
FreeSpace    :
Size         :
VolumeName   :

W jaki sposób uzyskać Freespacei Sizeod DeviceID C:? Muszę wyodrębnić tylko te dwie wartości bez innych informacji. Wypróbowałem to za pomocą polecenia Selectcmdlet, ale bez efektu.

Edycja: muszę wyodrębnić tylko wartości liczbowe i przechowywać je w zmiennych.

kulter
źródło

Odpowiedzi:

137
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Select-Object Size,FreeSpace

$disk.Size
$disk.FreeSpace

Aby wyodrębnić tylko wartości i przypisać je do zmiennej:

$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Foreach-Object {$_.Size,$_.FreeSpace}
Shay Levy
źródło
18
po prostu dodanie $ disk.Size / 1GB sprawia, że ​​wynik jest również bardziej czytelny.
ricky89
8
Jeśli chcesz zaokrąglić wyświetlacz, aby wyświetlić tylko liczby całkowite, użyj[Math]::Round($Disk.Freespace / 1GB)
user4317867,
w PowerShell dlaczego 1mbzwraca wartość 1048576a nie 1000000????
oldboy
@oldboy, ponieważ używa potęg 2: 2 ^ 20 w porównaniu z 10 ^ 6. Powinien być rzeczywiście napisany 1MiB(z odpowiednią wielkością liter), ale zwykle jest wyświetlany małymi literami, bez „i”. Zobacz Mebibyte .
Matthieu
130

Dużo prostsze rozwiązanie:

Get-PSDrive C | Select-Object Used,Free

i dla komputerów zdalnych (potrzeby Powershell Remoting)

Invoke-Command -ComputerName SRV2 {Get-PSDrive C} | Select-Object PSComputerName,Used,Free
Puste wskaźniki itp.
źródło
Zainstaluj PSTools i zróbpsexec -u administrator \\[computer name or IP] powershell "get-psdrive C"
Ch.Idea
@JacobEvans ansible?
Kiquenet
Jeśli potrzebujesz uwierzytelnienia, będzie to wymagało „mechanizmu uwierzytelniania Kerberos” włączonego na komputerze zdalnym.
Eddie Kumar,
46

Tylko jedno polecenie, proste, słodkie i czyste, ale działa to tylko na dyskach lokalnych

Get-PSDrive

wprowadź opis obrazu tutaj

Nadal możesz użyć tego polecenia na serwerze zdalnym, wykonując Enter-PSSession -Computername nazwa_serwera, a następnie uruchom Get-PSDrive, które pobierze dane tak, jakbyś je uruchomił z serwera.

grepit
źródło
19

Jakiś czas temu stworzyłem zaawansowaną funkcję PowerShell (skrypt cmdlet), która umożliwia wykonywanie zapytań na wiele komputerów.

Kod funkcji ma nieco ponad 100 linii, więc możesz go znaleźć tutaj: Wersja PowerShell polecenia df

Sprawdź Wykorzystanie sekcję przykładów. Poniższy przykład użycia wysyła zapytanie do zestawu komputerów zdalnych (dane wejściowe z potoku programu PowerShell) i wyświetla dane wyjściowe w formacie tabeli z wartościami liczbowymi w postaci czytelnej dla człowieka:

PS> $cred = Get-Credential -Credential 'example\administrator'
PS> 'db01','dc01','sp01' | Get-DiskFree -Credential $cred -Format | Format-Table -GroupBy Name -AutoSize

   Name: DB01

Name Vol Size  Used  Avail Use% FS   Type
---- --- ----  ----  ----- ---- --   ----
DB01 C:  39.9G 15.6G 24.3G   39 NTFS Local Fixed Disk
DB01 D:  4.1G  4.1G  0B     100 CDFS CD-ROM Disc


   Name: DC01

Name Vol Size  Used  Avail Use% FS   Type
---- --- ----  ----  ----- ---- --   ----
DC01 C:  39.9G 16.9G 23G     42 NTFS Local Fixed Disk
DC01 D:  3.3G  3.3G  0B     100 CDFS CD-ROM Disc
DC01 Z:  59.7G 16.3G 43.4G   27 NTFS Network Connection


   Name: SP01

Name Vol Size   Used   Avail Use% FS   Type
---- --- ----   ----   ----- ---- --   ----
SP01 C:  39.9G  20G    19.9G   50 NTFS Local Fixed Disk
SP01 D:  722.8M 722.8M 0B     100 UDF  CD-ROM Disc
mweisel
źródło
Chciałbym skorzystać z tej funkcji, ale domena blogspot jest dla mnie zablokowana. Czy mógłbyś dołączyć tutaj funkcję?
Kevin Panko,
1
ten sam link w archiwum internetowym: web.archive.org/web/20150614115736/http://…
Thomas
Wydaje się, że Get-DiskFree nie jest dostępny w PowerShell 2.0
Geoff Dawdy
11

W przypadku innych sugestii napotkałem dwa problemy

    1) Mapowania dysków nie są obsługiwane, jeśli uruchomisz PowerShell w ramach harmonogramu zadań
    2) Możesz otrzymać odmowę dostępu błędy błędy przy próbie użycia polecenia „get-WmiObject” na zdalnych komputerach (oczywiście w zależności od konfiguracji infrastruktury)

Alternatywą, która nie cierpi z powodu tych problemów, jest użycie GetDiskFreeSpaceEx ze ścieżką UNC:

function getDiskSpaceInfoUNC($p_UNCpath, $p_unit = 1tb, $p_format = '{0:N1}')
{
    # unit, one of --> 1kb, 1mb, 1gb, 1tb, 1pb
    $l_typeDefinition = @' 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
        [return: MarshalAs(UnmanagedType.Bool)] 
        public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName, 
            out ulong lpFreeBytesAvailable, 
            out ulong lpTotalNumberOfBytes, 
            out ulong lpTotalNumberOfFreeBytes); 
'@
    $l_type = Add-Type -MemberDefinition $l_typeDefinition -Name Win32Utils -Namespace GetDiskFreeSpaceEx -PassThru

    $freeBytesAvailable     = New-Object System.UInt64 # differs from totalNumberOfFreeBytes when per-user disk quotas are in place
    $totalNumberOfBytes     = New-Object System.UInt64
    $totalNumberOfFreeBytes = New-Object System.UInt64

    $l_result = $l_type::GetDiskFreeSpaceEx($p_UNCpath,([ref]$freeBytesAvailable),([ref]$totalNumberOfBytes),([ref]$totalNumberOfFreeBytes)) 

    $totalBytes     = if($l_result) { $totalNumberOfBytes    /$p_unit } else { '' }
    $totalFreeBytes = if($l_result) { $totalNumberOfFreeBytes/$p_unit } else { '' }

    New-Object PSObject -Property @{
        Success   = $l_result
        Path      = $p_UNCpath
        Total     = $p_format -f $totalBytes
        Free      = $p_format -f $totalFreeBytes
    } 
}
Warren Stevens
źródło
Dzięki, fajne rozwiązanie, ale czy mamy podobną funkcję, aby uzyskać UNCpath dla wszystkich użytkowników
user149621
Czy metoda PowerShell dla dysków zamapowanych, gdy nie jest używana przez TaskScheduler?
Bill Greer
10

Innym sposobem jest rzutowanie ciągu znaków na obiekt WMI:

$size = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'").Size
$free = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'").FreeSpace

Możesz również podzielić wyniki przez 1 GB lub 1 MB, jeśli chcesz mieć różne jednostki:

$disk = ([wmi]"\\remotecomputer\root\cimv2:Win32_logicalDisk.DeviceID='c:'")
"Remotecomputer C: has {0:#.0} GB free of {1:#.0} GB Total" -f ($disk.FreeSpace/1GB),($disk.Size/1GB) | write-output

Wynik to: Remotecomputer C: has 252.7 GB free of 298.0 GB Total

Greg Bray
źródło
@BillGreer Nie wiem od razu, ale często spotykałem połączenia WMI wolniejsze niż PS. Możesz sam przetestować za pomocą Measure-Command, ale pamiętaj, aby uruchomić go kilka razy i uśrednić wyniki.
channel_tape_coder
7

Wiersz poleceń:

powershell gwmi Win32_LogicalDisk -ComputerName remotecomputer -Filter "DriveType=3" ^|
select Name, FileSystem,FreeSpace,BlockSize,Size ^| % {$_.BlockSize=
(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_}
^| Format-Table Name, @{n='FS';e={$_.FileSystem}},@{n='Free, Gb';e={'{0:N2}'-f
$_.FreeSpace}}, @{n='Free,%';e={'{0:N2}'-f $_.BlockSize}},@{n='Capacity ,Gb';e={'{0:N3}'
-f $_.Size}} -AutoSize

Wynik:

Name FS   Free, Gb Free,% Capacity ,Gb

---- --   -------- ------ ------------

C:   NTFS 16,64    3,57   465,752

D:   NTFS 43,63    9,37   465,759

I:   NTFS 437,59   94,02  465,418

N:   NTFS 5,59     0,40   1 397,263

O:   NTFS 8,55     0,96   886,453

P:   NTFS 5,72     0,59   976,562

wiersz poleceń:

wmic logicaldisk where DriveType="3" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpace

na zewnątrz:

Caption  FileSystem  FreeSpace     Size           VolumeName  VolumeSerialNumber

C:       NTFS        17864343552   500096991232   S01         EC641C36

D:       NTFS        46842589184   500104687616   VM1         CAF2C258

I:       NTFS        469853536256  499738734592   V8          6267CDCC

N:       NTFS        5998840832    1500299264512  Vm-1500     003169D1

O:       NTFS        9182349312    951821143552   DT01        A8FC194C

P:       NTFS        6147043840    1048575144448  DT02        B80A0F40

wiersz poleceń:

wmic logicaldisk where Caption="C:" get caption, VolumeName, VolumeSerialNumber, Size, FileSystem, FreeSpace

na zewnątrz:

Caption  FileSystem  FreeSpace    Size          VolumeName  VolumeSerialNumber

C:       NTFS        17864327168  500096991232  S01         EC641C36

command-line:

dir C:\ /A:DS | find "free"

out:
               4 Dir(s)  17 864 318 976 bytes free

dir C:\ /A:DS /-C | find "free"

out:
               4 Dir(s)     17864318976 bytes free
STTR
źródło
2
To jest niedorzeczne.
Alexander Trauzzi,
dlaczego @AlexanderTrauzzi?
Kiquenet
1
wmic logicaldisk get sizenie uwzględnia zarezerwowanego miejsca, mimo ... w programie PowerShell get-volumezwraca praktyczny całkowity rozmiar (tj. minus zarezerwowane miejsce), ale kiedy spróbuję get-volume | format-list size, mówi, że całkowity rozmiar plus zarezerwowane miejsce ... jak uzyskać całkowity rozmiar minus zarezerwowane miejsce dla każdego dysku z PowerShell ???
oldboy
6
Get-PSDrive C | Select-Object @{ E={$_.Used/1GB}; L='Used' }, @{ E={$_.Free/1GB}; L='Free' }
leorzz
źródło
3
PS> Get-CimInstance -ComputerName bobPC win32_logicaldisk | where caption -eq "C:" | foreach-object {write " $($_.caption) $('{0:N2}' -f ($_.Size/1gb)) GB total, $('{0:N2}' -f ($_.FreeSpace/1gb)) GB free "}  
C: 117.99 GB total, 16.72 GB free 

PS> 
quux
źródło
1
Nathan, wycofałem twoją edycję. Pokazuje podane dane wyjściowe, które są cenne dla osób wybierających odpowiedź na jej wyniki. Kopiowanie i wklejanie to jedna linia.
quux
2

Znam narzędzia psExec, które możesz pobrać stąd

Z pakietu narzędzi pochodzi plik psinfo.exe. Podstawowe użycie jest następujące w PowerShell / cmd.

wprowadź opis obrazu tutaj

Jednak możesz mieć z nim wiele opcji

Użycie: psinfo [[\ komputer [, komputer [, ..] | @file [-u użytkownik [-p psswd]]] [-h] [-s] [-d] [-c [-t separator]] [filtr]

\ komputer Wykonaj polecenie na komputerze zdalnym lub określonych komputerach. Jeśli pominiesz nazwę komputera, które polecenie jest uruchamiane w systemie lokalnym, i jeśli określisz symbol wieloznaczny (\ *), polecenie zostanie uruchomione na wszystkich komputerach w bieżącej domenie.

@file   Run the command on each computer listed in the text file specified.
-u  Specifies optional user name for login to remote computer.
-p  Specifies optional password for user name. If you omit this you will be prompted to enter a hidden password.
-h  Show list of installed hotfixes.
-s  Show list of installed applications.
-d  Show disk volume information.
-c  Print in CSV format.
-t  The default delimiter for the -c option is a comma, but can be overriden with the specified character.

filter Psinfo pokaże tylko dane dla pola pasującego do filtra. np. „usługa psinfo” wyświetla tylko pole pakietu serwisowego.

Himanshu Chauhan
źródło
0

Zdalnie do komputera za pomocą Enter-PSsession pcName, a następnie wpisuję Get-PSDrive

Spowoduje to wyświetlenie wszystkich dysków oraz zajętego i pozostałego miejsca. Jeśli chcesz zobaczyć wszystkie sformatowane informacje, prześlij je do FL w ten sposób: Get-PSdrive | FL *

Michael Dark
źródło
0

Stworzyłem tę prostą funkcję, aby mi pomóc. To sprawia, że ​​moje wywołania są dużo łatwiejsze do odczytania, że ​​mając wbudowane instrukcje Get-WmiObject , Where-Object itp.

function GetDiskSizeInfo($drive) {
    $diskReport = Get-WmiObject Win32_logicaldisk
    $drive = $diskReport | Where-Object { $_.DeviceID -eq $drive}

    $result = @{
        Size = $drive.Size
        FreeSpace = $drive.Freespace
    }
    return $result
}

$diskspace = GetDiskSizeInfo "C:"
write-host $diskspace.FreeSpace " " $diskspace.Size
Kaj Bonfils
źródło
1
OP to „komputer zdalny”. To nie zadziałało dla mnie na zamontowanym dysku, ale to chyba z mojej strony ...
Yumi Koizumi
0

Jeśli chcesz sprawdzić wiele liter dysków i / lub filtrować między dyskami lokalnymi i sieciowymi, możesz użyć programu PowerShell, aby skorzystać z klasy WMI Win32_LogicalDisk . Oto krótki przykład:

$localVolumes = Get-WMIObject win32_volume;

foreach ($vol in $localVolumes) {
  if ($vol.DriveLetter -ne $null ) {
    $d = $vol.DriveLetter[0];
    if ($vol.DriveType -eq 3) {
      Write-Host ("Drive " + $d + " is a Local Drive");
    }
    elseif ($vol.DriveType -eq 4) {
      Write-Host ("Drive" + $d + " is a Network Drive");
    }
    else {
      // ... and so on
    }

    $drive = Get-PSDrive $d;
    Write-Host ("Used space on drive " + $d + ": " + $drive.Used + " bytes. `r`n");
    Write-Host ("Free space on drive " + $d + ": " + $drive.Free + " bytes. `r`n");
  }
}

Użyłem powyższej techniki do stworzenia skryptu Powershell, który sprawdza wszystkie dyski i wysyła alert e-mail, gdy tylko spadną poniżej limitu zdefiniowanego przez użytkownika. Możesz go pobrać z tego posta na moim blogu.

Darkseal
źródło
0

Zabawa PowerShell

Get-WmiObject win32_logicaldisk -Computername <ServerName> -Credential $(get-credential) | Select DeviceID,VolumeName,FreeSpace,Size | where {$_.DeviceID -eq "C:"}
GhostWolf
źródło
0

Właśnie znalazłem polecenie Get-Volume , które zwraca SizeRemaining, więc (Get-Volume -DriveLetter C).SizeRemaining / (1e+9)można użyć czegoś takiego, aby zobaczyć pozostałą Gb dla dysku C. Wydaje się, że działa szybciej niż Get-WmiObject Win32_LogicalDisk.

Ilya Finkelsheyn
źródło