0

I am trying to pull a report of all C:\ drive usage for windows 7 machine in our ESX farm. My initial ps codes will extract all windows 7 machine nto a csv file (sample picture below). I would like to ideally query the disk space with the DNS name first and if it fails due to RPC error, it should then catch the error and run the command again using the IP address instead. This is because there are instances that the dns entry does not get registered on our DNS and there are also times where the ESX sees 169.x.x.x IP during the query which would then gets polled by DNS name first.

Issue here is that, I am not able to catch the RPC failure with the catch command. In the sample below, I have purposely filled up the .csv file with dummy dns names hoping that it will catch the error and execute the command in the catch portion. Unfortunately, it seems not to be working.

Anyone here can shade some light on this one ?

CSV File Sample

csv file

$Win7JumpboxList = import-csv 'D:\Win7DiskSpace\Win7PoweredOn.csv' |
ForEach-Object {
    try {
        Get-WmiObject -Class win32_volume -ComputerName $_.DnsName -Filter "drivetype=3 and DRIVELETTER = 'C:' " | Select-Object @{LABEL='Computer';EXPRESSION={$_.pscomputername}}, DriveLetter, @{LABEL="Capacity (GB)";e={[math]::round($_.Capacity/1GB, 2)}}, @{LABEL="FreeSpace (GB)";e={[math]::round($_.FreeSpace/1GB, 2)}},@{LABEL="FreeSpace (%)";e={[int]($_.Freespace*100/$_.Capacity)}} -ErrorAction Stop
    }
    catch [System.Runtime.InteropServices.COMException] {
        Get-WmiObject -Class win32_volume -ComputerName $_.IPAddress -Filter "drivetype=3 and DRIVELETTER = 'C:' " | Select-Object @{LABEL='Computer';EXPRESSION={$_.pscomputername}}, DriveLetter, @{LABEL="Capacity (GB)";e={[math]::round($_.Capacity/1GB, 2)}}, @{LABEL="FreeSpace (GB)";e={[math]::round($_.FreeSpace/1GB, 2)}},@{LABEL="FreeSpace (%)";e={[int]($_.Freespace*100/$_.Capacity)}}
    }
}

$Win7JumpboxList | Export-Csv D:\Win7DiskSpace\Win7DiskSpace.csv -NoTypeInformation -force
2
  • Your -Erroraction Stop cmdlet is at the wrong place. You gotta put it for the Get-WmiObject cmdlet for this to work. Commented Sep 26, 2017 at 7:52
  • WMI is painfully slow and unreliable on it's best day. If you want accurate data fast and have access to vSphere using PowerCLI then that is the way to go. Commented Sep 26, 2017 at 12:32

2 Answers 2

1

Use ErrorAction for Get-WmiObject cmdlet instead of Select-Object

try {
    Get-WmiObject -Class win32_volume -ComputerName $_.DnsName -Filter "drivetype=3 and DRIVELETTER = 'C:' " -ErrorAction Stop | Select-Object @{LABEL='Computer';EXPRESSION={$_.pscomputername}}, DriveLetter, @{LABEL="Capacity (GB)";e={[math]::round($_.Capacity/1GB, 2)}}, @{LABEL="FreeSpace (GB)";e={[math]::round($_.FreeSpace/1GB, 2)}},@{LABEL="FreeSpace (%)";e={[int]($_.Freespace*100/$_.Capacity)}} 
}
catch [System.Runtime.InteropServices.COMException] {
    Get-WmiObject -Class win32_volume -ComputerName $_.IPAddress -Filter "drivetype=3 and DRIVELETTER = 'C:' " | Select-Object @{LABEL='Computer';EXPRESSION={$_.pscomputername}}, DriveLetter, @{LABEL="Capacity (GB)";e={[math]::round($_.Capacity/1GB, 2)}}, @{LABEL="FreeSpace (GB)";e={[math]::round($_.FreeSpace/1GB, 2)}},@{LABEL="FreeSpace (%)";e={[int]($_.Freespace*100/$_.Capacity)}}
}
Sign up to request clarification or add additional context in comments.

1 Comment

Getting error for this one.. It does not move run through the catch command somehow. Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) At line:7 char:13 + Get-WmiObject -Class win32_volume -ComputerName '$_.IPAdd ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
0

Use PowerCLI instead:

C:> $vms = get-vm
C:> foreach ( $vm in $vms) {
C:> foreach ( $vmdisk in $vm.guest.Disks ) {
>>  $vm | select Name,
>>     @{n='hostname';e={$vm.guest.hostname}},
>>     @{n='IPAddress';e={$vm.guest.IPAddress}},
>>     @{n='Disk';e={$vmdisk.Path}},
>>     @{n='CapacityGB';e={$vmdisk.CapacityGB}},
>>     @{n='FreeSpaceGB';e={$vmdisk.FreeSpaceGB}}
>> }
>> }


Name        : somevm
hostname    : somevm.mydomain.org
IPAddress   : {192.168.130.141, 6c9e::9n5b:cbdb:6ce5:fb72}
Disk        : C:\
CapacityGB  : 98.533199310302734375
FreeSpaceGB : 57.00951385498046875

Name        : anothervm
hostname    : anothervm.mydomain.org
IPAddress   : {192.168.130.142, 6c9e::9n5b:cbdb:6ce5:fb73}
Disk        : C:\
CapacityGB  : 98.533199310302734375
FreeSpaceGB : 54.06373657644533

4 Comments

Hi Brendan. The solution seems to be working but I am getting the some weird output. The hostname and Ip is showing a long list of everything while the disk space is the same for all the servers.. Uploaded the output here : pastebin.com/raw/DeYp3yAeM. Mind checking it out ?
Your output on pastebin is gone, but it sounds like your variable $vm probably has multiple (all?) VM objects. So you need another foreach around the $vm objects. I'll edit my answer to give you an idea what I mean.
Thank you Brendan. It works perfectly. One more small bit though, is there any way for me to filter out C:\ drive and also the IPv4 address as per the one displayed in the VI console (normally starts with 10.x.x.x.x or 172.x.x.x) only.
Yes, if you add a where clauses, like { $_.Path -eq 'C:\' } on $vm.guest.Disks and possibly -notmatch ":" for the IPs. See if you can figure those out, if you get stumped please come back and ask specifics.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.