Hey… if Luc can do it, so can I, right? Turns out that yes, I can, and it’s quite easy with vCenter Orchestrator also. If you haven’t already, check out these other posts on vCO:
Now, our task at hand, clean up some orphaned files:
The Task
It’s spring, and it’s time to do a regular clean-up of your vCenter Server. Specifically you are looking for orphaned files and VMs to clean up.
The Workflow
There are two ways we can accomplish this: generate and e-mail a list of files to clean up; or generate the list, delete the files, then e-mail the result. We’re in luck in that vCO has the first of these workflows built in.
Built in
The built in workflow can be found here: “Library > vCenter > Virtual Machine management > Other > Find orphaned virtual machines”. Not buried deep enough for you?
This only takes care of 1/2 of our problem however in that we need to delete these files as well…
Customized
Having the need to delete the files leads us to having to customize the existing workflow, to do that, you must first right click & duplicate the existing workflow. From the resulting workflow, right click and choose edit.
Now let’s modify the schema a bit by changing a link, adding an additional decision point, and a scriptable task. The resulting workflow will look like:
Scriptable Task
What all is in that scriptable task? Take a look at the code here:
// Get all VMs known to vCO
var allVms = VcPlugin.getAllVirtualMachines(new Array());
var allVmFiles = new Array();
for (var i in allVms) {
allVmFiles = allVmFiles.concat(allVms[i].layoutEx.file);
}
// Get all Datastores known to vCO
var allDatastores = VcPlugin.getAllDatastores();
var fileList = new Array();
for (var i in allDatastores) {
ds = allDatastores[i];
System.log( “Deleting orphaned files from datastore: ” + ds.name);
Server.log( “Deleting orphaned files from datastore: ” + ds.name);
try {
// Get all vmdk files for a datastore
files = System.getModule(“com.vmware.library.vc.datastore.files”).getAllVmdkFile(ds);
var fileFound = false;
for (var x in files) {
//ignore esx console
var filename = System.getModule(“com.vmware.basic”).getFileName(files[x]);
if (filename == “esxconsole.vmdk”) {
continue;
}
var vmFound = false;
for (var y in allVmFiles) {
if (files[x] == allVmFiles[y].name) {
vmFound = true;
break;
}
}
// If we find some files, kill them with fire.
if (vmFound == false) {
fileFound = true;
var killWithFire = System.getModule(“com.vmware.library.vc.datastore.files”).deleteFile(ds,files[x])
System.log(“Deleted file ” + files[x] );
Server.log(“Deleted file ” + files[x] );
}
}
if (fileFound == false) {
System.log(“No File found on datastore ” + ds.name);
Server.log(“No File found on datastore ” + ds.name);
}
}
catch (e) {
System.error(“Exception while browsing datastore ” + ds.name + ” exception ” + e);
}
}
The Exported Package
Had to save this part for last… teach a fellow to fish and all. Here is an exported package that can be imported into your vCO installation and run.
Summary
The cool thing here, is that you don’t need to wait until spring to make this all work, and rather you can schedule this workflow as often as you’d like. If you have any questions, comments, requests, or what have you, drop me a line in the comments or follow me on twitter here.
Disclaimer
As this workflow has a delete function, I’m going to have to strongly recommend you do not run it blindly. Rather, I would suggest you read, understand, and test the workflow before deploying it in a live environment. I can’t be held responsible if you delete the wrong thing… just saying.
hi,
cool script – i tried it, but i found out that layoutEX is not aware of storage vmotions since the last startup of the vm right ?
when i storage migrate a vm and afterward ask for vmfiles (allVmFiles.concat(allVms[i].layoutEx.file);) i get back the old datastore/path to the vm-files.
is there a way to go around this ?
chris
I won’t be able to look into this until I get back from VMworld. That said, check the VMware communities forum for vCO, or open an SR.