Thursday, June 20, 2013

Using PowerCLI to export DRS details...vCenter 5.1 migration part 2

Ok, this past week has been busy as I still have tons of hosts to get up to ESXi 5.1...I'm just so glad vCenter is done :)  Now there are quite a few details that can be contained within DRS and I knew what settings I used and wrote the scripts specifically for those.

For DRS, I just needed to know the rules (affinity and anti-affinity)

Lets look at how I dumped the DRS rules (I'm obviously not the only one who has done this):


param(
 [Parameter(Mandatory=$true)][string] $VIserver = $(Read-Host -prompt "vCenter?")
)

$vc=connect-viserver $VIserver

$outfile = "rules_$($vc.name).csv"
$rules = get-cluster -server $vc| Get-DrsRule
$output=@()
if ($rules -ne $NULL)
{
 foreach($rule in $rules){
   $line=""|select Cluster,Name,Enabled,KeepTogether,VM1,VM2
   $line.cluster = (Get-View -Id $rule.ClusterId).Name
   $line.name = $rule.Name 
   $line.Enabled = $rule.Enabled
   $line.KeepTogether = $rule.KeepTogether
   $line.VM1 = (get-view -id ($rule.VMIds)[0]).name
   $line.VM2 = (get-view -id ($rule.VMIds)[1]).name
   $output+=$line
 }
}
$output|export-csv -notypeinformation $outfile
disconnect-viserver * -confirm:$false -force

...now, of course an import script would make this so much more useful.

param(
 [Parameter(Mandatory=$true)] [string] $inputfile = $(Read-Host -prompt "input file?"),
 [Parameter(Mandatory=$true)] $VIserver = $(Read-Host -prompt "VIserver?")
 )

$vc=connect-viserver $VIserver
$rules=import-csv -path $inputfile
if($rules -eq $NULL){throw "Could not read $inputfile"}

$clusters=$rules|select cluster|sort cluster|Get-Unique -AsString|%{$_.cluster}
foreach ($cluster in $clusters)
{
 $clusterrules = $rules|?{$_.cluster -eq $cluster}
 $clusterobj=get-cluster $cluster
 foreach ($rule in $clusterrules)
 {new-drsrule -cluster $clusterobj -Name $rule.name -Enabled ([system.convert]::toBoolean($rule.enabled)) `
  -KeepTogether ([system.convert]::toBoolean($rule.keeptogether)) -VM (get-vm $rule.vm1,$rule.vm2)} 
}

disconnect-viserver * -confirm:$false -force

Alright, there we have it. First script dumps ALL rules for all clusters in a vCenter, while the second script creates those rules on the corresponding clusters in the new vCenter. I know I haven't gone over the cluster creation scripts yet, but I thought it was better to go over the export/import in one post, not exactly chronological, very much related.

Thursday, June 6, 2013

Using Powershell to Export VM details...vCenter 5.1 migration part 1

Ok, I really have no idea how many posts this is going to take, but I want to make sure they aren't too long and hopefully they will be useful for more than JUST vCenter migrations (that was my point in making them in different scripts).

The purpose of this first script was to have a COPY of what all of the VM details were before the migration started.  Thankfully I had most of this written prior to our migration, as I ran it weekly for DR purposes.  Here it is:


param(
 [string] $location=".",
 [array] $vcenters)
 
filter Get-FolderPath {
    $_ | % {
        $row = "" | select Name, Path
        $row.Name = $_.Name
        $current = $_.folder
        $path = ""
        do {
            $parent = $current
            if($parent.Name -ne "vm"){$path = $parent.Name + "\" + $path}
            $current = $current.Parent
        } while ($current.Parent -ne $null)
        $row.Path = $path
        $row
    }
}

function get-vCenterDetails
{
 param($vcenters)
 
 $allvmdetails=@()
 $vcs = Connect-VIServer $vcenters
 foreach ($vc in $vcs)
 {
  $DCs=Get-Datacenter -server $vc|Sort-Object name
  foreach ($DC in $DCs)
  {
   Write-Host "Getting DC $DC"
   Get-Cluster -Location $DC|sort-object name| %{
    $cluster = $_
    
    Write-Host "Getting cluster $cluster"
    $vmhosts=Get-vmhost -Location $cluster|Sort-Object name
        
    write-host "Getting VM details..."
    $allvmdetails += $cluster | Get-VM|Sort-Object name|select @{n="vmname";e={$_.name}}, `
     @{n="Datacenter";e={$DC.name}}, `
     powerstate, `
     @{n="OS";e={$_.guest.OSFullName}}, `
     version, `
     @{n="Folder";e={($_|get-folderpath).path}}, `
     @{n="ToolsStatus";e={$_.guest.ExtensionData.ToolsStatus}}, `
     VMhost, `
     @{n="Cluster";e={$cluster.name}}, `
     NumCPU, `
     @{n="MemMB";e={$_.memorymb}}, `
     @{n="DiskGB";e={[Math]::Round((($_.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum / 1MB),2)}}, `
     Notes
   }
  }
 }
 $allvmdetails
}

$date=get-date -Format yyyy.MM.dd
write-host "Getting Host and VM details: $(get-date)"
$vcenterdetails=get-vcenterdetails $vcenters
$vcenterdetails|export-csv -NoTypeInformation "$location\VMware_vmdetails_$date.csv"
write-host "Done: $(get-date)"

Disconnect-VIServer * -Confirm:$false -force

You must have the PowerCLI snap-in loaded to run the above, here is the usage (assuming you save the file as get-vmdetails.ps1):
PS c:\> .\get-vmdetails.ps1 -location c:\reportfolder -vcenters MyvCenter1,MyvCenter2,MyvCenter3

I wasn't planning on a detailed explanation of all of the scripts that I post, only due the number of great resources out there, but please feel free to ask questions if you have them.  The brief summary of what the script is doing would be:

  • Connect to your vCenter(s)
  • Loop through each Cluster within each Datacenter within each vCenter
  • Gather the following details for each VM: Name, DataCenter, PowerState, OS, Folder, ToolsStatus, Cluster, Host, HW Version, Memory, CPU, Disk, Notes
  • Export this as a CSV file
This was my first step in recording where my VMs were located so I could parse this file later after the VMs were connected to a new vCenter I could put them back into the same folder structure.

Part 2 coming soon...