Video Screencast Help
Symantec to Separate Into Two Focused, Industry-Leading Technology Companies. Learn more.
Enterprise Vault Engineering Blog

[PowerShell] Show FreeSpace of each Partition (Pt 4)

Four part series of using Powershell to gather data from Registry/SQL Server/WMI and format them.
Created: 07 Jul 2014 • Updated: 08 Jul 2014 • 2 comments
Shinichi Hayashi's picture
+1 1 Vote
Login to vote

4. Returning the result in an Object

Our code so far uses Write-Host command to write string into console. This is not an object so commands like Format-Table , Format-List can not be used.  We want to create a custom object and then return the results. This can be done by creating PSCustomObject type object with  New-Object command in PowerShell 2.0.

A simple example would be like this.

PS>$MyCustomObject = New-Object -TypeName PSCustomObject -Property @{a=1;b=2}

PS>$MyCustomObject | Format-Table -AutoSize
      a b
      - -
      1 2

In our script, we want to create Custom Object with Partition Name and the FreeSpace. Custom Object with PartitionName and Free Space are appended into $object array. $object array will be the one that contains the final output.

PS>$object = @()
PS>$Props = @{
       'PartitionName' = $_['PartitionName']
       'FreeSpace' = $FreeSpace
}
PS>$object += New-Object -TypeName PSCustomObject -Property $Props

Once we have the $object, we can use Format-table to show the result. Also specified the alignment for the FreeSpace to “right”.

PS>$object | Format-Table PartitionName, @{Name="FreeSpace
(MB)";Expression='FreeSpace';Alignment='right'} -autosize

     PartitionName             FreeSpace(MB)
     -------------             -------------
     Exchange Vault Store Ptn1        20,205
     FSA Vault Store Ptn1             20,205

All in total the code will look like this.

$SQLServerName = (Get-ItemProperty "HKLM:SOFTWARE\Wow6432Node\KVS\Enterprise Vault\Directory\DirectoryService")."SQLServer Name"
$DatabaseName = (Get-ItemProperty "HKLM:SOFTWARE\Wow6432Node\KVS\Enterprise Vault\Directory\DirectoryService")."Database Name"
	
$ConnStr = "Data Source = "+$SQLServerName+"; Initial Catalog = "+$DatabaseName+"; Integrated Security = True"
$SqlString = "SELECT [PartitionRootPath],[PartitionName] FROM [dbo].[PartitionEntry]"

$Conn = New-Object System.Data.SqlClient.SqlConnection($ConnStr)
$SQLCmd = New-Object System.Data.SqlClient.SqlCommand($SqlString, $Conn)

$Conn.Open()

$Object = @()

$SQLCmd.ExecuteReader() | ForEach-Object{
  
     $DriveLetter= "DeviceID='" + $_['PartitionRootPath'].Split(":")[0] + ":'"

     $FreeSpace = [int64](Get-WmiObject -Class Win32_LogicalDisk -Filter $DriveLetter).FreeSpace

     $Props = @{'PartitionName' = $_['PartitionName']
                'FreeSpace' = [string]::Format("{0:N0}", $FreeSpace/1024/1024)}

     $Object += New-Object -TypeName PSCustomObject -Property $Props
}
$Conn.Close()

$Object | Format-Table PartitionName, @{Name="FreeSpace(MB)";Expression='FreeSpace';Alignment='right'} -autosize

---- Update Jul/9 2014 ----

There was a question if we can do the same if the Partitions are on a mount point.

For gathering data of mount points, WMI Win32_Volume class can be used. Following two lines are added to the original script.

$MountPoint = "Name='" + (($_['PartitionRootPath'] + "\") -replace "\\","\\") + "'"

$FreeSpace = [int64](Get-WmiObject Win32_Volume  -Filter $MountPoint).FreeSpace

The logic would be if the Win32_Volume class returns FreeSpace value for the PartitionRootPath, we will use that value. If Win32_Volume class does not return any value, we assume that it is not a mount point and refer to the Drive Letter.

$RegPath = "HKLM:SOFTWARE\Wow6432Node\KVS\Enterprise Vault\Directory\DirectoryService"

$SQLServerName = (Get-ItemProperty $RegPath)."SQLServer Name"
$DatabaseName = (Get-ItemProperty $RegPath)."Database Name"
	
$ConnStr = "Data Source = "+$SQLServerName+"; Initial Catalog = "+$DatabaseName+"; Integrated Security = True"
$SqlString = "SELECT [PartitionRootPath],[PartitionName] FROM [dbo].[PartitionEntry]"

$Conn = New-Object System.Data.SqlClient.SqlConnection($ConnStr)
$SQLCmd = New-Object System.Data.SqlClient.SqlCommand($SqlString, $Conn)

$Conn.Open()

$Object = @()

$SQLCmd.ExecuteReader() | ForEach-Object{

     $MountPoint= "Name='" + (($_['PartitionRootPath'] + "\") -replace "\\","\\") + "'"

     $FreeSpace= [int64](Get-WmiObject Win32_Volume  -Filter $MountPoint).FreeSpace
 
     if(!$FreeSpace){

       $DriveLetter= "DeviceID='" + $_['PartitionRootPath'].Split(":")[0] + ":'"

       $FreeSpace= [int64](Get-WmiObject -Class Win32_LogicalDisk -Filter $DriveLetter).FreeSpace

     }

     $Props = @{'PartitionName' = $_['PartitionName']
                'FreeSpace' = [string]::Format("{0:N0}", $FreeSpace/1024/1024)}

     $Object += New-Object -TypeName PSCustomObject -Property $Props
     $FreeSpace=""
}
$Conn.Close()

$Object | Format-Table PartitionName, @{Name="FreeSpace(MB)";Expression='FreeSpace';Alignment='right'} -autosize

Comments 2 CommentsJump to latest comment

Baris Aydogmusoglu's picture

Thank you for this great contribution!

Still can't calculate free space from mount point.

I found a script from a blog for mount points which is attached below.

Regards.

$TotalGB = @{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1073741824),2)}}
$FreeGB = @{Name="FreeSpace(GB)";expression={[math]::round(($_.FreeSpace / 1073741824),2)}}
$FreePerc = @{Name="Free(%)";expression={[math]::round(((($_.FreeSpace / 1073741824)/($_.Capacity / 1073741824)) * 100),0)}}

function get-mountpoints {
$volumes = Get-WmiObject -computer $server win32_volume | Where-object {$_.DriveLetter -eq $null}
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc | Format-Table -AutoSize
}

$servers = (Get-Content c:\servers.txt)

foreach ($server in $servers){
get-mountpoints
}

Senior System Expert

Microsoft Exchange Server

Symantec Enterprise Vault

http://www.aydogmusoglu.com

http://www.e-vault.info

0
Login to vote
Shinichi Hayashi's picture

Hi

Yes win32_volume class is the one to use for mountpoints.

I sent debug version of the updated script to see why it is not showing the FreeeSpace.

If you can get the result of the debug version, I can further check why it is not working.

Regards

0
Login to vote