Originally published February 20, 2017 @ 1:21 am
Below is a collection of useful Power-CLI one-liners (or thereabouts) that can speed up your script-writing efforts. As everything Windows, things change often and for no obvious reason, so expect to see type is deprecated
and parameter is obsolete
warnings now and then.More often than not, they’re harmless: they like changing things but usually don’t have the balls to actually remove something.
Import-Module VMware.VimAutomation.Vds $VMHost="vcenter01.krazyworks.local" Connect-VIServer -Server $VMHost
Get some info on the basket with all of your eggs
# Get a list of ESX hosts Get-VMHost | Format-Table -Auto # Some more info Get-VMHost | Format-List # And some more Get-VMHost | foreach-object {(Get-View $_.ID).Config.Product } # Get a list of datastores Get-Datastore | Format-Table -Auto # As above but more details Get-Datastore | Format-List # Get a list of VMDKs on a particular datastore Get-HardDisk -Datastore datastore_name | Format-Table -Auto # Get a list of of 10 largest VMDKs on a particular datastore Get-HardDisk -Datastore syno-iscsi-01 | Sort-Object CapacityGB -Descending | Format-Table -Auto | Select -First 10
Creating spreadsheets
# Set target directory and name of the output CSV file $userhome = get-content env:userprofile; $enddate = (Get-Date).tostring("yyyy-MM-dd_HHmmss"); $outfile = $userhome + '\Documents\vcenter_report_' + $enddate + '.csv'; # Append this to the end of any list-generating command to output to CSV | Export-Csv -NoTypeInformation -path $outfile
Get a list of templates with name matching:
# List templates in Datacenter1 containing "rhel7_64_build" in the name Get-Template -Location "Datacenter1" -name "*rhel7_64_build*"
Get a list of VMs with name matching:
# Select VM called "hostname1" $VMs = Get-VM | Where-Object { $_.Name -match 'hostname1'} # Select VMs named "hostname1*", or "hostname3*" $VMs = Get-VM | Where-Object { $_.Name -like 'hostname1*' -or $_.Name -like 'hostname3*'} # Select VMs named "hostname1*", but not "hostname10*" $VMs = Get-VM | Where-Object { $_.Name -like 'hostname1*' -and $_.Name -notlike 'hostname10*'} # Select VMs named "hostname1*", but not "hostname10*" with description containing "decom" or in powered-off state Get-VM | Where-Object {$_.Name -like 'hostname1*' -and $_.Name -notlike 'hostname10*' -and ($_.Description1 -like '*decom*' -or $_.PowerState -match 'PoweredOff')}
Get VM details:
# Get VMWare-Tools version for VMs matching 'prod*' name Get-VM | Where-Object { $_.Name -like 'prod*'} |% { get-view $_.id } | select Name, @{ Name=";ToolsVersion";; Expression={$_.config.tools.toolsVersion}} | Format-Table -Auto
Below is a quick PowerShell script to gather VM details based on the VM name regular expression. Note the Where-Object
syntax and modify to suit your needs.
Import-Module VMware.VimAutomation.Vds; $VMHost="vcenter1.your.domain"; Connect-VIServer -Server $VMHost; $userhome = get-content env:userprofile; $enddate = (Get-Date).tostring("yyyy-MM-dd_HHmmss"); $outfile = $userhome + '\Documents\vcenter_report_' + $enddate + '.csv'; Get-VM | Where-Object {$_.Name -like [regex]"[pd]lhttp*" -and $_.PowerState -match 'PoweredOn'} | Select Name, @{N="IP";E={@($_.Guest.IPAddress[0])}}, @{N="MAC";E={($_ | Get-NetworkAdapter).MacAddress -join ", "}}, @{N="NIC";E={$vNicInfo = Get-VM -Name $_ | Get-NetworkAdapter; $Result = foreach ($vNic in $VnicInfo) {"{0}={1}"-f ($vnic.Name.split("")[2]), ($vNic.Type)}; $Result -join (", ")}}, @{N="VLAN";E={($_ | Get-NetworkAdapter).NetworkName -join ", "}}, @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, NumCPU, MemoryGB, @{N="SizeGB";E={[math]::round($_.ProvisionedSpaceGB, 1)}}, @{N="HDDs (GB)";E={[math]::round(($_ | get-harddisk | select-object -ExpandProperty CapacityGB) -join " + ", 1)}}, Version, @{N="Boot Time";E={(Get-Date).AddSeconds(- (Get-Stat -Entity $_ -Stat sys.uptime.latest -Realtime -MaxSamples 1).value).ToString("yyyy-MM-dd HH:mm:ss")}}, @{N="Running OS";E={$_.ExtensionData.Guest.GuestFullName}}, @{N="VMTools";E={$_.ExtensionData.Guest.ToolsRunningStatus + " version " + $_.ExtensionData.Guest.ToolsVersion + ", " + $_.ExtensionData.Guest.ToolsVersionStatus}}, @{N="VMX";E={$_.ExtensionData.config.files.VMpathname}}, @{N="VMDK";E={($_ | Get-HardDisk).filename -join ", "}}, @{N="Snapshots";E={($_ | get-snapshot).count}}, @{N="Cluster";E={Get-Cluster -VM $_}}, @{N="ESX Host";E={Get-VMHost -VM $_}}, @{N="Datastore";E={Get-Datastore -VM $_}} | Export-Csv -NoTypeInformation -path $outfile;
Generate a datastore audit report in CSV format showing capacity, provisioned, and available space
$report = @() foreach($cluster in Get-Cluster){ Get-VMHost -Location $cluster | Get-Datastore | %{ $info = "" | select DataCenter, Cluster, Name, Capacity, Provisioned, Available $info.Datacenter = $_.Datacenter $info.Cluster = $cluster.Name $info.Name = $_.Name $info.Capacity = [math]::Round($_.capacityMB/1024,2) $info.Provisioned = [math]::Round(($_.ExtensionData.Summary.Capacity - $_.ExtensionData.Summary.FreeSpace + $_.ExtensionData.Summary.Uncommitted)/1GB,2) $info.Available = [math]::Round($info.Capacity - $info.Provisioned,2) $report += $info } } $report | Export-Csv "C:\datastore_report.csv" -NoTypeInformation -UseCulture
Same as above, but one cluster per Excel spreadsheet tab
foreach($cluster in Get-Cluster){ $report = @() Get-VMHost -Location $cluster | Get-Datastore | %{ $info = "" | select DataCenter, Cluster, Name, Capacity, Provisioned, Available $info.Datacenter = $_.Datacenter $info.Cluster = $cluster.Name $info.Name = $_.Name $info.Capacity = [math]::Round($_.capacityMB/1024,2) $info.Provisioned = [math]::Round(($_.ExtensionData.Summary.Capacity - $_.ExtensionData.Summary.FreeSpace + $_.ExtensionData.Summary.Uncommitted)/1GB,2) $info.Available = [math]::Round($info.Capacity - $info.Provisioned,2) $report += $info } $report | Export-Xls -Path C:\datastore_report.xls -WorksheetName $cluster.Name -SheetPosition "end" }
Generate a VMDK report in Excel format showing VM name, datastore, VMDK path, storage format, and capacity
$VMs = Get-VM * $Data = @() foreach ($VM in $VMs){ $VMDKs = $VM | get-HardDisk foreach ($VMDK in $VMDKs) { if ($VMDK -ne $null){ $CapacityGB = $VMDK.CapacityKB/1024/1024 $CapacityGB = [int]$CapacityGB $into = New-Object PSObject Add-Member -InputObject $into -MemberType NoteProperty -Name VMname $VM.Name Add-Member -InputObject $into -MemberType NoteProperty -Name Datastore $VMDK.FileName.Split(']')[0].TrimStart('[') Add-Member -InputObject $into -MemberType NoteProperty -Name VMDK $VMDK.FileName.Split(']')[1].TrimStart('[') Add-Member -InputObject $into -MemberType NoteProperty -Name StorageFormat $VMDK.StorageFormat Add-Member -InputObject $into -MemberType NoteProperty -Name CapacityGB $CapacityGB $Data += $into } } } $Data | Sort-Object VMname,Datastore,VMDK | Export-Xls -Path C:\vmdk_report.xls -NoTypeInformation -UseCulture
Get a list of Snapshots
# Show all snapshots for all VMs Get-VM | Get-Snapshot # Show any snapshots older than 7 days and their sizes Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-7)} | Select-Object VM, Name, Created, @{N="SizeGB";E={[math]::round($_.SizeGB, 1)}} # Same as above, but nicely formatted Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-7)} | Select-Object VM, Name, Created, @{N="SizeGB";E={[math]::round($_.SizeGB, 1)}} | Sort SizeGB | Format-Table -Auto
Create Snapshots
# Snapshot all VMs called prod* with snapshot description $Description = (Get-Date).ToString("yyyy-MM-dd")+'_before_patching' New-Snapshot -VM vmname -Name $Description Get-VM | Where-Object { $_.Name -like 'prod*'} | New-Snapshot -Name $Description
Delete the Snapshots
# Remove all snapshots for a VM Get-VM -Name vmname | Get-Snapshot | Remove-Snapshot # Remove a particular snapshot Get-VM -Name vmname | Get-Snapshot -Name snapshot_name | Remove-Snapshot # Remove all snapshots older than 90 days from all VMs Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-90)} | Remove-Snapshot
Disk Consolidation
# Get a list of VMs in need of disk consolidation Get-VM | Where-Object {$_.Extensiondata.Runtime.ConsolidationNeeded} # Consolidate disks on all VMs that need it Get-VM | Where-Object {$_.Extensiondata.Runtime.ConsolidationNeeded} | foreach {$_.ExtensionData.ConsolidateVMDisks_Task()}
# Give VM 2 CPU sockets get-VM -name vmname | set-VM -NumCpu 2 -Confirm:$false # Give VM 2 CPU sockets with 2 cores in each $VM=Get-VM -Name vmanme $VMSpec=New-Object –Type VMware.Vim.VirtualMAchineConfigSpec –Property @{“NumCoresPerSocket” = 2} <em>$VM.ExtensionData.ReconfigVM_Task($VMSpec) $VM | Set-VM -NumCPU 2</em> # Get a list of VMs with CPU reservations Get-VM | Get-VMResourceConfiguration | where {$_.CPUReservationMhz -ne '0'} | Sort-Object NumCpuShares -Descending | Format-Table -Auto # Get a list of VMs with CPU reservations and set reservations to zero Get-VM | Get-VMResourceConfiguration | where {$_.CPUReservationMhz -ne '0'} | Set-VMResourceConfiguration -CPUReservationMhz 0 # Get a list of VM with CPU limit set Get-VM | Get-VMResourceConfiguration | where {$_.CPULimitMhz -ne '-1'} | Format-Table -Auto # As above and unset the CPU limit Get-VM | Get-VMResourceConfiguration | where {$_.CPULimitMhz -ne '-1'} | Set-VMResourceConfiguration -CPULimitMhz $null
# Give VM 2GB of RAM Get-VM -Name vmname | Set-VM -MemoryGB 2 # Reduce RAM to 1GB (requires shutdown) Get-VM -Name vmname | Shutdown-VMGuest | Set-VM -MemoryGB 1 # Double VM's RAM Set-VM -VM vmname -MemoryGB ((Get-VM -Name vmname).MemoryGB * 2) # Set VM RAM to match another VM Set-VM -VM vmname -MemoryGB (Get-VM -Name vmname2).MemoryGB # Get a list of VMs with memory reservations Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'} | Format-Table -Auto # As above and unset memory reservations Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'} | Set-VMResourceConfiguration -MemReservationMB 0 # Get a list of VMs with memory reservations and the amount of associated datastore free space ForEach ($vm in (Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'} | ForEach {$_.VM})){Get-VM $vm | Select Name,PowerState,@{N="Reservation";E={Get-VMResourceConfiguration -VM $_ | ForEach {$_.MemReservationMB}}},@{N="Datastore";E={Get-Datastore -VM $_}},@{N="Datastore Free Space";E={Get-Datastore -VM $_ | ForEach {$_.FreeSpaceMB}}}} # Remove memory reservations on VMs if there is enough free datastore space ForEach ($vm in (Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'} | ForEach {$_.VM})){ # $name = (Get-VM $vm | ForEach {$_.Name}) $powerstate = (Get-VM $vm | ForEach {$_.PowerState}) [int]$reservation = (Get-VMResourceConfiguration -VM $vm | ForEach {$_.MemReservationMB}) $datastore = (Get-Datastore -VM $vm ) [int]$dsfreespace = $datastore.FreeSpaceMB [int]$numberofds = (Get-Datastore -VM $vm |Measure-object).Count write-host "VM = $vm `n`t PowerState = $powerstate `n`t Memory Reservation = $reservation `n`t DataStore VM = $datastore `n`t Free Space on datastore = $dsfreespace `n`t Number of Datastores is $numberofds" if ((($dsfreespace - $reservation) -gt "0") -and ($numberofds -eq "1")){ Write-Host "Now removing the memory reservation $reservation for VM $vm" -ForegroundColor Green Get-VMResourceConfiguration -VM $vm | Set-VMResourceConfiguration -MemReservationMB 0 } else { Write-Host "Memory reservation ($reservation) cannot be removed because there is not enough free space on the datastore, or because the VM has multiple datastores." -ForegroundColor Red } } # Get a list of VMs with memory limit Get-VM | Get-VMResourceConfiguration | where {$_.MemLimitMB -ne '-1'} | Format-Table -Auto
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.