Difference between revisions of "Virtual Machine Script Extracts and Examples"

Jump to navigation Jump to search
m
Added Google Ad
(Initial creation - content from Script_Extracts_and_Examples_(PowerCLI) page)
 
m (Added Google Ad)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
= VM's with Host and Cluster List =
{{#widget:Widget:GoogleAdSenseSkyscraper}}
= Reporting =
== VM's with Host and Cluster List ==
<source lang="powershell">
<source lang="powershell">
$vms = Get-VM | sort -property Name
$vms = Get-VM | sort -property Name
Line 8: Line 10:
</source>
</source>


= VM's Inventory CSV =
== VM's Inventory CSV ==
Creates a CSV export list of virtual machines.
Creates a CSV export list of virtual machines.


Line 66: Line 68:
</source>
</source>


= VM's with Snapshots Running =
== VM's with Snapshots Running ==
This script generates an email report of virtual machines that have snapshots running.
This script generates an email report of virtual machines that have snapshots running.


Be aware that there's a bug in the way <code>Get-Snapshot</code> handles VM's in VI4, in that for the snapshot size it tends to report the maximum size a snapshot file could become, not the actual size that it is.  As a result there is a workaround to found here - http://blogs.vmware.com/vipowershell/2010/09/snapshot-size.html.  I've found that this reports smaller sizes for VI3 snapshots as well (which match the actual disk usage in the few occasions I've bothered to check).
Be aware that there's a bug in the way <code>Get-Snapshot</code> handles VM's in early versions of PowerCLI v4, in that for the snapshot size it tends to report the maximum size a snapshot file could become, not the actual size that it is.  As a result there is a workaround to found here - http://blogs.vmware.com/vipowershell/2010/09/snapshot-size.html.  I've found that this reports smaller sizes for VI3 snapshots as well (which match the actual disk usage in the few occasions I've bothered to check). In later versions of PowerCLI v4 the problem is partially fixed, in that it works fine for VI4, but now misreports for VI3. 


<source lang="powershell">
<source lang="powershell">
Line 151: Line 153:
...then I've just replaced <code>Get-Snapshot</code> with <code>CalculateVMSnapshotsSizeMB</code>
...then I've just replaced <code>Get-Snapshot</code> with <code>CalculateVMSnapshotsSizeMB</code>


= VM's Effective CPU Shares =
== VM's Effective CPU Shares ==
Calculates the effective relative CPU shares of VM's contained within resource pools.  Can only handle resource pool depth of 1.   
Calculates the effective relative CPU shares of VM's contained within resource pools.  Can only handle resource pool depth of 1.   


Line 230: Line 232:
</source>
</source>


= Ping All VM's On ESX =
== VM's Recently Created ==
Useful sanity check prior to and after network level changes
 
<source lang="Powershell">
$esxToFind = "MyESX*"
 
$ESX = get-vmhost $esxToFind
if (!$ESX) {
    Write-Host "ERROR: No ESX found with name matching expression $esxToFind" -Background Red -ForegroundColor DarkRed
    Exit
}
 
# Get list of VM's on $ESX
$VMs = $ESX | get-vm | Where {$_.PowerState -eq "PoweredOn"} | Sort -property Name
$objPing = New-Object system.Net.NetworkInformation.Ping
 
Foreach ($VM in $VMs) {
    Write-Host $VM.Name.PadRight(20) -nonewline
   
    # Get guest's primary IP address
    $ip = (Get-VMGuest -VM $vm).IPAddress[0]
    if (!$ip) {
        Write-Host "NULL - Skipping test" -Background DarkYellow -ForegroundColor Yellow
        Continue
    }
    Write-Host $ip.PadRight(17) -nonewline
    if ($ip -eq '0.0.0.0') {
        Write-Host "Skipping" -Background DarkYellow -ForegroundColor Yellow
        Continue
    }
       
    [string]$res = $objPing.Send($ip).Status
    if ($res.CompareTo("Success")) {                    # Returns 1 if $res doesn't match "Success" !!
        Write-Host $res -BackgroundColor DarkRed -ForegroundColor Red
    } else {
        Write-Host $res -BackgroundColor DarkGreen -ForegroundColor Green
    }
}
</source>
 
= Enable Change Block Tracking =
This script enables CBT for all VM's managed by the vCentre its run on.  It runs through all VM’s managed by the VC and determines which can be changed, then run through and changes them.
 
Based on the work by ICT-Freak found at http://ict-freak.nl/2009/12/14/powercli-enable-changed-block-tracking/
 
<source lang="Powershell">
$log = "VM-EnableCBT.log"
 
# =====================================================================================================
# Functions...
 
function Log ($text) {
    [int]$duration = (New-TimeSpan $start (Get-Date)).TotalSeconds
    Write-Host "$duration secs | $text"
}
 
Function EnableChangeTracking{
    param($vmObj)
    $vmView = Get-View -VIObject $vmObj
   
    Log ($vmObj.Name + " - Reconfiguring VM for CBT...")
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $vmConfigSpec.ChangeTrackingEnabled = $true
    $task = $vmView.ReconfigVM_Task($vmConfigSpec)
    Wait-Task -Task (Get-VIObjectByVIView -MORef $task) -ErrorAction "SilentlyContinue"
    Sleep 1
 
    Log ($vmObj.Name + " - Creating temp snapshot...")
    $snap = New-Snapshot -Name "Temp snapshot to apply CBT" -VM $vm
   
    Sleep 1
 
    Log ($vmObj.Name + " - Removing temp snapshot...")
    Remove-Snapshot -Snapshot $snap -Confirm:$false
    Log ($vmObj.Name + " - Completed")
}
 
# ======================================================================================================
# The actual script...
 
$start = Get-Date
 
Start-Transcript -Path $log
Log "Started script run at $start"
 
$VMsToDo = @()
 
$VMs = Get-VM | Sort -Property Name
foreach ($vm in $VMs) {
    if (!(($vm.ExtensionData.Config.Extraconfig |?{$_.Key -eq "ctkEnabled"}).Value) -and $vm.Version.ToString() -eq "v7") {
        $VMsToDo += $vm
        Log ($vm.Name + " - Added to ToDo list")
    } else {
        if ((($vm.ExtensionData.Config.Extraconfig |?{$_.Key -eq "ctkEnabled"}).Value)) {
            Log ($vm.Name + " - CBT already enabled")
        } elseif ($vm.Version.ToString() -ne "v7") {
            Log ($vm.Name + " - Not v7, VM hardware version needs to be upgraded !!!")
        }
    }
           
}
Log ("Found " + $VMsToDo.Count + " to enable")
 
foreach ($vm in $VMsToDo) {
    EnableChangeTracking $vm
}
 
Log("All completed")
Stop-Transcript
</source>
 
= VM's Recently Created =
I run the following script twice a week (via a scheduled task), to generate a report of VM's recently created, as a catch-all reminder to check VM backup's, monitoring, etc etc have been set-up as required.  The number of days history it searches through can either be altered in the script (the <code>$days</code> parameter), or passed as a command line parameter when run as a scheduled task.
I run the following script twice a week (via a scheduled task), to generate a report of VM's recently created, as a catch-all reminder to check VM backup's, monitoring, etc etc have been set-up as required.  The number of days history it searches through can either be altered in the script (the <code>$days</code> parameter), or passed as a command line parameter when run as a scheduled task.


The script borrows heavily from http://get-admin.com/blog/how-to/vmware/powercli-get-every-vm-added-to-vcenter-in-the-last-30-days/, which is where the real genius of the script comes from.
The script borrows heavily from http://get-admin.com/blog/how-to/vmware/powercli-get-every-vm-added-to-vcenter-in-the-last-30-days/, which is where the real genius of the script comes from.


I use a username and password file for credentials, see [[#Store_Password_Securely|Store Password Securely]] for more info, plus a CSV with a list of vCentres in (one column with a heading of "vc").
I use a username and password file for credentials, see the note under the script for more info, plus a CSV with a list of vCentres in (one column with a heading of "vc").


<source lang="Powershell">
<source lang="Powershell">
Line 353: Line 244:
$VC_List = "ESX-Check.csv"
$VC_List = "ESX-Check.csv"
$EmailTo = "you@domain.com"
$EmailTo = "you@domain.com"
$EmailServer = "mail.domain.com"
$days = 2
$days = 2
$NotFoundText = "Not found/gone?"
$NotFoundText = "Not found/gone?"
Line 524: Line 416:


# Send email
# Send email
$smtp = New-Object Net.Mail.SmtpClient -arg "mailrelay.uk.michaelpage.local"
$smtp = New-Object Net.Mail.SmtpClient -arg $EmailServer
$msg = New-Object Net.Mail.MailMessage
$msg = New-Object Net.Mail.MailMessage
          
          
Line 537: Line 429:
Stop-transcript
Stop-transcript
</source>
</source>
{{PowerShell_Credentials_Files}}
= Maintenance =
== Ping All VM's On ESX ==
Useful sanity check prior to and after network level changes
<source lang="Powershell">
$esxToFind = "MyESX*"


= Add Attributes to VMs from CSV =
$ESX = get-vmhost $esxToFind
if (!$ESX) {
    Write-Host "ERROR: No ESX found with name matching expression $esxToFind" -Background Red -ForegroundColor DarkRed
    Exit
}
 
# Get list of VM's on $ESX
$VMs = $ESX | get-vm | Where {$_.PowerState -eq "PoweredOn"} | Sort -property Name
$objPing = New-Object system.Net.NetworkInformation.Ping
 
Foreach ($VM in $VMs) {
    Write-Host $VM.Name.PadRight(20) -nonewline
   
    # Get guest's primary IP address
    $ip = (Get-VMGuest -VM $vm).IPAddress[0]
    if (!$ip) {
        Write-Host "NULL - Skipping test" -Background DarkYellow -ForegroundColor Yellow
        Continue
    }
    Write-Host $ip.PadRight(17) -nonewline
    if ($ip -eq '0.0.0.0') {
        Write-Host "Skipping" -Background DarkYellow -ForegroundColor Yellow
        Continue
    }
       
    [string]$res = $objPing.Send($ip).Status
    if ($res.CompareTo("Success")) {                    # Returns 1 if $res doesn't match "Success" !!
        Write-Host $res -BackgroundColor DarkRed -ForegroundColor Red
    } else {
        Write-Host $res -BackgroundColor DarkGreen -ForegroundColor Green
    }
}
</source>
 
== Enable Change Block Tracking ==
This script enables CBT for all VM's managed by the vCentre its run on.  It runs through all VM’s managed by the VC and determines which can be changed, then run through and changes them.
 
Based on the work by ICT-Freak found at http://ict-freak.nl/2009/12/14/powercli-enable-changed-block-tracking/
 
<source lang="Powershell">
$log = "VM-EnableCBT.log"
 
# =====================================================================================================
# Functions...
 
function Log ($text) {
    [int]$duration = (New-TimeSpan $start (Get-Date)).TotalSeconds
    Write-Host "$duration secs | $text"
}
 
Function EnableChangeTracking{
    param($vmObj)
    $vmView = Get-View -VIObject $vmObj
   
    Log ($vmObj.Name + " - Reconfiguring VM for CBT...")
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $vmConfigSpec.ChangeTrackingEnabled = $true
    $task = $vmView.ReconfigVM_Task($vmConfigSpec)
    Wait-Task -Task (Get-VIObjectByVIView -MORef $task) -ErrorAction "SilentlyContinue"
    Sleep 1
 
    Log ($vmObj.Name + " - Creating temp snapshot...")
    $snap = New-Snapshot -Name "Temp snapshot to apply CBT" -VM $vm
   
    Sleep 1
 
    Log ($vmObj.Name + " - Removing temp snapshot...")
    Remove-Snapshot -Snapshot $snap -Confirm:$false
    Log ($vmObj.Name + " - Completed")
}
 
# ======================================================================================================
# The actual script...
 
$start = Get-Date
 
Start-Transcript -Path $log
Log "Started script run at $start"
 
$VMsToDo = @()
 
$VMs = Get-VM | Sort -Property Name
foreach ($vm in $VMs) {
    if (!(($vm.ExtensionData.Config.Extraconfig |?{$_.Key -eq "ctkEnabled"}).Value) -and $vm.Version.ToString() -eq "v7") {
        $VMsToDo += $vm
        Log ($vm.Name + " - Added to ToDo list")
    } else {
        if ((($vm.ExtensionData.Config.Extraconfig |?{$_.Key -eq "ctkEnabled"}).Value)) {
            Log ($vm.Name + " - CBT already enabled")
        } elseif ($vm.Version.ToString() -ne "v7") {
            Log ($vm.Name + " - Not v7, VM hardware version needs to be upgraded !!!")
        }
    }
           
}
Log ("Found " + $VMsToDo.Count + " to enable")
 
foreach ($vm in $VMsToDo) {
    EnableChangeTracking $vm
}
 
Log("All completed")
Stop-Transcript
</source>
 
 
== Add Attributes to VMs from CSV ==
You have the option in vCentre to create your own custom attributes to any of the standard objects.  This can be incredibly useful if you have a sprawling estate of VM's to manage for various different parts of your company, as you can record information like Owning Dept., Product Family etc against your VM's.   
You have the option in vCentre to create your own custom attributes to any of the standard objects.  This can be incredibly useful if you have a sprawling estate of VM's to manage for various different parts of your company, as you can record information like Owning Dept., Product Family etc against your VM's.   


Line 678: Line 685:
Stop-Transcript
Stop-Transcript
</source>
</source>
{{PowerShell_Credentials_Files}}


= Migrate VMs Between vCentres =
== Migrate VMs Between vCentres ==
The following script will migrate virtual machines from one vCentre to another, so long as both have a shared datastore.
The following script will migrate virtual machines from one vCentre to another, so long as both have a shared datastore.


Line 783: Line 791:
Stop-Transcript
Stop-Transcript
</source>
</source>
{{PowerShell_Credentials_Files}}
== Set VM Tools to Update Automatically on VM Reboot ==
Keeping VM Tools up to date is like [http://www.wikipedia.org/wiki/Forth_Railway_Bridge#Maintenance painting the Forth Bridge] (an endless task which, just as you finish, another ESX release goes live and you start all over again).  A useful, but almost hidden feature, is that which allows VM's to automatically update when they're being bounced.  Meaning that some VM's will be upgraded when machines are being otherwise rebooted.
The following script, applies the setting to all VM's managed by a vCentre, but you can edit the <code> Get-VM </code> line to select the VM's you want to change.  Note that you might want to disable the feature, in which case change <code> $UpgradePolicy = "manual" </code>.
Despite the '''Check and upgrade Tools before each power on''' option being greyed out for powered on VM's in VI3, this script will still change the setting. Which is nice.
<source lang="powershell">
<# ========================================================================================================================================
  Set VM's to automatically upgrade VMTools on reboot
  =========================================================================================================================================
  Simon Strutt        Feb 2012
  =========================================================================================================================================
 
  Script expects you to be connected to your vCentre already, applies the change to all managed VM's
 
Version 1
  - Initial creation
 
==========================================================================================================================================#>
$UpgradePolicy = "upgradeAtPowerCycle"      # Other option: manual
Write-Host "Setting all VM Tool's upgrade policy to $UpgradePolicy"
Write-Host "Get list of VMs to update..."
$vms = Get-VM
Write-Host ("...got " + $vms.count + " VMs")
# Create config spec to apply
$VMcfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$VMcfgSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
$VMcfgSpec.Tools.toolsUpgradePolicy = "upgradeAtPowerCycle"
# Go through all the VM's and update
$count = 0
foreach ($vm in $vms) {
    $count ++
    Write-Progress -Activity "Applying 'upgradeAtPowerCycle' setting to VMs" -Status ("Updating " + $vm.Name) -PercentComplete ($count/($vms.count)*100)
   
    # Get current setting
    $vmView = Get-View $vm -Property Config.Tools.ToolsUpgradePolicy
    # Change if setting isn't as we want
    if ($vmview.Config.Tools.ToolsUpgradePolicy -ne $UpgradePolicy) {
        $vmView.ReconfigVM($VMcfgSpec)
    }
}
Write-Host "Job done!"
</source>
See http://communities.vmware.com/message/1601811 for further info.
[[Category:PowerCLI]]
[[Category:Virtual Machine]]

Navigation menu