Lab Ops part 8 –Tidying up
If you have been to one of our IT camps you’ll know it’s all live and unstructured which can mean things can go wrong, typically because we didn’t tidy up properly after the previous event. The problems of repeatedly creating VMs are that:
The VM still exists in Hyper-V
The files making up the VM are still on disk
The VM is registered in active directory ( we don’t currently recreate the main domain controllers for each camp
So the sensible thing is to scripts to tidy this up before I run each demo again, in fact my plan is to have a clean up section at the start of every demo script so I never forget to run it. My advantage over some of Power Shell gurus is that I am starting form scratch and can leverage the power of the later versions of PowerShell in Windows server 2012 & R2. For example to delete a DNS record there is now remove-DNSServerResourceRecord where before you would have had to use complex WMI calls.
My clean up code needs to run without errors whatever state my rig is in so where possible I test for objects where I delete them. Sadly I found one problem here and that was with the DNS cmdlets – if you do Get-DNSServerResourceRecord it returns an error if the record is not there which I think is wrong, but at least the command is easy to use.
Anyway here’s what I do..
#1. delete the File server VM. Note that before a VM can be deleted it must be shutdown no matter what state it’s in when the script is run
$vmlist = get-vm | where vmname -in $vmname
$vmlist | where state -eq "saved" | Remove-VM -Verbose -Force
$vmlist | where state -eq "off" | Remove-VM -Verbose -Force
$vmlist | where state -eq "running" | stop-vm -verbose -force -Passthru | Remove-VM -verbose –force
#2. Get back the storage. My scripts to create VMs put all of the metadata and virtual hoard disks in the same folder so once the VM has been deleted in hyper-v, I can just delete its folder.
$VMPath = $labfilespath + $VMName
If (Test-Path $VMPath) {Remove-Item $VMPath -Recurse}
#3. remove FileServer1 from AD if it's there already.
Get-ADComputer -Filter {name -eq $VMName} | Remove-ADObject -Recursive -Confirm:$false
Notes on the above..
- the code to delete the vms makes extensive use of the pipe “|” command perhaps the most important part of PowerShell. what crosses over this pipe is not text but the actual instance of the object being referenced. For example the vm properties will include the host it is running on so this doesn’t need to be specified.
- Another good example of how much easier PowerShell3 is the much simpler where clause we don’t need the {$._} syntax anymore
- I got the code to remove the entry for the VM from active directory by grabbing it from the Active Directory Administrative Console which is not only a one stop shop for AD, but shows you the PowerShell for each command you run in it for exactly this purpose..
- If you want to delete a cluster in AD you’ll need to turn off the switch to stop it being accidentally deleted ..
Set-ADObject -Identity:"CN=HAFILECLUSTER,CN=Computers,DC=Contoso,DC=com" -ProtectedFromAccidentalDeletion:$false -Server:"Orange-DC.Contoso.com"
- I haven’t got any code here to delete DNS entries as creating VM’s the way I do with static IP addresses doesn’t need this. However later in this series I’ll be creating clusters and scale out file servers and that’s when I need to do this..
invoke-command -ComputerName Orange-DC -ScriptBlock {remove-DnsServerResourceRecord "HAFileCluster" -ComputerName orange-dc -zone contoso.com -RRType A -Force}
invoke-command -ComputerName Orange-DC -ScriptBlock {remove-DnsServerResourceRecord "HAFileServer" -ComputerName orange-dc -zone contoso.com -RRType A -Force}
where HAFileCluster is my actual cluster and HA FileServer is the scale out fileserver role running on that cluster. I am invoking this command remotely as I am running it from a cluster node where I don’t have the DNS Server PowerShell cmdlets as that role is not installed on the nodes.
As ever I hope you find this stuff useful, and please let me know if you have any comments. In the meantime I am at TechDays Online for the rest of the week.
Comments
Anonymous
November 05, 2013
A useful script, thanks for sharing. For brevity, you could just use Stop-VM -Verbose -Force -Passthru | Remove-VM -Verbose -Force This will shut down the VM if it is on and just show an informational message otherwise. Your first 4 lines can then be reduced to this long one-liner: $vmlist = get-vm | where vmname -in $vmname | Stop-VM -Verbose -Force -Passthru | Remove-VM -Verbose -ForceAnonymous
November 18, 2013
The comment has been removedAnonymous
December 23, 2013
Pingback from Windows Server 2012 R2: Lab Ops–Building a VDI environment with powershell | MS Tech BLOG