VMware utility I built – results are wrong after one pass through

Welcome Forums General PowerShell Q&A VMware utility I built – results are wrong after one pass through

Viewing 2 reply threads
  • Author
    Posts
    • #235423
      Participant
      Topics: 3
      Replies: 4
      Points: 37
      Rank: Member

      I have been writing a powershell utility to help with admin tasks. I will say right now I am a powershell novice, it is not something I have done for a long time, so my apologies on sloppy/archaic coding. I built a menu with ‘switch’ and put all the code I want to run pretty much in the menu. The only way I saw to branch out and do a loop was using functions. In testing the code I finally realized after executing each menu item once if I go back and try previous items they fail (or do not give the intended result). If I kill the ISE and start script again it works. Sometimes output gets cut off (missing the column labels), other times it seems like the code displays the members or properties of an object rather than just the title row and objects below it. Again , sorry if this is bad coding, I wouldn’t ask if I haven’t been beating myself up over this and going nuts. See below:

      # vCenter VM Utility

      #Temp folder setup
      $UtilTemp = “c:\temp\” + “VMutility-” + (get-date -format “MM-dd-yyyy”)
      Write-Host
      write-host “–>Temp folder setup”
      if (test-path $UtilTemp){
      write-host “–>Temp folder exists”
      }else {
      write-host “–>Creating temp folder at ” $UtilTemp
      new-item -path $UtilTemp -itemtype directory > $null
      }

      #Set variables
      $dt = get-date -format “MM/dd/yyyy HH:mm”

      #Get username and password via popup
      $UnamePW = get-credential -message “Please enter your full vCenter Username and Password”
      $user = $UnamePW.username
      $Creds = New-Object System.Management.Automation.PSCredential -ArgumentList $UnamePW.username ,$UnamePW.password
      $pwvsan = $Creds.GetNetworkCredential().Password

      #Clear the screen
      cls

      #Get the vCenter Server to work with
      $vServer = Read-Host -Prompt “IP of desired vCenter Server to process”
      if ($vServer -as [IPaddress] -as [Bool]){
      write-host
      } else {mh
      write-host “Your entry was not a valid IP address”
      exit
      }

      #Connect to vCenter
      Set-PowerCLIConfiguration -InvalidCertificateAction ignore -confirm:$false > $null
      connect-viserver -server $vServer -user $user -password $pwvsan > $null

      function get-decision {
      $EntRet = Read-Host “Press ENTER to return to the menu”
      if ($EntRet.length -eq “”) {
      show-menu
      } else {
      get-decision}
      }

      #Function to display menu
      function show-menu {
      [email protected]
      1 View vCenter Hosts & statistics
      2 Shut down host VM’s
      3 Power on host VMs
      4 Display VM Guest statistics
      5 Display VM snapshots
      6 Display datastore statistics
      7 Change selected host to process
      8 Backup Host and vSwitch configurations
      Q Quit

      Select a task by number or Q to quit
      “@
      cls
      start-sleep -m 250
      write-host
      Write-Host “*** VM Utility Menu ***” -ForegroundColor Cyan
      write-host
      write-host “You have selected vCenter Server: ” $vServer -ForegroundColor Green
      write-host “You have selected host: ” $vhost -ForegroundColor Green
      write-host

      $sel = Read-Host $menu

      Switch ($sel) {
      “1” {
      Write-Host “View vCenter Hosts and statistics on” $Vserver -ForegroundColor Green
      $VChostsStat = get-vmhost
      $VChostsStat
      start-sleep -m 250
      get-decision
      }
      “2” {
      write-host
      Write-Host “Shut down host VM’s…” -ForegroundColor Green

      #Process completed messages
      write-host “VM’s on this host are in file: ” $hostfile -ForegroundColor Green
      write-host “The following VM’s will be shut down on host:” $vhost -ForegroundColor Green
      write-host

      #Parse VM’s in the file
      $vmnfile = get-content -path $hostfile | select-object -skip 4
      foreach ($vm in $vmnfile){
      write-host $vm
      }
      $yesno = Read-Host (“Are you sure you want to power off these VM’s? (y/n)”)
      if ($yesno -eq “n”) {
      write-host “‘n’ was chosen, returning to the main menu”
      start-sleep -S 3
      show-menu
      } elseif ($yesno -eq “y”) {
      #power off VM’s here
      write-host “y was chosen”
      }
      else
      {
      write-host “Neither ‘y’ or ‘n’ was chosen, returning to the main menu”
      start-sleep -S 3
      show-menu
      }
      }
      “3” {
      write-host
      Write-Host “Power on host VMs…” -ForegroundColor Green
      #insert your code here
      get-decision
      }
      “4” {
      write-host
      Write-Host “Displaying VM Guest statistics for host: ” $vhost -ForegroundColor Green
      $VMstats = get-vmhost -name $vhost | get-vm | Where-Object {$_.powerstate -eq ‘PoweredOn’} | Select Name,VMhost,NumCpu,MemoryGB,@{ n=”SpaceUsedGB”; e={[math]::round( $_.usedspacegb, 1 )}} | ft
      write-host
      $vmcount = $VMstats.count
      $VMstats
      write-host “Total VM’s = ” $vmcount

      #Write VM statistics to a csv file at $UtilTemp
      $statfile = ($UtilTemp + “\” + “\VMstats-” + $vhost + “.csv”)
      get-vmhost -name $vhost | get-vm | Select Name,VMhost,NumCpu,MemoryGB,@{ n=”SpaceUsedGB”; e={[math]::round( $_.usedspacegb, 1 )}} | Export-Csv $statfile -NoTypeInformation
      get-decision
      }
      “5” {
      write-host
      Write-Host “Displaying VM snapshots for host: “$vhost -ForegroundColor Green
      $SNAPvms = get-vmhost -name $script:vhost | get-vm
      $sshots = Get-Snapshot -vm $SNAPvms | Select VM, Description, Created, @{ n=”SizeMB”; e={[math]::round( $_.SizeMB, 2 )}} | ft
      $sshots
      get-decision
      }
      “6” {
      Write-Host “View vCenter datastore statistics…” -ForegroundColor Green
      $vDatastore = get-datastore
      $vDatastore
      start-sleep -m 250
      clear-variable “vDatastore”
      get-decision
      }
      “7” {
      Write-Host “Change selected host to process: ” $vhost -ForegroundColor Green
      $VMChangeHost = get-vmhost
      $VMChangeHost
      get-vhost
      start-sleep -m 250
      show-menu
      }
      “8” {
      write-host
      Write-Host “Backup Host and vSwitch configurations…” -ForegroundColor Green
      $gethosts = Get-VMHost | select -expandproperty name
      write-host
      write-host -ForegroundColor green (“***Starting Host backups***”)
      foreach($esxhost in $gethosts)
      {
      write-host -foregroundcolor green (“Now backing up Host Configuration–> “+ $esxhost )
      Get-VMHostFirmware -VMHost $esxhost -BackupConfiguration -DestinationPath $UtilTemp > $null
      }
      write-host -foregroundcolor green (“***Backup of Host configs is now complete!***”)
      write-host

      #Backup the VDS’s
      $getvds = Get-VDSwitch | select -expandproperty name
      write-host -foregroundcolor green (“***Now backing up Virtual Distributed Switch configurations***”)
      foreach($VDS in $getVDS)
      {
      write-host -foregroundcolor green (“Now backing up Virtual Distributed Switch–> “+$VDS )
      export-vdswitch -vdswitch $VDS -description “VDS Configuration Backup” -destination ($UtilTemp+”\”+$VDS+”.zip”) -Force > $NULL
      }
      write-host -foregroundcolor green (“***Backup of VDS configs is now complete!***”)
      write-host
      get-decision
      }
      “Q” {
      Write-Host “Quitting!” -ForegroundColor Green
      }
      default {
      Write-Host “I don’t understand what you want to do.” -ForegroundColor Yellow
      }
      }
      }

      #Funtion to get the host you want to work with
      #Remember to make a variable global use ‘script:’
      function get-vhost {
      #Get the host to work with, creates $hostfile
      write-host
      $script:vhost = Read-Host -Prompt “IP of desired ESXi host to process”
      if ($vhost -as [IPaddress] -as [Bool]){
      write-host “Processing selected host…”
      $script:hostfile = $UtilTemp + “\” + (“Host-” + $vhost + “.txt”)
      } else {
      write-host “Your entry was not a valid IP address”
      exit
      }
      #Get the VM’s on the specified host
      $hostvms = get-vmhost -name $vhost | get-vm | Where-Object {$_.powerstate -eq ‘PoweredOn’}
      $vmcount = $hostvms.count

      #Wite host VM’s to a file
      $fileheader = (“*** The total number of powered on VM’s on host ” + $vhost + ” = ” + $vmcount + ” ***”)
      $dt | out-file $hostfile
      Add-Content $hostfile “”
      $fileheader | out-file $hostfile -append
      Add-Content $hostfile “”
      $hostvms.name | out-file $hostfile -append

      }

      #Get the host to work with
      get-vhost

      #Display menu
      show-menu

      exit

      #Ensure no connections are present
      #disconnect-viserver -server $vserver -force -confirm:$false

      #Clean up
      disconnect-viserver -server $vserver -confirm:$false
      clear-variable -name “user”
      clear-variable -name “pwvsan”

      If there is a better way to insert code let me know!FRUSTRATED!

       

    • #235426
      Participant
      Topics: 5
      Replies: 2372
      Points: 6,005
      Helping Hand
      Rank: Community MVP

      Alan, welcome to Powershell.org. Please take a moment and read the very first post on top of the list of this forum: Read Me Before Posting! You’ll be Glad You Did!.

      When you post code, error messages, sample data or console output format it as code, please.
      In the “Text” view you can use the code tags “PRE“, in the “Visual” view you can use the format template “Preformatted“. You can go back edit your post and fix the formatting – you don’t have to create a new one.
      Thanks in advance.

      That’s a lot of code. I think it’s beyond the scope a forum to debug or refactor such a bit complete script. You might start with a smaller version of your script and when this smaller version works as expected you add more functions to it.

    • #235789
      Participant
      Topics: 3
      Replies: 4
      Points: 37
      Rank: Member

      No, I get it . I know it’s a lot to ask but I have been beating my head against the wall and getting very frustrated. All the code did start out as workable little pieces and then I put the individual pieces in to the main program. I’m convinced it has to do with powershell scopes to a degree. I restart the ISE and the code works again. Running it in a command window yields the same results of not working correctly.

      If I have to I’ll break it all apart again. This is more keep busy work than anything but trying to fill my time.

      …Alan

Viewing 2 reply threads
  • You must be logged in to reply to this topic.