VMware Cloud Community
PowaCLI
Contributor
Contributor
Jump to solution

Problems accesing and configuring the scheduled tasks

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

  1. --------------------------------------------------------------------------------------------

  2. 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

  1. This returns a MoRef to the scheduled task manager

$schMgr_ref = $serviceInstance.Content.scheduledTaskManager

  1. This return the actual scheduled task manager object

$schMgr_obj=get-view $schMgr_ref

  1. The method needs to be called on the object

  2. The method requires 1 argument.

  3. As the API Ref states when the parameter is Null the method will return

  4. all scheduled tasks

$foo=$schMgr_obj.RetrieveEntityScheduledTask($null)

  1. 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 Smiley Wink

Greetings PowaCLI

Reply
0 Kudos
47 Replies
PowaCLI
Contributor
Contributor
Jump to solution

HELL YES !! Smiley Happy

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 Smiley Happy

Greetings from happy PowaCli

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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 Smiley Wink

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.

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

I hope this is my last question Smiley Wink

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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  	
     }

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

PowaCLI
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

So, now it works with your solution Smiley Wink

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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. ^^ Smiley Wink

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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
PowaCLI
Contributor
Contributor
Jump to solution

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

Reply
0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

I think the datastore should be referenced by name and not by MoRef. See for more information.

Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
Reply
0 Kudos