Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

PowerShell to calculate Datastore Free Space in Percentage

Posted on 2016-09-15
8
47 Views
Last Modified: 2016-10-05
We always maintain at-least 15% Free Space in VMware Datastores. Sometimes requirements come to allocate additional storage space to servers from the existing datastores. In that case we get confused about how much space should we allocate so that we can maintain more than 15% datastore space.

I am preparing following script to calculate VMware Datastore Free Space in Percentage. The script is in initial stage and running fine as of now. It will prompt to input datastore Capacity, Free Space and Space that needs to be reclaimed. It will then calculate whether 15% free space will be maintained or not after reclaiming the required storage space.

Can you please help me to add the the following conditions in the script as well-

1. It will force user to input only numbers.
2. It will not accept '0' (zero) in the input field.
3. User cannot left the input fields blank. It will force user to input.
Calculator
0
Comment
Question by:cbinayak
  • 3
  • 3
  • 2
8 Comments
 
LVL 84

Expert Comment

by:oBdA
ID: 41799665
Use this instead of Read-Host:
Function Read-Integer([string]$Prompt) {
	Do {
		$InputOK = $False
		$Input = Read-Host -Prompt $Prompt
		$Input = $Input.Trim()
		If ([string]::IsNullOrEmpty($Input)) {
			Write-Host "Empty input is not allowed!" -ForegroundColor Red
			Continue
		}
		$Integer = 0
		If (-Not [uint64]::TryParse($Input, [ref]$Integer)) {
			Write-Host "Input '$($Input)' is not a positive integer!" -ForegroundColor Red
			Continue
		}
		If ($Integer -eq 0) {
			Write-Host "Input '0' is not allowed!" -ForegroundColor Red
			Continue
		}
		$InputOK = $True
	} Until ($InputOK)
	Return $Integer
}

Open in new window

0
 

Author Comment

by:cbinayak
ID: 41799700
I am not that much expert in PowerShell. Can you please let me know where to include this code more specifically?
0
 
LVL 84

Expert Comment

by:oBdA
ID: 41799711
For example starting in the current line 10, below the end of the CalcPercent function.
Then wherever you want a positive integer (currently lines 11, 12, 13), replace the Read-Host with the new Read-Integer call.

And the next time you post code, please use "Style Code" tags (see tool bar above the Comment block), not a screenshot.
0
Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 80

Expert Comment

by:David Johnson, CD, MVP
ID: 41800581
Why do you have to input the values? Can you not get the total drive space and space used by querying the drive itself?
$VMhost = HostSystem-host-8
$disks = Get-Datastore -VMHost (Get-VMHost -Id $VMHost)
$capacity = $disks.capacityMB
$freespace = $disks.FreeSpaceMB
if ($freespace -le ($capacity *0.15)) { # less than 15% available) }; else { #more than 15% available }

Open in new window

0
 

Author Comment

by:cbinayak
ID: 41801226
@oBdA

I have slightly modified the existing code. It would be very helpful if you can help me in modifying my code with yours. Here is the code -
cls

Write-Host "*******************************************************************************"
Write-Host -ForegroundColor Green "CALCULATOR to calculate FREE SPACE PERCENTAGE after reclaiming storage space"
Write-Host "*******************************************************************************"
Write-Host ""

function CalcPercent {
    param(
    [parameter(Mandatory = $true)]
    [int]$InputNum1,
    [parameter(Mandatory = $true)]
    [int]$InputNum2)
    $InputNum1 / $InputNum2*100
}

$CapacityMB = Read-Host -Prompt 'Input Datastore CAPACITY in MB '
$A = [Math]::Round($CapacityMB)

$CurrentFreeSpaceMB = Read-Host -Prompt 'Input Datastore CURRENT FREE SPACE in MB '
$B = [Math]::Round($CurrentFreeSpaceMB)

$SpaceToReclaimMB = Read-Host -Prompt 'Input Space that you want to RECLAIM in MB '
$C = [Math]::Round($SpaceToReclaimMB)

$FreeSpaceMB = [float]$B-$C
$D = [Math]::Round($FreeSpaceMB)

$PercentFree = CalcPercent $D $A
$PercentFree = "{0:N2}" -f $PercentFree
$E = [Math]::Round($PercentFree)

Write-Host ""
Write-Host -ForegroundColor Yellow "Datastore Free Space will be $PercentFree % after reclaiming $SpaceToReclaimMB MB storage"

if ($E -lt 15)
{
	Write-Host -BackgroundColor Red "Free space is less than 15%. You have to add additional storage before you reclaim $SpaceToReclaimMB MB."
}
else
{
	Write-Host -ForegroundColor Green "YOU CAN GO AHEAD WITH RECLAIMING $SpaceToReclaimMB MB OF SPACE."
}

Open in new window

0
 
LVL 84

Accepted Solution

by:
oBdA earned 500 total points (awarded by participants)
ID: 41801297
Maybe some comments:
- You start out "correctly", by assigning the input to variables with meaningful names. Why do you then continue with using $A, $B, etc, when two lines below, you probably can't remember yourself anymore which variable holds which value?
- The same is true for function arguments - make them self-explaining; "InputNum" isn't.
- Line 14: Careful when calculating with integers. Powershell is flexible enough to make it work, but if you were working with real integers (for example in a batch script), "FreeSpaceMB / CapacityMB * 100" would always return 0, because the division would be calculated first and return 0.
- Line 29: your function will return an integer or a float, depending on the values passed. You then turn that into a string with two decimal places, and then turn that string back into a float and finally round it back to an integer. Aside from that being overly complicated: if the free percentage was 14.51, Round() will turn that into a full 15, so your script might return incorrect results.
- Powershell functions should follow the Cmdlet naming rules, that is, <verb>-<noun>. <verb> should be from the list obtained with Get-Verb.

That said, here's the pimped version:
cls

Write-Host "*******************************************************************************"
Write-Host "CALCULATOR to calculate FREE SPACE PERCENTAGE after reclaiming storage space" -ForegroundColor Green 
Write-Host "*******************************************************************************"
Write-Host ""

Function ConvertTo-Percent {
Param(
	[parameter(Mandatory = $true)][Alias('Numerator')]
	[int]$Antecedent,
	[parameter(Mandatory = $true)][Alias('Denominator')]
	[int]$Consequent,
	[int]$DecimalPlaces = 0
)
	Return [math]::Round((100 * $Antecedent) / $Consequent, $DecimalPlaces)
}

Function Read-Integer([string]$Prompt) {
	Do {
		$InputOK = $False
		$Input = Read-Host -Prompt $Prompt
		$Input = $Input.Trim()
		If ([string]::IsNullOrEmpty($Input)) {
			Write-Host "Empty input is not allowed!" -ForegroundColor Red
			Continue
		}
		$Integer = 0
		If (-Not [uint64]::TryParse($Input, [ref]$Integer)) {
			Write-Host "Input '$($Input)' is not a positive integer!" -ForegroundColor Red
			Continue
		}
		If ($Integer -eq 0) {
			Write-Host "Input '0' is not allowed!" -ForegroundColor Red
			Continue
		}
		$InputOK = $True
	} Until ($InputOK)
	Return $Integer
}

$CapacityMB = Read-Integer -Prompt 'Input Datastore CAPACITY in MB (no decimal places) '

$CurrentFreeSpaceMB = Read-Integer -Prompt 'Input Datastore CURRENT FREE SPACE in MB (no decimal places) '

$SpaceToReclaimMB = Read-Integer -Prompt 'Input Space that you want to RECLAIM in MB (no decimal places) '

$FreeSpaceMB = $CurrentFreeSpaceMB - $SpaceToReclaimMB

$PercentFree = ConvertTo-Percent $FreeSpaceMB $CapacityMB -DecimalPlaces 2

Write-Host ""
Write-Host -ForegroundColor Yellow "Datastore Free Space will be $PercentFree % after reclaiming $SpaceToReclaimMB MB storage"

if ($PercentFree -lt 15)
{
	Write-Host -BackgroundColor Red "Free space is less than 15%. You have to add additional storage before you reclaim $SpaceToReclaimMB MB."
}
else
{
	Write-Host -ForegroundColor Green "YOU CAN GO AHEAD WITH RECLAIMING $SpaceToReclaimMB MB OF SPACE."
}

Open in new window

0
 

Author Comment

by:cbinayak
ID: 41802622
Excellent oBdA. Many many thanks for your suggestion and specially for the code. I will try that and let you know the status.
0
 
LVL 80

Expert Comment

by:David Johnson, CD, MVP
ID: 41829531
Asker liked code then disappeared
0

Featured Post

Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Set OWA language and time zone in Exchange for individuals, all users or per database.
"Migrate" an SMTP relay receive connector to a new server using info from an old server.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question