cancel
Showing results for 
Search instead for 
Did you mean: 

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

Shinichi_Hayash
Not applicable
Employee

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