Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
NLVMUG– 16 maart 2017
Breng jouw PowerCli script naar een hoger (sneller)
niveauBouke Groenescheij – Jume BV
Bouke Groenescheij• Eigenaar / Consultant / Trainer
• Jume BV
• vSphere / VRO / PowerCLI / API / DevOPS
• W: www.jume.nl
• E: [email protected]
• T: @boukeg
• F: 06-21873858
Waarom deze sessie?
• Versnelling van je scripts
• Toename in robuustheid
• 100% controlle over ALLE method & properties
• Eenvoudige vertaling andere programmeertalen
• Verlaging van belasting op vCenter en server/werkstation
• Omdat het leuk en leerzaam is
Agenda
• get-blabla -> get-view –viewtype “blabla”
• Properties & Filters voor get-view
• Methods vs. Properties
• MoRef & vSphere API + Onyx
• COTL Methode
• Array / Hashtable
• Connectie naar meerdere vCenters + issues & oplossing
• Jobs
• Voorbeelden
• Vragen
Get-VM / Get-VMHost / Get-Cluster / Get-Folder / Get-Datacenter / Get-...
• Cmdlets zijn eenvoudig in gebruik, altijd volledig, leggen relaties en doen error-checking. Dat doet get-view niet!!!
• $vmsview = get-view -ViewType "VirtualMachine"
• Accepted types: ClusterComputeResource, ComputeResource, Datacenter, Datastore, DistributedVirtualPortgroup, DistributedVirtualSwitch, Folder, HostSystem, Network, OpaqueNetwork, ResourcePool, StoragePod, VirtualApp, VirtualMachine, VmwareDistributedVirtualSwitch
Get-view -Property
• Haalt alleen de benodigde properties op
• Beschikbare properties:
get-view -viewtype "VirtualMachine" | get-member | ? {$_.MemberType -eq"Property"}
• Properties kunnen properties bevatten
Get-view -Filter
• Filter op een property• Op basis van @{<string>,<string>} hash
• Bij meerdere properties een ‘AND’
• Zoekterm is RegEx!!!
• Voorbeelden• get-view -ViewType "VirtualMachine"
• -Filter @{"Name" = "-a"}
• -Filter @{"Name" = "^Photon-A5A3jILeE$"}
• -Filter @{"Runtime.PowerState" = "poweredOff";"Runtime.Host" = "host-9"}
• -Filter @{"Name" = "^Photon-A5A3jILeE$|^Photon-83X9bxiv3$"}
Methods vs. Properties
• Properties zijn eigenschappen (waarden)
• Methods zijn acties
• get-view -viewtype "..." | get-member | ? {$_.MemberType -eq "Method"}
Methods/Properties vs. MoRef browser (API)
• Methods & Properties komen grotendeels overeen met de vSphere API call
• Ook te zien via de MoRef Browser
• ALLES kan dus gedaan worden via het verkregen object met get-view!
MoRef vs. Relaties
• Ieder object in vCenter heeft een uniek id (MoRef)
• Relatie tussen de verschillende componenten is relatief met MoRef id als key
• Datacenter <-> Cluster <-> Host <-> VM, Folder <-> <VIObj>
• Kijk naar properties zoals ‘Parent’ Of ‘Child’
• Get-View –Id <MoRef>
Relatie leggen met Array vs Hashtable
• Array is een lijst van objecten (met properties & methods)
$array = @()
$array += "Eric Sloof"
$array += "Bouke Groenescheij“
$array[0]
Eric Sloof
• Hashtable is een key-value pair
$hash = @{}
$hash.add("eric","Eric Sloof")
$hash.add("bouke","Bouke Groenescheij")
$hash."bouke"
Bouke Groenescheij
Kracht van hashtable
• Supersnel
• Laag resource verbruik
• Kan objecten bevatten (zowel key als value)
• Heeft unieke keys
• $vmsviewhash = @{}
• $vmsview | ForEach-Object {$vmsviewhash.Add($_.Moref,$_)}
• Persoonlijk gebruik ik zo veel mogelijk hashtables!!!
COTL
• Collect Once Then Loop
• Verzamel alle data in 1 keer, hergebruik deze objecten
• Voorbeelden volgen
Connectie naar meerdere vCenters
• MoRef is uniek binnen vCenter
• MoRef is niet altijd uniek bij meerdere vCenters
• Issue met hashtable:
• Issue met array icm where-object• Meer compare operators nodig
Oplossing voor meerdere vCenters
• Naar MoRef is altijd Client beschikbaar
• ServiceUrl gebruiken icm MoRef
Method gedrag
• Bij gelijkwaardige objecten in dezelfde state is de method direct beschikbaar:
• Niet zo: $objects | % {$_.Method}
• Maar zo: $objects.Method
• Als een _Task van een method beschibaar is, gebruik deze• Zo: $objects.Method_Task
• Methods worden sequentieel uitgevoerd!!!
vSphere API Object inheritance
• vSphere API respecteert OOP
• Object inheritance (overerving)
• Check SDK Documentation:• https://www.vmware.com/support/developer/vc-sdk/
• Voorbeeld:
$allmacs = ($thevmsview.Config.Hardware.Device | Where-Object {$_ -is [VMware.Vim.VirtualVmxnet3]}).MacAddress
$allmacs = ($thevmsview.Config.Hardware.Device | Where-Object {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress
VIObjectByVIView
$cat = Get-TagCategory "Phase"
$thevmviews = get-view -ViewType "VirtualMachine" -filter @{"Name"="^Photon-29z7SnOxA$"}
$thevms = $thevmviews | Get-VIObjectByVIView
$myTagAssignment = Get-TagAssignment $thevms -Category $cat
• Toch een VIObject nodig voor bepaalde cmdlets?
Jobs
• Gebruik jobs voor parallel processing
• Een job draait in eigen memory space
• Initialiseren van PowerCLI is nodig
• Jobs komen met ‘kosten’ (cpu / memory)
• Voorkeur is scripts aan te roepen vanuit scriptblock
• Gebruik ‘SessionSecret’ om vanuit de job direct in vCenter in te loggen
Jobs
foreach ($HostView in $HostsView) {
$rescanjob = {
if (!(Get-Module -Name VMware.VimAutomation.Core) -and (Get-Module -ListAvailable -Name VMware.VimAutomation.Core)) {
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
connect-viserver $args[0] -session $args[1] -WarningAction:Ignore -ErrorAction:Stop | out-null
try {
Write-Host "Info - Rescanning host: $($args[2])"
$esxhostview = Get-View -ViewType "hostsystem" -Property "ConfigManager.StorageSystem" -Filter@{"Name" = "^" + $args[2] + "$"}
$cmss = get-view $esxhostview.ConfigManager.StorageSystem -Property "availableField"
$cmss.RescanAllHba()
}
catch {
Write-Host "Info - Something went wrong while rescanning host: $($args[2])"
}
Write-Host "Info - Script ended with arguments: vcenter:$($args[0]), esxhost:$($args[2])"
}
$vcenter = ($HostView.Client.ServiceUrl).split("/")[2]
$session = $HostView.Client.SessionSecret
$esxhost = $HostView.Name
start-job -argumentlist $vcenter,$session,$esxhost -scriptblock $rescanjob | out-null
}
Onyx
• ‘Specs’ kunnen lastig zijn te definieren
• Project Onyx helpt hierbij
• https://labs.vmware.com/flings/onyx-for-the-web-client
Voorbeelden
• get-vm one-liner naar get-view• https://ict-freak.nl/2009/11/17/powercli-one-liner-to-get-vms-clusters-esx-
hosts-and-datastores/
• Array vs. Hashtable relaties
• Methods
• Types
• Bonus: group-object cmdlet
• Job
• Specs: 2 vCenters, 3 hosts, 1000 VMs, 10 datastores
Get-VM | Select-Object Name, `
@{N="Cluster";E={(Get-Cluster -VM $_ | Select-Object "Name").Name}}, `
@{N="HAEnabled";E={(Get-Cluster -VM $_ | Select-Object "HAEnabled").HAEnabled}}, `
@{N="DRSEnabled";E={(Get-Cluster -VM $_ | Select-Object "DRSEnabled").DRSEnabled}}, `
@{N="ESX Host";E={(Get-VMHost -VM $_ | Select-Object "Name").Name}}, `
@{N="PowerState";E={(Get-VMHost -VM $_ | Select-Object "PowerState").PowerState}}, `
@{N="Model";E={(Get-VMHost -VM $_ | Select-Object "Model").Model}}, `
@{N="Datastore";E={(Get-Datastore -VM $_ | Select-Object "Name").Name}}, `
@{N="FreeSpaceGB";E={(Get-Datastore -VM $_ | Select-Object "FreeSpaceGB").FreeSpaceGB}}, `
@{N="FileSystemVersion";E={(Get-Datastore -VM $_ | Select-Object "FileSystemVersion").FileSystemVersion}} | `
Export-Csv -NoTypeInformation result-langzaam.2.csv
Resultaten
• TotalSeconds : 520,9315386
Jobs
$vmsview = get-view -ViewType "VirtualMachine"
$computesview = get-view -ViewType "ComputeResource"
$hostsview = get-view -viewtype "HostSystem"
$datastoreview = get-view -viewtype "Datastore"
$results = @()
foreach ($vmview in $vmsview) {
$row = "" | Select-Object "Name","Cluster","HAEnabled","DRSEnabled","ESX Host","PowerState","Model","Datastore","FreeSpaceGB","FileSystemVersion"
$row.Name = $vmview.Name
$hostobj = $hostsview | Where-Object {$_.MoRef -eq $vmview.Runtime.Host -and $_.Client.ServiceUrl -eq $vmview.Client.ServiceUrl}
$row."ESX Host" = $hostobj.Name
$row."PowerState" = $hostobj.Runtime.PowerState
$row."Model" = $hostobj.Hardware.SystemInfo.Model
$hostparentobj = $computesview | where-object {$_.Moref -eq $hostobj.Parent -and $_.Client.ServiceUrl -eq $vmview.Client.ServiceUrl}
if ($hostparentobj -is [VMware.Vim.ClusterComputeResource]) {
$row.Cluster = $hostparentobj.name
$row.HAEnabled = $hostparentobj.Configuration.DasConfig.Enabled
$row.DRSEnabled = $hostparentobj.Configuration.DrsConfig.Enabled
} else {
$row.Cluster = $null
$row.HAEnabled = $null
$row.DRSEnabled = $null
}
$datastores = @()
$datastoresfree = @()
$datastoresversion = @()
foreach ($ds in $vmview.Datastore) {
$dsview = ($datastoreview | where-object {$_.moref -eq $ds -and $_.Client.ServiceUrl -eq $vmview.Client.ServiceUrl})
$datastores += $dsview.name
$datastoresfree += $dsview.Info.FreeSpace / 1Gb
$datastoresversion += $dsview.Info.Vmfs.Version
}
Resultaten
• TotalSeconds : 9,4216488• (CPU te laag om verandering te zien...)
• Na optimilisaties:• Hashtable• Beperkte Properties
• TotalSeconds : 1,0042037
• 518x sneller!!!
Bonus Group-Object
$poweredOn = @()
$poweredOff = @()
$unknown = @()
foreach ($vmview in $vmsview) {
if ($vmview.Runtime.PowerState -eq "poweredOn") {
$poweredOn += $vmview
} elseif ($vmview.Runtime.PowerState -eq "poweredOff") {
$poweredOff += $vmview
} else {
$unknown += $vmview
}
}
Bonus Group-Object
$vmsview = get-view -ViewType "VirtualMachine"
$groupedvmsview = $vmsview | Group-Object -Property{$_.Config.Template} -AsHashTable -AsString
Bonus Group-Object
• Met 1000 VMs weinig verschil
• Met 13000+
• 12x sneller!
Job (master-job)
$HostsView = $esxhostview = Get-View -ViewType "hostsystem" -Property "name"
foreach ($HostView in $HostsView) {
$rescanjob = {
set-location $args[0]
$scriptPath = $args[0]
powershell -command "$($scriptPath)\job-slave.ps1 -vcenter $($args[1]) -session$($args[2]) -esxhost $($args[3])"
}
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$vcenter = ($HostView.Client.ServiceUrl).split("/")[2]
$session = $HostView.Client.SessionSecret
$esxhost = $HostView.Name
start-job -argumentlist $scriptPath,$vcenter,$session,$esxhost -scriptblock $rescanjob |out-null
}
Job (slave-job)
param($vcenter,$session,$esxhost)
Write-Host "Info - Script starts with arguments: vcenter:$($vcenter), esxhost:$($esxhost)"
if (!(Get-Module -Name VMware.VimAutomation.Core) -and (Get-Module -ListAvailable -Name VMware.VimAutomation.Core)) {
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue
}
connect-viserver $vcenter -session $session -WarningAction:Ignore -ErrorAction:Stop | out-null
try {
Write-Host "Info - Rescanning host: $($esxhost)"
$esxhostview = Get-View -ViewType "hostsystem" -Property "ConfigManager.StorageSystem" -Filter @{"Name" = "^" + $esxhost + "$"}
$cmss = get-view $esxhostview.ConfigManager.StorageSystem -Property "availableField"
$cmss.RescanAllHba()
}
catch {
Write-Host "Info - Something went wrong while rescanning host: $($esxhost)"
}
Write-Host "Info - Script ended with arguments: vcenter:$($vcenter), esxhost:$($esxhost)"
Job (master-job)
$somejobsrunning = $true
do {
Write-Host "Some rescan jobs are still running"
Get-Job | Receive-Job
$jobs = Get-Job
$groupedjobs = $jobs | Group-Object "State"
if ($groupedjobs.Values.Count -eq 1 -and $groupedjobs.Name -eq"Completed") { $somejobsrunning = $false }
Start-Sleep 1
}
while ($somejobsrunning)
Get-Job | Receive-Job
Get-Job | Remove-Job
Bonus tips
• Check out Visual Studio Code!!!
• https://blogs.vmware.com/PowerCLI/2015/02/get-view-part-1-introduction.html
• https://blogs.vmware.com/PowerCLI/2015/02/get-view-part-2-views-extension-data.html
• https://blogs.vmware.com/PowerCLI/2015/06/get-view-part-3-peformance-really-much-different.html
Vragen