Difference between revisions of "Script Extracts and Examples (PowerCLI)"
Jump to navigation
Jump to search
(→ESX Host: Added "Display ESX hosts that are HA Primaries") |
(→Virtual Machine: Added "VM's Recently Created") |
||
Line 689: | Line 689: | ||
Log("All completed") | Log("All completed") | ||
Stop-Transcript | 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. | |||
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"). | |||
<source lang="Powershell"> | |||
$UserFile = "User.fil" | |||
$PassFile = "Pass.fil" # Encrypted file to store password in | |||
$VC_List = "ESX-Check.csv" | |||
$EmailTo = "you@domain.com" | |||
$days = 2 | |||
$NotFoundText = "Not found/gone?" | |||
# Library funcs | |||
function Log ($text) { | |||
[int]$duration = (New-TimeSpan $start (Get-Date)).TotalSeconds | |||
Write-Host "$duration secs | $text" | |||
} | |||
$start = Get-Date | |||
Start-Transcript -Path VMs-Created.log -Append | |||
Log("Started script at $start hrs") | |||
if (!$args[0]) { | |||
Log "No argument passed, using default of VM's created in last $days days." | |||
} else { | |||
$days = $args[0] | |||
Log "Checking for VM's created in last $days days." | |||
} | |||
# Load VMware PS Snapin | |||
Log("Loading VMware PowerShell Snapin...") | |||
Add-PsSnapin *VMware* | |||
# Functions =================================================================================================================================== | |||
function Get-Container ($objVM) { | |||
# Returns either the containing vApp or Folder | |||
if ($objVM.VApp) { | |||
Return $objVM.VApp.Name | |||
} else { | |||
Return $objVM.Folder.Name | |||
} | |||
} | |||
function Get-VMsCreated ([int]$LastDays) { | |||
# Modified from http://get-admin.com/blog/how-to/vmware/powercli-get-every-vm-added-to-vcenter-in-the-last-30-days/ | |||
$EventFilterSpecByTime = New-Object VMware.Vim.EventFilterSpecByTime | |||
if ($LastDays) { | |||
$EventFilterSpecByTime.BeginTime = (get-date).AddDays(-$($LastDays)) | |||
$EventFilterSpecByTime.EndTime = get-date | |||
} | |||
$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec | |||
$EventFilterSpec.Time = $EventFilterSpecByTime | |||
$EventFilterSpec.DisableFullMessage = $False | |||
$EventFilterSpec.Type = "VmCreatedEvent","VmDeployedEvent","VmClonedEvent","VmDiscoveredEvent","VmRegisteredEvent" | |||
$EventManager = Get-View EventManager | |||
$NewVmTasks = $EventManager.QueryEvents($EventFilterSpec) | |||
$VMs = @() | |||
Foreach ($Task in $NewVmTasks) | |||
{ | |||
# If VM was deployed from a template/cloned from VM then record which template/VM. | |||
If ($Task.Template -and ($Task.SrcTemplate.Vm)) { | |||
$srcMachine = (Get-View $Task.SrcTemplate.Vm -Property name).Name | |||
} elseif ($Task.SourceVm.Vm) { | |||
$srcVM = Get-VM -Id $Task.SourceVm.Vm | |||
$srcMachine = (Get-Container $srcVM) + "\" + $srcVM.Name | |||
} Else { | |||
$srcMachine = $null | |||
} | |||
# Create output | |||
$vmCreated = "" | Select VC_Name, VM_Path, VM_Name, Created, ByUser, Method, Source | |||
$vmCreated.VC_Name = $vc.vc | |||
try { | |||
$vmCreated.VM_Path = Get-Container (Get-VM -Id $Task.Vm.Vm -errorAction stop) | |||
if ($vmCreated.VM_Path -eq "vm") { | |||
$vmCreated.VM_Path = "(root)" | |||
} | |||
} catch { | |||
Log("VM not found " + $Task.Vm.name) | |||
$vmCreated.VM_Path = $NotFoundText | |||
} | |||
#$vmCreated.VM_Path = Get-Container (Get-VM -Id $Task.Vm.Vm) | |||
$vmCreated.VM_Name = $Task.Vm.name | |||
$vmCreated.Created = $Task.CreatedTime | |||
$vmCreated.ByUser = [regex]::Replace($Task.UserName, "MPADGLOBAL\\", "") | |||
$vmCreated.Method = $Task.gettype().name # VmDeployedEvent - from template, VmClonedEvent - from existing VM, VmCreatedEvent - from scratch/Convertor import | |||
$vmCreated.Source = $srcMachine | |||
$VMs += $vmCreated | |||
} | |||
$VMs | |||
} | |||
# Business ================================================================================================================================= | |||
# Load list of VC's | |||
try { | |||
$VCs = Import-CSV $VC_List | |||
} catch { | |||
Log("ERROR: Failed to load list of vC's") | |||
Exit | |||
} | |||
# Load password credential from encrypted file | |||
$pass = Get-Content $PassFile | ConvertTo-SecureString | |||
$user = Get-Content $UserFile | |||
$cred = New-Object System.Management.Automation.PsCredential($user, $pass) | |||
# Disconnect any existing VI Server sessions (otherwise you can end up with duplicate VM's) | |||
if ($DefaultVIServers.Count) { | |||
Log("Disconnect existing vCentre server connections...") | |||
Disconnect-VIServer -Server * -Force -Confirm:$false | |||
} | |||
$VMsCreated = @() | |||
# Get VM's from each VC | |||
foreach ($vc in $VCs) { | |||
#if ($vc.vc -eq "lab-manager") { | |||
# Log("Skipping " + $vc.vc) | |||
# Continue | |||
#} | |||
Log("Checking for VMs on " + $vc.vc) | |||
try { | |||
$VCconn = Connect-VIServer -Server $vc.vc -Credential $cred -errorAction stop | |||
} catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidLogin] { | |||
Log("ERROR: Unable to connect to " + $vc.vc + ", invalid logon error !!") | |||
Log("Abandoning further script processing in order to prevent potential account lockout.") | |||
Exit | |||
} catch { | |||
Log("ERROR: Unable to connect to " + $vc.vc) | |||
Log($_) | |||
Continue | |||
} | |||
$VMsCreated += Get-VMsCreated $days | |||
Log("VMs created count now " + $VMsCreated.Length) | |||
Disconnect-VIServer -Server $VCconn -Confirm:$false | |||
} | |||
$VMsCreated | |||
# Create HTML for email | |||
[string]$msgHTML = "<!-- Genenerated by $ScriptName at " + (Get-Date).ToString() + " hrs -->`n" | |||
$msgHTML += "<html xmlns='http://www.w3.org/TR/REC-html40'>`n`n<head>`n<meta http-equiv=Content-Type content='text/html; charset=uk'`n>" | |||
$msgHTML += "<meta name=Generator content='VMs Recently Created script'>`n<meta name=Author content='Simon Strutt'>`n</head>`n`n" | |||
$msgHTML += "<body style='font-family: arial; font-size: 12;'>`n" | |||
$msgHTML += "The following VM's have been created in the last $days days (ie since " + ((Get-Date).AddDays(-$days)).ToString("HH:mm \h\r\s\, ddd dd-MMM-yyyy") + ")," | |||
$msgHTML += " and backup jobs may need to be updated as a result.<br><br>`n" | |||
if (!$VMsCreated.Length) { | |||
$msgHTML += "None !!" | |||
} else { | |||
$msgHTML += "<table border=1 style='border-width: 1px; border-spacing: 1; border-color: black; background-color: #faf0e6; font-family: arial; font-size: 11;'>`n" | |||
$msgHTML += "<tr style='border-width: 2px; border-color: black; background-color: #fcf7f8;'><th>vCentre<th title='vApp or parent folder'>Container<th>VM<th>Created<th>By User<th>Method<th>Source`n" | |||
foreach ($vm in $VMsCreated) { | |||
if ($vm.Created) { | |||
$msgHTML += "<tr><td>" + $vm.VC_Name | |||
if ($vm.VM_Path -eq $NotFoundText) { | |||
$msgHTML += "<td>" + $vm.VM_Path + "<td>" + $vm.VM_Name | |||
} else { | |||
$msgHTML += "<td style='font-weight: bold;'>" + $vm.VM_Path + "<td style='font-weight: bold;'>" + $vm.VM_Name | |||
} | |||
$msgHTML += "<td style='text-align: right;'>" + ($vm.Created).ToString("HH:mm ddd dd-MM-yy") + "<td>" + $vm.ByUser + "<td>" + $vm.Method + "<td>" + $vm.Source + "`n" | |||
} | |||
} | |||
$msgHTML += "</table><br><br>`n" | |||
$msgHTML += "Generated by script: " + ($MyInvocation.MyCommand.Name) + "<br>`n" | |||
$msgHTML += "Sent from machine : $env:computername</body></html>" | |||
} | |||
# Send email | |||
$smtp = New-Object Net.Mail.SmtpClient -arg "mailrelay.uk.michaelpage.local" | |||
$msg = New-Object Net.Mail.MailMessage | |||
$msg.From = "VI-Mgmt@sandfordit.com" | |||
$msg.To.Add($EmailTo) | |||
$msg.Subject = "VMs created in last $days days" | |||
$msg.IsBodyHTML = $true | |||
$msg.Body = $msgHTML | |||
$smtp.Send($msg) | |||
Stop-transcript | |||
</source> | </source> | ||