Solved

PowerShell to calculate Datastore Free Space in Percentage

Posted on 2016-09-15
8
78 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
[X]
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
  • 3
  • 3
  • 2
8 Comments
 
LVL 85

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 85

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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 82

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 85

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 82

Expert Comment

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

Featured Post

Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

Question has a verified solution.

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

A brief introduction to what I consider to be the best editor for PowerShell.
My attempt to use PowerShell and other great resources found online to simplify the deployment of Office 365 ProPlus client components to any workstation that needs it, regardless of existing Office components that may be needing attention.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

632 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