Showing posts with label PowerShell. Show all posts
Showing posts with label PowerShell. Show all posts

Tuesday, October 13, 2009

Who's VM is This? Custom Fields for VMs with PowerShell

Being new into an environment, it is often difficult to sort through the hundreds of new servers that are now under your care. Seasoned veterans in your organization will already have intimate knowledge about each system that they support, and more often than not it is not fully documented as to who owns what system. I find myself often asking my new coworkers..."Who's VM is This?"

You may already know that within vCenter server you can easily add notes to VMs by selecting the VM, clicking on the Summary tab, and look under 'Annotations'.

Clicking on the Edit link will display the "Edit Custom Attributes" box where you can enter notes.



You should also see a button for creating custom Attributes. Attributes are custom fields (which is important to remember when using PowerCLI) that you can set name and values for at your pleasure. This can be applied to Hosts, Virtual Machines, or Globally which will apply the new attribute to both Host and Virtual Machine.


Note: Adding a custom attribute to one Host or Virtual Machine will add that attribute to all like systems. It does NOT populate the value for this attribute on other systems however. This is still our responsibility. Likewise if you delete an attribute it will also remove it and all values from like systems. These values are stored in the vCenter database and could possibly be recovered from your database backup. I have not tried testing this but have verified that the data is there and reference the VM in tables VPX_FIELD_DEF and VPX_FIELD_VAL.

In our environment it was my goal to create a custom attribute for "Owner", "Director", "App Owner" so that I could easily run an "Owners Report" that could be used for change notifications.

If you've read any of my other posts you probably know what's coming next...A Script!

Since there are so many VMs in my environment and I was relying on other people to populate the necessary data I created an Excel spreadsheet on a shared drive with a list of the VMs and columns for Owner, Director, App Owner, and Notes (which I'll share a separate script for later).

While that information was being populated I put together a quick script to import the file (.csv) and implement the attributes.

$import = Import-Csv "\\server\share\VM-Owner-Info.csv"

$import | %{
$field = $_.Field
$value = $_.Value
$server = Get-VM -Name $_.Name

#Create/Set custom attribute based on CSV values
$server | Set-CustomField -Name $field -Value $value
}

Note: Each new custom attribute that is added will appear at the top of the annotations section, just above the previous attribute added. i.e. If you have an attribute that you wish to have on top, then make sure you add it last.

For the sake of simplicity and under reasonable time constraints I reformatted my completed excel spreadsheet so that each Field was isolated on it's own line along with the VM and Value. This involved an extra minute but knowing Excel pretty well you should be able to accomplish this very quickly as well. My .CSV thus looks as such:

Name,Field,Value
Josh-Test-01,Owner,Josh 1
Josh-Test-02,Owner,Josh 2
JoshNet-DC,Owner,Josh 3
Josh-Test-01,Director,Jason 1
Josh-Test-02,Director,Jason 2
JoshNet-DC,Director,Jason 3
Josh-Test-01,App Owner,Rod 1
Josh-Test-02,App Owner,Rod 2
JoshNet-DC,App Owner,Rod 3


The script will process each line and assign the custom attribute accordingly. Since this serves the purpose and within the right time criteria I consider it in order. I'll be working hard later to allow you to generate an easier to manage table/CSV where the script will determine the Attribute name based on the header, and enter the value accordingly.

Host,Owner,Director,App Owner
Josh-Test-o1,Josh 1,Jason 1,Rod 1
Josh-Test-02,Josh 2, Jason 3, Rod 2
JoshNet-DC,Josh 3, Jason 3, Rod 3


This would be easier to edit and manage in Excel rather than having to define the attribute and value on each line. If anyone has some insight on how to make this possible since my initial attempt failed then please let me know.

Once run, the final product appears as so on all VMs:

I can now see the Owner, Director, and App Owner for this VM. Certainly you can use whatever attributes you'd like. I highly recommend using Excel and collaborating with your team to gather the pertinent information.

Now that you have this data populated for your VMs it is only really good to you if you can get it out. The PowerCLI Blog has a post for moving this data between vCenter servers (in the DB as you recall). I have modified it slight where it will display the attributes and their values for each VM.

function Get-CustomField {
param($item)
foreach ($cf in $item.CustomFields) {
if ($cf.Value) {
$field = "" | Select Key, Value, EntityName
$field.Key = $cf.Key
$field.Value = $cf.Value
$field.EntityName = $item.Name
Write-Output $field
}
}
}
$fields = Get-VM -server $server1 | Foreach { Get-CustomField $_ }
$fields


You can also use the quick one-liner:

Get-VM | Select -ExpandProperty customfields

Hope you find this useful.

Links:
Eric Siebert on Custom Attributes - http://itknowledgeexchange.techtarget.com/virtualization-pro/using-custom-attributes-with-vcenter-server/

When researching additional information for this post I came across where Arne Fokkema also created a one-liner to populate custom attributes from a .CSV file. It seems he beat me to it by about a month and I somehow didn't find it before creating my own. Here are two links from his blog where he performs the same task as well as adding notes as I mentioned earlier.
http://ict-freak.nl/2009/08/14/powercli-add-notes-to-multiple-vms/
http://ict-freak.nl/2009/08/17/powercli-set-custom-fields/

http://blogs.vmware.com/vipowershell/2009/05/moving-custom-fields-from-one-vcenter-to-another.html

Update Service Console Memory across Environment

I recently noticed a host in my environment that had its Service Console Memory set to 272MB which is far lower than recommended but is default. Since it is possible that others in my environment are also misconfigured I decided I needed a script to change this. A quick search on the internets led me to:

http://ict-freak.nl/2009/07/17/powercli-find-and-set-the-service-console-memory-value/

In his post, Arne Fokkema demonstrates how to generate a report on Console Memory in the environment using his script:

Get-VMHost | Sort Name | Get-View | Select Name, `
@{N="Service Console Memory";E= {"" + `
[math]::round($_.Config.ConsoleReservation.ServiceConsoleReserved / 1MB, 0) + " MB "}}

Fortunately he also provided a script for modifying this setting. I have it written below with a small modification that takes advantage of PowerShell's ability to perform calculations based on unit (KB/MB/GB). Functionally it isn't any different then Arne's script, but I found it a little more user friendly.

Get-VMHost | Get-View | % {
$_.Name | Where { $_.Config.ConsoleReservation.ServiceConsoleReserved -ne (800*1mb) }
(Get-View -Id $_.ConfigManager.MemoryManager).ReconfigureServiceConsoleReservation(800*1mb) }


Thanks to Arne for his post and work. Take a look at his blog at http://ict-freak.nl/

Tuesday, October 6, 2009

Configuring Network with PowerCLI and .CSV File

A couple of weeks ago I was in need to configure several new ESX servers with multiple NICs, vSwitches, and VLANs. Since I'm not one to do the same thing over and over again I turned to scripting. To further complicate things I wanted to allow the same script to create vSwitches, configure vMotion switch, add port groups, and create NIC Teams all from a prepopulated .CSV file. I'm doing this primarily so that all configuration could be done before the server arrived and so that I could create "Switch Profiles" when I add new hosts to clusters.

In the end I developed a script that reads from a .CSV file and then creates the desired switching. The first column tells the script what type of addition it is and the script processes the information for that object accordingly. I've noticed a few others have been posting recently about scripts on setting up portgroups, etc. and thought it was time to no longer keep this to myself (i.e. finally found the time to post). I too would like to also credit Hal Rottenburg's book Managing VMware Infrastructure with Windows Powershell which was very helpful for this and many other scripting projects I will be posting soon. Mike Laverick's post linked below helped in configuring the vMotion switch.

I hope you find this helpful. It has been HUGE in my environment.

Download the files here:
ESX-ConfigureSwitchCSV-Generic.txt
esx_switching_generic.csv

Links where others discuss switch configuration with PowerCLI.
http://halr9000.com/article/828
http://www.holy-vm.com/2009/10/01/adding-port-groups-with-powercli/
http://www.rtfm-ed.co.uk/?p=1514



Text of Script w/out comments

$getinfo = Import-Csv "\\server\share\file.csv"
Connect-VIServer -Server vCenterServer

$getinfo | % {
$Type = $_.Type #!!!! Case Sensitive !!!!!!
$gethost = Get-VMHost -Name $_.HostName
$SwitchName = $_.SwitchName
$PortGroup = $_.PortGroupName
$Nic = $_.NIC
$VLAN = $_.VLAN
$IP = $_.IP
$Subnet = $_.Subnet
$kernelGW = $_.KernelGW

If ($Type -eq "Switch") {
$gethost | New-VirtualSwitch -Name $SwitchName -Nic $Nic
}
If ($Type -ne "vMotion") {
$getswitch = Get-VirtualSwitch -VMHost $gethost -Name $SwitchName
}
If ($Type -eq "Team"){
$getswitch | Set-VirtualSwitch -Nic $Nic
}
IF ($Type -eq "Portgroup") {
$getswitch | New-VirtualPortGroup $PortGroup -VLanId $VLAN
}
IF ($Type -eq "vMotion") {

$newvswitch = New-VirtualSwitch -VMHost $gethost -Name $SwitchName -Nic $Nic
$vmotion = New-VirtualPortGroup -VirtualSwitch $newvswitch -Name $PortGroup
New-VMHostNetworkAdapter -VMHost $gethost -PortGroup $PortGroup -VirtualSwitch $newvswitch -IP $IP -SubnetMask $subnet -VMotionEnabled: $true

$vmhostnetwork = get-vmhostnetwork $gethost
set-vmhostnetwork -network $vmhostnetwork -vmkernelgateway $kernelGW
}
}

Tuesday, September 22, 2009

Hmm...We need to reorganize our clusters

This isn't first time that growth has yielded a desire to repurpose or rename a cluster in my virtual environment (VI3.5 currently), but this is the first time I was determined to use Powershell to perform the task.

The goal? I need 2 clusters in an organization folder named "Production" of our Raleigh Datacenter with the names "Windows Cluster" and "Production Cluster". I already have a "Production Cluster" that is getting repurposed in the near future so it must be renamed. I will then need to create a new cluster and name it "Production Cluster" for our new production servers.

1. Log into PowrCLI and connected to my vCenter server with

Connect-VIServer -Server

2. Change the name of the current cluster "Production Cluster" to "Windows Cluster":

Get-Cluster
-Name "Production Cluster" | Set-Cluster -Name "Windows Cluster"

This requires user acceptance of the change. Just hit enter or type Y and enter to accept.

3. Create new cluster Named "Production Cluster" and enable DRS, HA, make DRS Fully Automatic, and set HA so that it will not power on VM if it will exceed resource availability limits.

Get-Datacenter -Name "Raleigh Datacenter" | Get-Folder -Name "Production" | New-Cluster -Name "Production Cluster" -DrsEnabled -HAEnabled -DrsAutomationLevel FullyAutomated -HAAdmissionControlEnabled

Hit enter and in a couple of moments you have a brand new Cluster named "Production Cluster" in the correct Datacenter and Organization folder with DRS and HA initially configured. Always a good idea to check your configurations, but all looked well.

Note: vSphere (ESX4) has additional features (VM Monitor and fully supported Power Management) to manage on your cluster. I will update this post once I get some testing on that environment.