Home » Posts tagged 'PowerCLI'

Tag Archives: PowerCLI

SRM And PowerShell

PowerShell can be a great way to help you create the site recovery you really want. This article talks about installing PowerCLI on a SRM server installed as described here. Also, running the script automatically and adding them into your recovery plan will be discussed.

Installing PowerShell

We have a Site Recovery Server 5.1 server which is installed as described here. To install PowerCLI we first have to install PowerShell, which, on Windows Server 2008 R2 is a feature and can be installed as such:

  • Start Server Manager
  • Click Add Feature
  • Check the “Windows PowerShell Integrated Scripting Environment (ISE)” checkbox and select the .NET Framework dependency
  • Click Next, Install, and Close.

Now we can install PowerCLI. We’ll use PowerCLI 5.1 R2, which was released on 2013-02-11 and is released as this executable:

  • VMware-PowerCLI-5.1.0-1012425.exe

Run the executable as an administrator and keep all the defaults during installation.

Also, to speed up PowerCLI go to the control panel → Internet Options → Advanced tab → Security Section → Uncheck the “Check for publisher’s certificate revocation” checkbox.

Now, start PowerCLI as an administrator using the shortcuts on the desktop and issue:

Set-ExecutionPolicy RemoteSigned -force
Set-PowerCLIConfiguration -InvalidCertificateAction ignore -ProxyPolicy NoProxy -Confirm:$False
Note: For more information regarding installing, configuring and getting started with PowerShell and PowerCLI see Getting Started with PowerShell and vSphere PowerCLI.
Note: In case you also use 32 bits commands you should also do this in the PowerCLI for 32 bits.

Managing PowerCLI Scripts Authentication

Create a AD service account and grant the account the following permissions:

  • Member of Domain Users
  • Member of the local administrators group
    • Open Server Manager → Configuration → Local Users and Groups –> Groups → Add service account to Administrators group
  • Log on as a service permission
    • Open gpedit.msc → Computer Configuration → Windows Settings → Security Settings → Local Policies → User Rights Assignment → Add service account to “Log on as a service”
  • vCenter permissions
    • Grant the account administrator permissions at the vCenter of the recovery site
Note that the vCenter permissions might be a bit too much. You could just grant permissions at the correct cluster, or use specific roles.

Then configure the SRM service to run under this account:

  • Open services.msc → VMware vCenter Site Recovery Manager Server → Log On → Enter the service account credentials.

Restart the service to make sure the created account works and test your Site Recovery Manager setup.

Adding a PowerCLI Script to a Recovery Plan

Because adding scripts to recovery plans will be a common tasks we put some extra effort in making this look nice. Because adding a powershell script to a recovery plans uses a lot of text in the commands this means it gets quite confusing and unreadable. To prevent this we’ll use a redirect command. Create a redirect.cmd in the same location where your scripts will be stored and put the following lines in it:

redirect.cmd:

@echo off
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -psc "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1" "& '%1'"

Now you can add a powershell script to a recovery plan like this:

  • Select the recovery plan that should run the script and select the “Recovery Steps” tab.
  • Select the step where you want to run the script before or after and click “Add Step:
  • Now fill in the required settings
  • And click ok.

For reference, the command in the Command Step is this:

c:\windows\system32\cmd.exe /C g:\scripts\redirect.cmd g:\scripts\srmrdms.ps1

Note that without the redirect script you should use this command, and would have to load the VMware snap-ins inside the script:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File g:\scripts\srmrdms.ps1

srmpowershell01.jpg 

You have now added an extra step to the recovery plan to run a script, which in this case sets the RDM settings correctly.

Source: http://www.getshifting.com/wiki/srmpowershell

PowerCLI Usefull Scripts And Commands

PowerCLI Usefull Scripts And Commands

This is an overview page with small PowerCLI scripts and or commands.

Getting all Possible Values for Objects

If only I knew then what I know now! When working on Script: PowerCLI: Create CSV with VMInfo I spent some serious time on finding what properties and values are available on certain objects. Today I finally figured it out, simply use “Select *”:

[vSphere PowerCLI] C:\> Get-NetworkAdapter -vm testvm01 | select *
    MacAddress       : 00:50:56:89:2e:18
WakeOnLanEnabled : True
NetworkName      : SFT0-VLAN2
Type             : Flexible
ParentId         : VirtualMachine-vm-117451
Parent           : testvm01
Uid              : /VIServer=@localhost:443/VirtualMachine=VirtualMachine-vm-11
                   7451/NetworkAdapter=4000/
ConnectionState  : Connected:True
ExtensionData    : VMware.Vim.VirtualPCNet32
Id               : VirtualMachine-vm-117451/4000
Name             : Network adapter 1

Commands And OneLiners

VM with CPU Reservation

Get-VM | Get-VMResourceConfiguration | where {$_.CPUReservationMhz -ne '0'}

And setting the CPU reservation to 0:

Get-VM | Get-VMResourceConfiguration | where {$_.CPUReservationMhz -ne '0'} | Set-VMResourceConfiguration -CPUReservationMhz 0

Get All VMs and IP Addresses

Get-VM | Select Name, @{N="IP Address";E={@($_.guest.IPAddress[0])}}

Export to CSV:

Get-VM | Select Name, @{N="IP Address";E={@($_.guest.IPAddress[0])}} | Export-Csv c:\serverandip.csv

VM with CPU Limit

Get-VM | Get-VMResourceConfiguration | where {$_.CPULimitMhz -ne '-1'}

And setting the CPU limit to unlimited:

Get-VM | Get-VMResourceConfiguration | where {$_.CPULimitMhz -ne '-1'} | Set-VMResourceConfiguration -CPULimitMhz $null

VM with Memory Reservation

Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'}

And setting the memory reservation to 0:

Get-VM | Get-VMResourceConfiguration | where {$_.MemReservationMB -ne '0'} | Set-VMResourceConfiguration -MemReservationMB 0

Note that if you change the memory reservation, and there is not enough free space in the datastore the next time the VM is powered on the operation will fail. To prevent this you can see all this information with this command:

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}}}}

This is a small script to automatically remove the reservation if the datastore has enough free 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
  }
}
Note: if you just want to view the VMs for which the change cannot be done automatically comment the other Write-Host lines out.

VM with Memory Limit

Get-VM | Get-VMResourceConfiguration | where {$_.MemLimitMB -ne '-1'}

And setting the memory limit to unlimited:

Get-VM | Get-VMResourceConfiguration | where {$_.MemLimitMB -ne '-1'} | Set-VMResourceConfiguration -MemLimitMB $null

Get All CPU and Memory Values

$startdir = "D:\sjoerd"
$csvfile = "$startdir\memlimits.csv"
  $myCol = @()
  foreach ($VM in (Get-VM | Get-VMResourceConfiguration | where {$_.MemLimitMB -ne '-1'})){
  $vmview = Get-VM $VM | Get-View   $VMInfo = "" |select-Object VMName,CPUReservation,CPULimit,CPUShares,NumCPU,MEMSize,MEMReservation,MEMLimit,MEMShares
$VMInfo.VMName = $vmview.Name
$VMInfo.CPUReservation = $vmview.Config.CpuAllocation.Reservation
If ($vmview.Config.CpuAllocation.Limit-eq "-1"){$VMInfo.CPULimit = "Unlimited"}
Else{$VMInfo.CPULimit = $vmview.Config.CpuAllocation.Limit}
$VMInfo.CPUShares = $vmview.Config.CpuAllocation.Shares.Shares
$VMInfo.NumCPU = $VM.NumCPU
$VMInfo.MEMSize = $vmview.Config.Hardware.MemoryMB
$VMInfo.MEMReservation = $vmview.Config.MemoryAllocation.Reservation
If ($vmview.Config.MemoryAllocation.Limit-eq "-1"){$VMInfo.MEMLimit = "Unlimited"}
Else{$VMInfo.MEMLimit = $vmview.Config.MemoryAllocation.Limit}
  $myCol += $VMInfo
}
  $myCol |Export-csv -NoTypeInformation $csvfile

VMWare Tools Version

get-vm |% { get-view $_.id } | select Name, @{ Name=";ToolsVersion";; Expression={$_.config.tools.toolsVersion}}

Get Hosts with Specific Version

get-vmhost | where-object { $_.version -eq "4.1.0" } | select name,version

Get Datastores and Used Storage for VMs within Cluster

Get-Cluster "Acceptance" | Get-VM | Select Name, @{N="Datastore";E={Get-Datastore -vm $_}}, UsedSpaceGB, ProvisionedSpaceGB  | sort Name | Export-Csv F:\Scripts\Output\datastores-acceptance.csv

Get All Datastores for All Clusters and See Usage

ForEach ($cluster in get-cluster){get-cluster "$cluster" | Get-VMHost | select -first 1 | get-datastore | where {$_.name -like "?_*"} | Select Name,FreeSpaceMB,CapacityMB,@{N="Number of VMs";E={@($_ | Get-VM).Count}},@{N="VMs";E={@($_ | Get-VM | ForEach-Object {$_.Name})}},@{N="VM Size";E={@($_ | Get-VM | ForEach-Object {$_.UsedSpaceGB})}} | Export-Csv D:\sjoerd\datastore-$cluster-overview.csv}

Get Number of Paths in Use per Host within Cluster

Get-Cluster "Acceptance" | Get-VMHost | where {$_.State -eq "Connected"} | Select Name, @{N="TotalPaths";E={($_ | Get-ScsiLun | Get-ScsiLunPath | Measure-Object).Count}}

Scan Storage for all Hosts within Cluster

ForEach ($esxhost in (Get-Cluster "Acceptance" | Get-VMHost)) {Get-VmHostStorage $esxhost -RescanAllHba}

Set MPIO Settings for All Hosts in Cluster

ForEach ($esxhost in (Get-Cluster "Acceptance" | Get-VMHost)) {D:\tools\plink -ssh $esxhost -l root -pw <fillinpw> /opt/ontap/santools/config_mpath --primary --loadbalance --policy fixed}

Count the Number of VMs in a Cluster That Match a Name Pattern

get-cluster "acceptance" | get-vm | where {$_.name -match "prd"} | measure-object

Get all Dead Paths In a Datacenter

ForEach ($vmhost in (Get-Datacenter "The Netherlands" | Get-Vmhost | Sort)){ $deadpaths = Get-ScsiLun -vmhost $vmhost | Get-ScsiLunPath | where {$_.State -eq "Dead"} | Select ScsiLun,State; Write-Host $vmhost $deadpaths}

Get All LUN IDs in use on an ESX Server

Get-ScsiLun -vmhost esx01 -luntype disk | select runtimename | sort runtimename

Get All LUN IDs in use on a NetApp Filer

Get-NaLun | get-nalunmap | select Path,LunId | Sort LunId

Get All Volumes From NetApp Filer

This will get you all Volumes from a NetApp Filer that start with a capital R and an underscore, separated by a comma, and copied to the clipboard. I needed this to get all volumes that are part of replication:

import-module D:\sjoerd\dataontap
connect-nacontroller filer01 -credential (Get-credential)
(Get-NaVol | where {$_.name -like "R_*"} | select name -expandproperty Name) -join ',' | clip

Working with Credentials

If you need to submit credentials for connecting to something you can do this to get a prompt for entering the credentials in stead of having to put them on the commandline:

Connect-NaController filer01 -Credential (Get-Credential)

Get the Number of VMs on all Datastores in a Datacenter

Get-Datastore | where {$_.datacenter -match "The Netherlands"} | Select Name, @{N="Number of VMs";E={@($_ | Get-VM).Count}} | Sort "Number of VMs"

Get All VMs with Old Hardware Level Version

Get-Cluster "Acceptance" | Get-VM | Get-View | Where {$_.Config.Version -ne "vmx-09"} | Select Name | Sort Name

Set VM Description with CSV File

Note: This command will overwrite the existing descriptions, so make sure you do not overwrite anything important.

You need to create a simple csv file which looks like this:

VMName,Description
server01,Domain Controller
server02,Database Server

The second step is to run this command:

Import-Csv "D:\sjoerd\description.csv" | % { Set-VM $_.VMName -Description $_.Description -Confirm:$false}

That’s all!

Scripts

Save the code on your management workstation in a simple textfile, and change the extention to “.ps1”. Now you can run them from powershell like any executable.

Resource Pools with Ballooning and Swapping

$myCol = @()
foreach($clus in (Get-Cluster)){
 foreach($rp in (Get-ResourcePool -Location $clus | Get-View | Where-Object `
  {$_.Name -ne "Resources" -and `
   $_.Summary.QuickStats.BalloonedMemory -ne "0"})){
   $Details = "" | Select-Object Cluster, ResourcePool, `
   SwappedMemory ,BalloonedMemory   $Details.Cluster = $clus.Name
    $Details.ResourcePool = $rp.Name
    $Details.SwappedMemory = $rp.Summary.QuickStats.SwappedMemory
    $Details.BalloonedMemory = $rp.Summary.QuickStats.BalloonedMemory   $myCol += $Details
  }
}
$myCol

VMs with Ballooning and Swapping

$myCol = @()
foreach($vm in (Get-View -ViewType VirtualMachine | Where-Object `
  {$_.Summary.QuickStats.BalloonedMemory -ne "0"})){
   $Details = "" | Select-Object VM, `
   SwappedMemory ,BalloonedMemory   $Details.VM = $vm.Name
    $Details.SwappedMemory = $vm.Summary.QuickStats.SwappedMemory
    $Details.BalloonedMemory = $vm.Summary.QuickStats.BalloonedMemory   $myCol += $Details
  }
$myCol

VMs Network Info

(get-vm) | %{
  $vm = $_
  echo $vm.name----
  $vm.Guest.Nics | %{
    $vminfo = $_
    echo $vminfo.NetworkName $vminfo.IPAddress $vminfo.MacAddress
    echo ";`n";
  }
}

VMs Boot Time

$LastBootProp = @{
  Name = 'LastBootTime'
    Expression = {
      ( Get-Date ) - ( New-TimeSpan -Seconds $_.Summary.QuickStats.UptimeSeconds )
	}
}
  Get-View -ViewType VirtualMachine -Property Name, Summary.QuickStats.UptimeSeconds | Select Name, $LastBootProp

Reading Values for Properties from CSV file

This little snippet will set the memory reservations for a VM from a csv file. This is useful if you want to rollback a change and you remembered to make a csv file with VM information. You can use the list to make a separate vms.txt file as input as well as a vmsinput.txt file with reservation settings:

vms.txt:

WINXP-TESTVM2
WINXP-TESTVM3
WINXP-TESTVM4

vmsinput.txt:

VMName,MEMReservation
WINXP-TESTVM2,128
WINXP-TESTVM3,256
WINXP-TESTVM4,128
$sourcevms = "C:\Users\sjoerd\Desktop\powercli scripts\vms.txt"
$sourcememory = "C:\Users\sjoerd\Desktop\powercli scripts\vmsinput.txt"
  $list = Get-Content $sourcevms | Foreach-Object {Get-VM $_ }   foreach($item in $list){
                $vm = $item.Name
		# The line below gives all information in @= format. This is not directly usable. 				
		$memres = import-csv $sourcememory | where-object {$_.vmname -eq "$vm"} 
		# With this you get only the value of the property in the variable.
		$memresvm = $memres.MEMReservation
		Get-VM $vm | Get-VMResourceConfiguration | where {$_.MemReservationMB -eq '0'} | Set-VMResourceConfiguration -MemReservationMB $memresvm
		}
 

Combining PowerCLI and Powershell

This snippet queries the windows host machine for the uptime. 

$vms = get-vm | where { ($_.PowerState -eq "PoweredOn") } | get-view | where { ($_.Guest.GuestFamily -eq "windowsGuest") }   foreach ($vm in $vms) {
   $vmname = $vm.name
   $hostname = $vm.Guest.HostName
   write-host "Starting with $vmname with hostname $hostname"
   Get-WmiObject -computer $hostname
   $objUptime = (Get-WmiObject -computer $hostname -class Win32_PerfFormattedData_PerfOS_System).SystemUpTime
   write-host "$vmname heeft $objUptime as uptime"
}

Resources