Hello all!
I'm new in the community. Im an apprentice in the last year. I work with vmware esx / vsphere since august 2009.
In december 2009 i startet scripting with powershell and powerCLI.
Maybe someone can help me, i searched long time, but I don't know how to do.
I've got a small script, which leads you through some menus. There you can select the datacenter, the template and insert the vm name. The datastores and the host or cluster will get automatically for the deploy. At the end, the script creates an INI File like this:
vmname=test
Location=VENV40
Template=w2k3eesp2x32_template
Cluster_Host=adcv43e.xxx.yyyy.net
DatastoreSystem=esx40_nfs01_SystemDrives1
DatastoreSwap=esx40_nfs02_SwapDrives1
VCenterVENV=xx.yy.xx.yyy
Now to my problem. The second script should be an endless loop, which looks if there are some new INI Files.
Because of our policies, we only can deploy during night (storage load). We've got 3 "slots". at 01:00, at 03:00 and at 05:00, where we can deploy a vm.
The second script should get the scheduled deploy task from the Vcenter and check if there is a "slot" free to deploy, if not, check next night and so on.
My problems are:
I can't get only the deploy task
The start time got one hour difference than in the vcenter ? (daylight saving time ?)
When I got the available task, how do I create an new one, with the Informations out of the Ini file?
Has anyone an idea ?
This is what i've got until now. This was just to try if i can get the scheduled task
--------------------------------------------------------------------------------------------
Force load (otherwise VMware.Vim objects are not known)
http://Reflection.Assembly::LoadWithPartialName("vmware.vim")
cls #clearscreen
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
This returns a MoRef to the scheduled task manager
$schMgr_ref = $serviceInstance.Content.scheduledTaskManager
This return the actual scheduled task manager object
$schMgr_obj=get-view $schMgr_ref
The method needs to be called on the object
The method requires 1 argument.
As the API Ref states when the parameter is Null the method will return
all scheduled tasks
$foo=$schMgr_obj.RetrieveEntityScheduledTask($null)
The method returns an array of ScheduledTask object references
foreach ($task in $foo) {
$infos = (get-view $task).info
$taskname = $infos.Name
$taskdate =($infos.Scheduler).RunAt
$task = "$taskname","$taskdate"
}
#----
Thanking you in anticipation.
I'm looking forward to hear from you, and sorry for my bad english ![]()
Greetings PowaCLI
HELL YES !!
I could also solve this problem.
Again i't soo logical and my error was just stupid.
In the 4 different Vcenter, we got Templates and Datastores with Same names.
Now I specified the the $specs with more details:
$cloneSpec.Location.Datastore = ((Get-Datastore $params.DatastoreSystem -Datacenter $params.Location ) | Get-View).MoRef
---
$diskSpec2.Datastore = ((Get-Datastore $params.DatastoreSwap -Datacenter $params.Location ) | Get-View).MoRef
---
$entity = (Get-Template $params.template -Location $params.Location ) | Get-View
Thanks a lot for your help LucD, now my script begins to rock hehe ![]()
Greetings from happy PowaCli
Great. Happy for you.
Perhaps you could post the script under Documents once it's finished.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Of corse I will. First I will also implement, that I can add a Customization Specifization file.
I'll post it here when it's finished and a bit better structured ![]()
Here a short preview off my idea.
The scheduler runs endless for example on the Vcenter server.
The admins have a little commandline Menu (CSV Creator script) on their Desk which shows every Datacenter which contains a template.
After selecting the Datacenter, you can select a template from it.
Last step is to give an VMname (will get checked if it already exists, and allowed ar only a-z0-9 chars).
The rest will do the CSV Creator Script. It selects the Datastore(s), Cluster or Host and Resourcepool and save the file in the folder which the Scheduler script looks.
The scheduler schedules the CSV File at the specified taskhours.
This script is not perfect, but for some small and medium-sized companies it helps to deploy new vms.
Or maybe someone can use this as a base to make oder tasks.
I hope this is my last question ![]()
Is it possible to "select" an existing customization specification or do i have to specifie for each Vm the customizationspecs new?
Refering to these posts:
http://communities.vmware.com/thread/171830
http://communities.vmware.com/message/1000737#1000737
It would be a lot simpler if i can use an existing file.
Provided I understood the question correctly, yes, you can reuse the CustomizationSpec object.
Just make sure the required properties (for example hostname and IP address) are updated for each call.
You could in fact also make a function to populate the VirtualMachineCloneSpec object and pass the parameters that need to be changed.
Something like this for example
....
function New-MyCustomizationSpec{
param($hostname, $ipaddress,....)
$spec = New-Object CustomizationSpec
....
$spec
}
$cloneSpec.customization = New-MyCustomizationSpec -hostname MyVM1 -ipaddress "192.168.1.1"...
...
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I mean if i can select one of the already created files, so that I don't have to specifie each thing in the Code.
IP Settings aren't important at this point. More things like name, Productcode and RunOnce, which we specified in the Customization Files.
Ok, I see.
Yes, you can fetch an existing OS Customization specification like this
$custSpec = Get-OSCustomizationSpec -Name <OS-customizationname> New-VM ... -OSCustomizationSpec $custSpec
And you can create them from a script with the New-OSCustomizationSpec and change them with the Set-OSCustomizationSpec cmdlets.
Note that you have to use the Set-OSCustomizationNicMapping cmdlet to change the network settings in such a customization specification.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thx LucD now I can reuse the customization files.
I thought that every thing works, because it could schedule the Task, but yesterday I testet it by running the tasks.
There is a problem I think with the DRS Cluster.
In Vcenter with ResourcePools it works. But where we use Cluster it don't.
In the referenceguide I found this:
if resource pool is specified, and the target pool represents a DRS-enabled cluster, a host selected by DRS is used.
How do I have to specifie?
$cloneSpec.location.Pool= (Get-Cluster $params.cluster_host -Location $params.location | Get-View).MoRef
Like that it says in the Vcenter: The request refers to an unexpected or unknown type.
I made an If condition to check if it's a cluster or not:
if($params.Cluster_Host -like "*Cluster*"){
$cloneSpec.location.Pool = (Get-Cluster $params.cluster_host -Location $params.location |Get-View).MoRef
}
else{
$cloneSpec.Location.Pool = ((Get-ResourcePool $params.cluster_host -Location $params.location | select -First 1) | Get-View).MoRef
}
I suspect that you have more than 1 resourcepool on the cluster.
In that case the Get-ResourcePool cmdlet will return an array.
Perhaps try to go for the default resourcepool (Resources).
Like this
if($params.Cluster_Host -like "*Cluster*"){
$cloneSpec.location.Host = (Get-Cluster $params.cluster_host -Location $params.location | Get-View).MoRef
$cloneSpec.location.Pool = ((Get-Cluster $params.cluster_host -Location $params.location | Get-ResourcePool -Name "Resources") |Get-View).MoRef
# $vmHost = (Get-Cluster $params.cluster_host -Location $params.location) | Get-VMHost | sort CpuUsageMhz | select -First 1
# $cloneSpec.Location.Host = ($vmHost | Get-View).MoRef
}
else{
$cloneSpec.Location.Pool = ((Get-ResourcePool $params.cluster_host -Location $params.location | select -First 1) | Get-View).MoRef # Get-cluster QVENV00_Cluster00 | bsp. QVENV00_Cluster00
}
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thx LucD I think I can get on with that.
I also created a reference Task in the Vcenter and had a look with the MOB browser. And the Vms on the "cluster" all are in the default resourcepool.
What i saw, was, that my created task don't have any value set by the pool.
I'll fix it.
So, now it works with your solution ![]()
By the way, do you know on what depends de DiskID ? The ID is everytime 2000 for the first disk, and 2001 for the second disk.
The algorithm seems indeed to always start from 2000, but I wouldn't rely on it.
Could be changed in a coming ESX release.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Okei. I tested it in the 4 different Vcenters with Esx 3.5 and Vsphere 4.0.
But yes, it would be better if I don't specifie the ID static to 2000 + x
If I find out something I'll post it.
I always use the -1 for the key for a new device.
From the VirtualDevice object:
When adding new devices, it may be necessary for a client to assign keys temporarily in order to associate controllers with devices in configuring a virtual machine. However, the server does not allow a client to reassign a device key, and the server may assign a different value from the one passed during configuration. Clients should ensure that existing device keys are not reused as temporary key values for the new device to be added (for example, by using negative integers as temporary keys).
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Okei thanks.
I got an other error, not sure if its because of the customization.
At the end of deploying, there comes a message, Customization Failed and the new Vm get deleted.
Is this maybe because of the ProductID ? Is it really needed, or can I insert a "dummykey" so that I have to change the key after sysprep?
I'm not sure, if the deploying fails, because of the customization, but i think so. I'll test a deploying without specifing any Customization.
If the OS is a Windows OS and if you're doing customisation, then this implies running sysprep as part of the cloning process.
That means the productId needs to be a valid one, unless you installed the original OS from a multi-volume license medium.
In the CustomizationUserData description the property is not marked as optional. So it has to be there (and valid).
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello LucD
It works now, without ProductID. It is definitly not required, although its not marked Optional.
If you look in the GUI, you can leave this field blank.
The problem by me was the networkadapter configuration.
Note: Never use $clonespec.Customization.NicSettingMap[0].Adapter.Ip = New-Object VMware.Vim.CustomizationFixedIP
if you don't specifie the IP etc. or specifie it wrong. ^^
I now use dhcp instead.
$clonespec.Customization.NicSettingMap[0].Adapter.Ip = New-Object VMware.Vim.CustomizationDhcpIpGenerator # dhcp
I got a last question, I hope its really the last one.
Can I directly add a new disk to the new VM? I had a look to the sdk, but I don't unterstand it really.
I think I can go on with:
$cloneSpec.config = new-object vmware.vim.VirtualmachineConfigSpec
$clonespec.config.DeviceChange = new-object vmware.vim.virtualDeviceConfigSpec
But then I'm not really sure, how to add a new disk
Thanks for the feedback.
I thought the productId was obligatory.
Yes, you can add devices.
In the VirtualMachineCloneSpec object use the config.deviceChange property to add one or more devices.
A short example. It adds a Buslogic controller
... $spec.config.deviceChange = @() $devspec = New-Object VMware.Vim.VirtualDeviceConfigSpec $devspec.device = New-Object VMware.Vim.VirtualBusLogicController $devspec.device.busNumber = 0 $devspec.device.ControllerKey = -100 $devspec.device.DeviceInfo = New-Object VMware.Vim.Description $devspec.device.DeviceInfo.label = "SCSI Controller 0" $devspec.device.DeviceInfo.summary = "BusLogic" $devspec.device.hotAddRemove = $TRUE $devspec.device.key = -1000 $devspec.device.scsiCtlrUnitNumber = 7 $devspec.device.sharedBus = "noSharing" $devspec.operation = "add" $spec.config.deviceChange += $devspec ...
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello LucD
I'm doing something wrong with the backing i think:
This is from an existing VM for a reference:
Backing Infos:
This is my code:
{code}
$cloneSpec.config = New-Object vmware.Vim.VirtualMachineConfigSpec
$clonespec.config.deviceChange = @()
$devspec = New-Object VMware.Vim.VirtualDeviceConfigSpec
$devspec.Device = New-Object vmware.Vim.VirtualDisk
$devspec.device.ControllerKey = "1000"
$devspec.Device.Key = "2001"
$devspec.device.CapacityInKB = $SwapCapacity
$devspec.device.DeviceInfo = New-Object VMware.Vim.Description
$devspec.device.DeviceInfo.label = "Hard Disk 2"
$devspec.device.DeviceInfo.summary = "$swapCapacity KB"
$devspec.device.Backing = New-Object vmware.Vim.virtualdiskflatver2backingInfo
$devspec.device.backing.Datastore = ((Get-Datastore $params.datastoreSwap) | Get-View).MoRef
$devspec.Device.backing.diskmode = "persistent"
$datastoreswap = $params.DatastoreSwap
$vmname = $params.vmname
$filename = " " + "$vmname" + "/" + "$vmname" + ".vmdk"
$devspec.device.backing.Filename = $filename
$devspec.operation = "add"
$clonespec.config.deviceChange += $devspec
{code}
I looked in the Scheduled Task Manager for the result, and it looks like that:
I don't know why, but I get this error while scheduling:
fault.InvalidDeviceBacking.summary
Maybe you know this error by heart.
Thx and greets PowaCLI
I think the datastore should be referenced by name and not by MoRef. See for more information.
Robert
