VMware Cloud Community
DZ1
Hot Shot
Hot Shot

End of my script, just need one more push (outputting if statement)

I apologize in advance for all the code, and how long the post is.  I will make the code in Blue, so it stands out in the post.

Well, I just don't want to spend all day on this, so I'm hoping to find some help...again.

I want to output a message that only shows if a certain percentage of free space is low on a datastore (I have it at 15 percent).  On my old script, I didn't create any objects, and for the datastore part I did this:

Function My-Data {



Function PercentFree { ## Start Function

param($ds)

[Math]::Round(($ds.FreeSpaceMB / $ds.CapacityMB * 100),0)

} ## End Function



$runOnce = 0
$datastores = Get-Datacenter 'Datacenter' | Get-Datastore
$vDataStore = @()
Foreach ($datastore in $datastores) {

if ($runOnce -eq 0) { Write ("`r" + "Please do not place any VMs on the following datastores today " + "(" + (Get-date -Format "MM-dd-yyyy") + ")" + "," + " they are low on space: (Never place VMs on the `"ISOs`" datastore)"); "`r"; $runOnce++ }
$vDataStore = "" | Select Datastore, UsedSpace, Capacity, PercentageFree
$vDataStore.Datastore = $datastore.Name
$vDatastore.UsedSpace = [Math]::Round($datastore.FreeSpaceGB)
$vDataStore.Capacity = [Math]::Round($datastore.CapacityGB)
$vDataStore.PercentageFree = PercentFree $datastore

#The IF that tells you that there is less that 15 percent of freespace on the datastores, and it outputs the information
if ($vDataStore.PercentageFree -lt 15 -and $vDataStore.Datastore -notmatch 'ISOs') { write $vDataStore.Datastore ("{0:N0}% free" -f $vDataStore.PercentageFree),`
("Total amount free = " + $vDataStore.UsedSpace + "GB"),("Total capacity = " + $vDataStore.Capacity + "GB")"`r" }
}



} #end Function My-Data

The above script is just a portion of the script, but would output the information below:

------------------------------------------------------------------------------------------------------

Please do not place any VMs on the following datastores today (05-15-2012), they are low on space:

Datastore-vdisk

13% free

Total amount free = 251GB

Total capacity = 1900GB

What I want is that same information, but now I want to dynamically add it to an existing object.  The code below is the new script (just a portion)

Function My-Function {

$vDataStore = New-Object PSObject

$vDataStore | Add-Member -MemberType NoteProperty -Name "vCenter Datastores" -Value ($Alldatastore).count

$vDataStore | Add-Member -MemberType NoteProperty -Name "Total storage capacity of datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property CapacityGB -sum).sum) / 1024))" + "(TB)")

$vDataStore | Add-Member -MemberType NoteProperty -Name "Total amount of free space on datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property FreeSpaceGB -sum).sum) / 1024))" + "(TB)")

Write "Datastore information "`r" ",

$vDatastore | fl

} #end My-Function

What I think the solution is, is that after this:

if ($vDataStore.PercentageFree -lt 15 -and $vDataStore.Datastore -notmatch 'ISOs')

I basically copied a portion of the old script to the new script, I changed some of the names around, and tried this

Function My-Test {



Function PercentFree { ## Start Function

param($ds)

[Math]::Round(($ds.FreeSpaceMB / $ds.CapacityMB * 100),0)

} ## End Function


$Alldatastore = Get-Datacenter "Center" | Get-Datastore


$OBJvDataStore = New-Object PSObject

$OBJvDataStore | Add-Member -MemberType NoteProperty -Name "vCenter Datastores" -Value ($Alldatastore).count

$OBJvDataStore | Add-Member -MemberType NoteProperty -Name "Total storage capacity of datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property CapacityGB -sum).sum) / 1024))" + "(TB)")

$OBJvDataStore | Add-Member -MemberType NoteProperty -Name "Total amount of free space on datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property FreeSpaceGB -sum).sum) / 1024))" + "(TB)")



$runOnce = 0

Foreach ($datastore in $Alldatastore) {

if ($runOnce -eq 0) { Write ("`r" + "Please do not place any VMs on the following datastores today " + "(" + (Get-date -Format "MM-dd-yyyy") + ")" + "," + " they are low on space: (Never place VMs on the `"ISOs`" datastore)"); "`r"; $runOnce++ }

$vDataStore = "" | Select Datastore, UsedSpace, Capacity, PercentageFree

$vDataStore.Datastore = $datastore.Name

$vDatastore.UsedSpace = [Math]::Round($datastore.FreeSpaceGB)

$vDataStore.Capacity = [Math]::Round($datastore.CapacityGB)

$vDataStore.PercentageFree = PercentFree $datastore

#I tried various things here

if ($vDataStore.PercentageFree -lt 15 -and $vDataStore.Datastore -notmatch 'ISOs') {

    $Hash = New-Object PSObject -Property @{

    "Datastores with low space" = $vDataStore.Datastore("{0:N0}% free" -f $vDataStore.PercentageFree)

    }

     #I tried adding a member, but I could not get it to work

   # Add-Member -InputObject $OBJvDataStore  "Datastores with low space" -Value $vDataStore.Datastore ("{0:N0}% free" -f $vDataStore.PercentageFree),`

    #("Total amount free = " + $vDataStore.UsedSpace + "GB"),

    #("Total capacity = " + $vDataStore.Capacity + "GB") }


} # End Foreach


Write "Test",

$OBJvDataStore | fl

}

}

Thanks in advance, if I need to just upload or copy and paste the entire script, just let me know.  I just didn't think it was needed, because I only have an issue with this one part.  

0 Kudos
13 Replies
LucD
Leadership
Leadership

Can you try something like this ?

$vDataStore = "" | Select Datastore, UsedSpace, Capacity, PercentageFree,"Datastores with low space"
...
if ($vDataStore.PercentageFree -lt 15 -and $vDataStore.Datastore -notmatch 'ISOs') {   $vDatastore."Datastores with low space" = ("{0:N0}% free" -f $vDataStore.PercentageFree) }


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

Thanks, I'm trying to work out the logic on that.  I bumped up the percentage free to 90%, because I know there aren't any datastores with less that 15% now, but I get weird results 

if ($vDataStore.PercentageFree -lt 90 -and $vDataStore.Datastore -notmatch 'ISOs') {
     $vDatastore."Datastores with low space" = ("{0:N0}% free" -f $vDataStore.PercentageFree)
     }
    }
Write "Test",
$vDatastore,
$OBJvDataStore | fl

Here is the output

Datastore                 : --vdisk  #removed name

UsedSpace                 : 984

Capacity                  : 2000

PercentageFree            : 49

Datastores with low space : 49% free

vCenter Datastores                       : 20

Total storage capacity of datastores     : 40(TB)

Total amount of free space on datastores : 17(TB)

0 Kudos
LucD
Leadership
Leadership

Not sure where you see the "weird".

That datastore is 50% used, so 49% free seems reasonable to me.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

More datastores should be showing, there are 20, almost all of them should be showing since I changed to to less than 90% of freespace.  Maybe I'm in the wrong foreach?

0 Kudos
LucD
Leadership
Leadership

I'm not sure how you fit this function in your script, but the function should place the $vDatastore object on the pipeline for each datastore.

You could change the last line to something like this

    ...
   
Write "Test",
   
$OBJvDataStore | fl   
   
$vDataStore
  } }


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

Thanks, I tried that, but it's not working.  I have something wrong in the Foreach section, because even if I say I want to see datastores that are less than 100% it still shows 1 datastore.  Since I know the old script works, I'm going to just dig into it a bit more and see where I made the error.  I'll post the results.  Thanks again Smiley Happy

0 Kudos
LucD
Leadership
Leadership

Can you attach the current version of your script ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

Line 106-119 is where the problem is, I still have small things to add, like automatically connecting to vCenter, but I just have not put them in yet.  The section that starts "$runOnce = 0" (line 106) was from another script I had, I just tried to paste it in, and then work it out, I probably should have just started that part over, but it was right at the end, so I guess I became somewhat lazy about trying to redo it.  Overall, the script outputs just what I want.

Obviously the SMTP address and email addresses are removed.  The only other omission is on line 25 for the name parameter of the Get-Datacenter cmdlet. 

Any help is appreciated, and any critques are welcome (be gentle). 

0 Kudos
LucD
Leadership
Leadership

The problem with this loop is that you will overwrite the properties in $vDatastore for each through the ForEach loop.

You assign a couple of properties outside the loop, that is ok.

But then in the loop, you fill in values for a number of other properties. Unfortunately these are the same properties in the same object. So only the last pass through the loop will be reported.

An alternative would be something like this

  $vAllDataStore = New-Object PSObject
 
$vAllDataStore | Add-Member -MemberType NoteProperty -Name "vCenter Datastores" -Value ($Alldatastore).count
  $vAllDataStore | Add-Member -MemberType NoteProperty -Name "Total storage capacity of datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property CapacityGB -sum).sum) / 1024))" + "(TB)")   $vAllDataStore | Add-Member -MemberType NoteProperty -Name "Total amount of free space on datastores" -Value ("$([Math]::Round((($Alldatastore | measure -Property FreeSpaceGB -sum).sum) / 1024))" + "(TB)")   $runOnce = 0
  $vDatastoreTab = @()

 
Foreach ($datastore in $Alldatastore) {     if ($runOnce -eq 0) {       Write-Host "`r" + "Please do not place any VMs on the following datastores today (" + (Get-date -Format "MM-dd-yyyy") + "), they are low on space: (Never place VMs on the `"ISOs`" datastore)"      Write-Host "`r"      $runOnce++     }     $vDataStore = "" | Select Datastore, UsedSpace, Capacity, PercentageFree
    $vDataStore.Datastore = $datastore.Name
    $vDatastore.UsedSpace = [Math]::Round($datastore.FreeSpaceGB)     $vDataStore.Capacity = [Math]::Round($datastore.CapacityGB)     $vDataStore.PercentageFree = PercentFree $datastore     $vDatastoreTab += $vDatastore

    if ($vDataStore.PercentageFree -lt 90 -and $vDataStore.Datastore -notmatch 'ISOs') { write $vDataStore.Datastore ("{0:N0}% free" -f $vDataStore.PercentageFree),`
      (        "Total amount free = " + $vDataStore.UsedSpace + "GB"),("Total capacity = " + $vDataStore.Capacity + "GB")"`r" }   }   #Writing the results, and the email will display them   Write "Datacenters, Clusters, and ESXi Hosts:",
  $vDataCenter,
  $Cluster,
  $ESXiInfo,
$('*'*100),
  "VM and template information: "`r" ",
  $VM,  $('-'*80),
  "Top ten VMs with the most memory: "`r" ",
 
$TopMemVM,
  "Average memory assigned to VMs in vCenter is: $("$AvgVMMem" + "(MB)")",  $('*'*100),
  "Snapshot Information: "`r"",
  $SnapObj,  $('-'*80),
 
"VMs with 3 or more snapshots: "`r"",
  $Snapshotsover2,
  $('*'*100),
  "Datastore Information: (Never place VMs on the 'ISOs' datastore) "`r" ",
  $vAllDataStore,
  $vDataStoreTab | fl


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

Thanks for the reply again LucD,

I guess that I had not run the entire script in awhile, I was only testing out the section for datastores, since that's what was giving me the problem.  For the section I was testing, I did have the object names different, but not in the actual "final" script.

I'm having a small issue, and I see what it is.  I'm writing all my info, but the way it is for the datastores section, it's writing the datastores with the percentage free that I want, but it's getting written at the very begininng, and not with the datastores section.

I took 3 datastores, and ran the debugger so that I could see.

Please do not place any VMs on the following datastores today (11-19-2012), they are low on space: (Never place VMs on the "ISOs" datastore)



-disk01

10% free

Total amount free = 183GB

Total capacity = 1900GB



Test



vCenter Datastores                       : 3

Total storage capacity of datastores     : 6(TB)

Total amount of free space on datastores : 2(TB)


Datastore      : -disk01

UsedSpace      : 183

Capacity       : 1900

PercentageFree : 10


Datastore      : -disk02

UsedSpace      : 574

Capacity       : 2047

PercentageFree : 28


Datastore      : disk01

UsedSpace      : 989

Capacity       : 2000

PercentageFree : 49

I see what's happening, the IF statement does its job, but since I'm writing out everything in order, the IF statement does not have an order, so it just writes out the info first.

I tried to write out data, and then move the IF statement, but then all the alignment is off, so I just need to see how to save the data in the IF statement and write out under the datastore section.  I'm playing around with it, I'm getting close...I think.

0 Kudos
DZ1
Hot Shot
Hot Shot

Now that I think about it, maybe I should just have the datastore warning first, since a lot of people may not scroll down and view the entire report. 

0 Kudos
LucD
Leadership
Leadership

That sounds like a good idea.

Noteworthy points (and warnings) should better appear in the beginning of a report.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
DZ1
Hot Shot
Hot Shot

Thanks LucD for all of your help.  My script is finished, and of course, I immediately see improvements that I want to make, but those will just need to be put on hold for now.  There is such a stark difference between my first summary script and this one, it looks 10x better.  Well, back to learning Powershell.

0 Kudos