param ( [string]$vCenterServer, [string]$Username, [string]$Password, [string]$LastVM, [switch]$DryRun, # Add a DryRun switch [switch]$Help # Add a Help switch ) # Script Information Write-Host "VMware Emergency Shutdown Script - Paul Mataruso (paulmataruso@dhitechnical.com) v0.1" Write-Host "-----------------------------------------------------------------------------------------" # Display help message if ($Help) { Write-Host "Shutdown VMs PowerCLI Script" Write-Host "----------------------------------------------------" Write-Host "This script connects to a vCenter server and shuts down all running VMs." Write-Host "VMs with VMware Tools installed will be gracefully shut down, others will be powered off." Write-Host "You can specify a VM that should be shut down last using the -LastVM parameter." Write-Host "If no last VM is specified, you will be prompted to select one." Write-Host "" Write-Host "Usage:" Write-Host " .\script.ps1 -vCenterServer -Username -Password [-LastVM ] [-DryRun] [-Help]" Write-Host "" Write-Host "Options:" Write-Host " -vCenterServer Specify the vCenter server hostname or IP." Write-Host " -Username Specify the vCenter login username." Write-Host " -Password Specify the vCenter login password." Write-Host " -LastVM Specify the last VM to be shut down. If omitted, you will be prompted to select one." Write-Host " -DryRun Simulate the shutdown process without making changes." Write-Host " -Help Show this help message." exit } # Import VMware PowerCLI module if (-not (Get-Module -ListAvailable -Name VMware.PowerCLI)) { Write-Host "VMware PowerCLI module is not installed. Installing..." Install-Module -Name VMware.PowerCLI -Scope CurrentUser -Force -SkipPublisherCheck } # Connect to vCenter Write-Host "Connecting to vCenter: $vCenterServer" $securePassword = ConvertTo-SecureString $Password -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential ($Username, $securePassword) Connect-VIServer -Server $vCenterServer -Credential $cred # Get all running VMs $runningVMs = Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" } # Prompt for last VM if not provided if (-not $LastVM) { Write-Host "Select the last VM to shut down:" $vmList = $runningVMs | Select-Object -ExpandProperty Name for ($i = 0; $i -lt $vmList.Count; $i++) { Write-Host "[$i] $($vmList[$i])" } $selection = Read-Host "Enter the number corresponding to the VM" if ($selection -match "^\d+$" -and [int]$selection -ge 0 -and [int]$selection -lt $vmList.Count) { $LastVM = $vmList[[int]$selection] } else { Write-Host "Invalid selection. Exiting." exit } } # Separate the last VM $LastVMInstance = $runningVMs | Where-Object { $_.Name -eq $LastVM } $otherVMs = $runningVMs | Where-Object { $_.Name -ne $LastVM } foreach ($vm in $otherVMs) { Write-Host "Processing VM: $($vm.Name)" if ($vm.ExtensionData.Guest.ToolsStatus -eq "toolsOk") { Write-Host "[DryRun] Would shut down $($vm.Name) gracefully..." if (-not $DryRun) { Shutdown-VMGuest -VM $vm -Confirm:$false } } else { Write-Host "[DryRun] Would force power off $($vm.Name)..." if (-not $DryRun) { Stop-VM -VM $vm -Confirm:$false -Kill } } } # Shutdown last specified VM if ($LastVMInstance) { Write-Host "[DryRun] Would shut down last VM: $($LastVMInstance.Name) last..." if (-not $DryRun) { if ($LastVMInstance.ExtensionData.Guest.ToolsStatus -eq "toolsOk") { Shutdown-VMGuest -VM $LastVMInstance -Confirm:$false } else { Stop-VM -VM $LastVMInstance -Confirm:$false -Kill } } } Write-Host "All VMs processed. Disconnecting from vCenter." Disconnect-VIServer -Server $vCenterServer -Confirm:$false #.\vmshut.ps1 -vCenterServer "vcenter7.dhitechnical.com" -Username "administrator@vsphere.local" -Password "Gx180d132!23456"