Solved

PowerShell to calculate Datastore Free Space in Percentage

Posted on 2016-09-15
8
34 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 83

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 83

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
 
LVL 78

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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

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 83

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 78

Expert Comment

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

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Why would I want to create a function for tracking messages? I am glad you asked. As with most monotonous/routine tasks, human error tends to creep in after doing the same task over and over again. By creating a function, you load the function once…
This article will help you understand what HashTables are and how to use them in PowerShell.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

705 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now