Powerdown VMs

I am looking for a powercli/pworshell script to power down VMs safely in a datacenter.
I have both windows and Linux VMs.
I will appreciate if anyone help me on this.
LVL 2
sara2000Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ITguy565Commented:
This should do what you want it to:

Function powerdownVM($Computername, $Hypervisor, [switch]$graceful, [switch]$Force, [switch]$StartVM ){
    $vm = get-vm -computername $($hypervisor) |? {$_.name -like "*$($computername)*"}
        if ($vm.name -eq "$($computername)"){
            if ($graceful.IsPresent){
                write-host "Gracefully shuttingdown ... $($computername)"
                $vm|stop-vm -Force -whatif
            }
            if ($Force.IsPresent){
                write-host "Forcing $($computername) to poweroff"
                $vm|stop-vm -TurnOff -whatif
            }
            if ($StartVM.IsPresent) {
                write-host "Starting $($computername)"
                $vm|start-vm -name $computername -whatif
            }
        }
}

Open in new window



This code is in test mode and you will need to remove -whatif from both lines if you want to run the code in production.


commandline syntax is as follows :

for a graceful shutdown
. PowerdownVM -computername  [Computer you want to powerdown] -Hypervisor [Host that hosts the VM] -graceful

for a forced shutdown
. PowerdownVM -computername  [Computer you want to powerdown] -Hypervisor [Host that hosts the VM] -force
 
To turn the VM back on
. PowerdownVM -computername  [Computer you want to powerdown] -Hypervisor [Host that hosts the VM] -Start-VM
ITguy565Commented:
This should work for both Linux and Windows
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

ITguy565Commented:
My script above works on Hyper-V, however I am unsure if it will work on ESX and can't test it..

This one I am going to provide based on the command reference manuals online but I can't test it..


Function powerdownVM($Computername, $Hypervisor, [switch]$graceful, [switch]$Force, [switch]$StartVM ) {
    $vm = get-vm -computername $($hypervisor) |? {$_.name -like "*$($computername)*"}
    if ($vm.name -eq "$($computername)") {
        if ($graceful.IsPresent) {
            write-host "Gracefully shuttingdown ... $($computername)"
            $vm| Shutdown-VMGuest -whatif
        }
        if ($Force.IsPresent) {
            write-host "Forcing $($computername) to poweroff"
            Function Kill-VM {
                                param (
                                    [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
                                    $VM, $KillType
                                )
                                PROCESS {
                                    if ($VM.PowerState -eq "PoweredOff") {
                                        Write-Host "$($VM.Name) is already Powered Off"
                                    }
                                    Else {
                                        $esxcli = Get-EsxCli -vmhost ($VM.VMHost)
                                        $WorldID = ($esxcli.vm.process.list() | Where { $_.DisplayName -eq $VM.Name}).WorldID
                                        if (-not $KillType) {
                                            $KillType = "soft"
                                        }
                                        $result = $esxcli.vm.process.kill($KillType, $WorldID)
                                        if ($result -eq "true") {
                                            Write-Host "$($VM.Name) killed via a $KillType kill"
                                        }
                                        Else {
                                            $result
                                        }
                                    }
                                }
                            }
            $vm |Kill-VM -KillType Hard -whatif


        }
        if ($StartVM.IsPresent) {
            write-host "Starting $($computername)"
            $vm|start-vm
        }
    }
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sara2000Author Commented:
i have to power down multiple VMs at once.
i have to find the way to get-VMs and power down  or Get-Content of a file.
ITguy565Commented:
Before I convert this to multiple VM's please make sure it works on a single. As I said before, I have not been able to test this as I do not have ESX to test on.
ITguy565Commented:
If you test the above code and it functions correctly, this should give you the functionality from an imported file :

$computers = import-csv "c:\temp2\Computers.csv"

<# CSV with three columns
Name,Hypervisor,typeofshutdown


typeofshutdown can support 2 values :

Graceful, Force
#>

Function powerdownVM($Computername, $Hypervisor, [switch]$graceful, [switch]$Force, [switch]$StartVM ) {
    $vm = get-vm -computername $($hypervisor) |? {$_.name -like "*$($computername)*"}
    if ($vm.name -eq "$($computername)") {
        if ($graceful.IsPresent) {
            write-host "Gracefully shuttingdown ... $($computername)"
            $vm| Shutdown-VMGuest -whatif
        }
        if ($Force.IsPresent) {
            write-host "Forcing $($computername) to poweroff"
            Function Kill-VM {
                                param (
                                    [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)]
                                    $VM, $KillType
                                )
                                PROCESS {
                                    if ($VM.PowerState -eq "PoweredOff") {
                                        Write-Host "$($VM.Name) is already Powered Off"
                                    }
                                    Else {
                                        $esxcli = Get-EsxCli -vmhost ($VM.VMHost)
                                        $WorldID = ($esxcli.vm.process.list() | Where { $_.DisplayName -eq $VM.Name}).WorldID
                                        if (-not $KillType) {
                                            $KillType = "soft"
                                        }
                                        $result = $esxcli.vm.process.kill($KillType, $WorldID)
                                        if ($result -eq "true") {
                                            Write-Host "$($VM.Name) killed via a $KillType kill"
                                        }
                                        Else {
                                            $result
                                        }
                                    }
                                }
                            }
            $vm |Kill-VM -KillType Hard -whatif


        }
        if ($StartVM.IsPresent) {
            write-host "Starting $($computername)"
            $vm|start-vm
        }
    }
}

foreach ($comp in $computers){
    if ($comp.typeofshutdown -eq "Graceful"){
        . PowerdownVM -computername $($comp.Name) -Hypervisor $($comp.Hypervisor) -graceful
    }
    if ($comp.typeofshutdown -eq "Force"){
        . PowerdownVM -computername $($comp.Name) -Hypervisor $($comp.Hypervisor) -force
    }
}

Open in new window


Please be aware that this script is presented in test mode and will not power down your machines until you remove the -whatif parameter from the 2 lines it exists in.
line 17 and 46


In order to run my script all you need to do is create a CSV with Three Columns, save to or change the location in the following line

"c:\temp2\Computers.csv"
 
Save the file to yourfilename.ps1
Name,Hypervisor,typeofshutdown

Note: Name and Hypervisor speak for themselves,
  • The typeofshutdown column is currently able to support two values, Graceful or Force  



If you use graceful it will shutdown the VM gracefully if you use force it will power it off.
Ajay ChananaMCSE-2003/08|RHCSA| VCP5/6 |vExpert2018Commented:
Get-VM VMNAME | Shutdown-VMGuest
Shutdowns the guest OS of the virtual machine named VM.
Ajay ChananaMCSE-2003/08|RHCSA| VCP5/6 |vExpert2018Commented:
This is the simplest script which I can share to shutdown multiple VM as per your list in .csv file  If you wish to test only use -whatif parameter instead of -confirm:$false.

$VMList = Import-CSV -Path C:\vm.csv
foreach ($vm in $VMList)
{ Get-VM $vm.Name| Shutdown-VMGuest -Confirm:$false}
David Johnson, CDRetiredCommented:
hyper-v uses the command stop-vm -name vmname    # uses the guest operating system shutdown
stop-vm -name vmname -force   # forces a shutdown, allows 5 minute grace to save data
stop-vm -name vmname -turnoff   # equivalent to pulling out the power cord on a physical machine

functions should precede the code that calls the function.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VMware

From novice to tech pro — start learning today.