Como obter capacidade do disco e espaço livre do computador remoto

116

Eu tenho este one-liner:

get-WmiObject win32_logicaldisk -Computername remotecomputer

e a saída é esta:

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   :

Como faço para obter Freespacee Sizede DeviceID C:? Preciso extrair apenas esses dois valores sem outras informações. Eu tentei com Selectcmdlet, mas sem efeito.

Edit: eu preciso extrair os valores numéricos apenas e armazená-los em variáveis.

culter
fonte

Respostas:

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

$disk.Size
$disk.FreeSpace

Para extrair apenas os valores e atribuí-los a uma variável:

$disk = Get-WmiObject Win32_LogicalDisk -ComputerName remotecomputer -Filter "DeviceID='C:'" |
Foreach-Object {$_.Size,$_.FreeSpace}
Shay Levy
fonte
18
simplesmente adicionar $ disk.Size / 1GB torna o resultado mais legível também.
ricky89
8
Se você quiser arredondar a tela para mostrar apenas números inteiros, use[Math]::Round($Disk.Freespace / 1GB)
user4317867
em Powershell por que 1mbretorna um valor de 1048576e não 1000000????
oldboy
@oldboy porque usa potências de 2: 2 ^ 20 vs. 10 ^ 6. Na verdade, deve ser escrito 1MiB(com letras maiúsculas), mas geralmente é mostrado em letras minúsculas, sem o "i". Veja Mebibyte .
Matthieu
128

Solução muito mais simples:

Get-PSDrive C | Select-Object Used,Free

e para computadores remotos (necessidades Powershell Remoting)

Invoke-Command -ComputerName SRV2 {Get-PSDrive C} | Select-Object PSComputerName,Used,Free
Ponteiros nulos etc.
fonte
Instale PSTools e façapsexec -u administrator \\[computer name or IP] powershell "get-psdrive C"
Ch.Idea
@JacobEvans ansible?
Kiquenet
Se você precisar autenticar, isso exigirá "mecanismo de autenticação Kerberos" habilitado na máquina remota.
Eddie Kumar
45

Apenas um comando simples doce e limpo, mas isso só funciona para discos locais

Get-PSDrive

insira a descrição da imagem aqui

Você ainda pode usar este comando em um servidor remoto executando Enter-PSSession -Computername ServerName e, em seguida, executar o Get-PSDrive, que extrairá os dados como se você o tivesse executado do servidor.

grepit
fonte
19

Eu criei uma função avançada do PowerShell (cmdlet de script) há algum tempo que permite consultar vários computadores.

O código da função tem pouco mais de 100 linhas, então você pode encontrá-lo aqui: Versão PowerShell do comando df

Confira o seção Uso para exemplos. O exemplo de uso a seguir consulta um conjunto de computadores remotos (entrada do pipeline do PowerShell) e exibe a saída em um formato de tabela com valores numéricos em formato legível por humanos:

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
fonte
Eu gostaria de usar esta função, mas o domínio blogspot está bloqueado para mim. Você poderia incluir a função aqui?
Kevin Panko
1
o mesmo link no arquivo da web: web.archive.org/web/20150614115736/http://…
Thomas
Get-DiskFree não parece estar disponível no PowerShell 2.0
Geoff Dawdy
11

Existem dois problemas que encontrei com as outras sugestões

    1) Os mapeamentos de unidade não são suportados se você executar o PowerShell no agendador de tarefas
    2) Você pode obter erros de erros de acesso negado tentando usar "get-WmiObject" em computadores remotos (dependendo da configuração de sua infraestrutura, é claro)

A alternativa que não sofre com esses problemas é usar GetDiskFreeSpaceEx com um caminho 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
fonte
Obrigado, boa solução, mas temos uma função semelhante para obter UNCpath para todo o usuário
user149621
O método PowerShell para unidades mapeadas quando não é usado por TaskScheduler?
Bill Greer
10

Outra maneira é lançar uma string para um objeto WMI:

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

Além disso, você pode dividir os resultados por 1 GB ou 1 MB se quiser unidades diferentes:

$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

O resultado é: Remotecomputer C: has 252.7 GB free of 298.0 GB Total

Greg Bray
fonte
@BillGreer Não sei de imediato, mas muitas vezes descobri que as chamadas WMI são mais lentas do que PS. Você mesmo pode testar com Measure-Command, mas certifique-se de executá-lo várias vezes e calcular a média dos resultados.
duct_tape_coder
7

Linha de comando:

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

Resultado:

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

linha de comando:

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

Fora:

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

linha de comando:

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

Fora:

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
fonte
2
Isto é ridículo.
Alexander Trauzzi
porque @AlexanderTrauzzi?
Kiquenet
1
wmic logicaldisk get sizenão leva em conta o espaço reservado que ... no PowerShell get-volumeretorna o tamanho total prático (ou seja, menos o espaço reservado), mas quando tento get-volume | format-list sizediz o tamanho total mais o espaço reservado ... como faço para obter o tamanho total menos o espaço reservado para cada unidade com PowerShell ???
oldboy
6
Get-PSDrive C | Select-Object @{ E={$_.Used/1GB}; L='Used' }, @{ E={$_.Free/1GB}; L='Free' }
Leorzz
fonte
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
fonte
1
Nathan, revirei sua edição. Isso mostra a saída fornecida, que é valiosa para aqueles que selecionam uma resposta para seus resultados. É uma linha para copiar e colar.
quux
2

Sei de ferramentas psExec que você pode baixar aqui

Vem um psinfo.exe do pacote de ferramentas. O uso básico é da seguinte maneira em powershell / cmd.

insira a descrição da imagem aqui

No entanto, você pode ter muitas opções com ele

Uso: psinfo [[\ computador [, computador [, ..] | @arquivo [-u usuário [-p psswd]]] [-h] [-s] [-d] [-c [-t delimitador]] [filtro]

\ computer Executa o comando no computador remoto ou computadores especificados. Se você omitir o nome do computador, o comando será executado no sistema local e se você especificar um caractere curinga (\ *), o comando será executado em todos os computadores no domínio atual.

@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.

O filtro Psinfo mostrará apenas os dados do campo que corresponde ao filtro. por exemplo, "serviço psinfo" lista apenas o campo do service pack.

Himanshu Chauhan
fonte
0

Eu acesso remoto ao computador usando Enter-PSsession pcName e, em seguida, digito Get-PSDrive

Isso listará todas as unidades e espaço usado e restante. Se você precisa ver todas as informações formatadas, canalize-as para FL assim: Get-PSdrive | FL *

Michael Dark
fonte
0

Criei esta função simples para me ajudar. Isso torna minhas chamadas muito mais fáceis de ler, tendo em linha instruções Get-WmiObject , Where-Object , etc.

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
fonte
1
OP era "Computador remoto". Isso não funcionou para mim no drive montado, mas provavelmente estava no meu lado ...
Yumi Koizumi
0

Caso queira verificar várias letras de unidade e / ou filtrar entre unidades locais e de rede, você pode usar o PowerShell para aproveitar a classe Win32_LogicalDisk WMI . Aqui está um exemplo rápido:

$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");
  }
}

Usei a técnica acima para criar um script Powershell que verifica todas as unidades e envia um alerta por e-mail sempre que elas ficam abaixo da cota definida pelo usuário. Você pode obtê-lo neste post no meu blog.

Darkseal
fonte
0

PowerShell Fun

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

Acabei de encontrar o comando Get-Volume , que retorna SizeRemaining, então algo como (Get-Volume -DriveLetter C).SizeRemaining / (1e+9)pode ser usado para ver Gb remanescente para o disco C. Parece que funciona mais rápido do que Get-WmiObject Win32_LogicalDisk.

Ilya Finkelsheyn
fonte