Archive for April, 2010

Powershell Script Extension….

April 1, 2010

LucD posted a Powershell Script yesterday, to give a UML diagram of the disks attached to a VM.

That’s nice, but the VM in question was hard-coded, as file name of the diagram created.Not great if you want the diagram for a bunch of vms. So, I swapped out the definition of $vmName and tweeked the definition of the default for $diagramFileName. Giving a script that can be run in a loop over all VMs, leaving you with .jpgs (or pdfs) in the root of C:\

param($vmName)
$output = “C:\” + $vmName + “.jpg”

function Get-UMLDiagram{

function Set-ULMFromTo{
param($from, $to, $attrib)

$result = “[” + $from + “]->[” + $to
if($attrib){
$result += “|”
$attrib | %{
$result += ([string]$_ + “;”)
}
$result = $result.TrimEnd(“;”)
}
$result += “],`n”
$result
}

filter Get-SnapHash{
param($parent)

$snapHash[$_.Snapshot.Value] = @($_.Name,$parent)
if($_.ChildSnapshotList){
$newparent = $_
$_.ChildSnapShotList | Get-SnapHash $newparent
}
}

$vms = Get-View -ViewType VirtualMachine -Filter @{“Name”=$vmName}

$snapHash = @{}

$vms | %{
$ulmStr = “”
$vm = $_

if($vm.Snapshot){
$vm.Snapshot.RootSnapshotList | Get-SnapHash $vm
}
$firstHD = $true
$_.Config.Hardware.Device | where {$_.DeviceInfo.Label -like “Hard disk *”} | %{
$hd = $_
$hdNr = $hd.DeviceInfo.Label.Split(” “)[-1]
$exDisk = $vm.LayoutEx.Disk | where {$_.Key -eq $hd.Key}
$diskFiles = @()
$exDisk.Chain | %{$_.FileKey} | %{$diskFiles += $_}
$totalDiskAllocated = 0
$vm.LayoutEx.File | where {$diskFiles -contains $_.Key} | %{
$totalDiskAllocated += $_.Size
}
$hdProp = @()
if($hd.Backing.ThinProvisioned){
$hdProp += “Thin”
$hdProp += (“AllocatedGB=” + (“{0:N0} GB” -f ($totalDiskAllocated / 1GB)))
$hdProp += (“Used=” + (“{0:P0}” -f ($totalDiskAllocated / 1KB /$hd.CapacityInKB)))
}
elseif($hd.Backing.GetType().Name.Contains(“RawDisk”)){
$hdProp += “RDM”
}
else{
$hdProp += “Thick”
$hdProp += (“Allocated=” + (“{0:N0} GB” -f ($totalDiskAllocated / 1GB)))
}
$ulmStr += (Set-ULMFromTo ($vm.Name + “{bg:orange}”)  ($hd.DeviceInfo.Label) $hdProp)

$exDisk.Chain[0].FileKey | %{
$ulmStr += (Set-ULMFromTo ($hd.DeviceInfo.Label + “{bg:green}”) $vm.LayoutEx.File[$_].Name.Split(“/”)[-1] $vm.LayoutEx.File[$_].Size)
}
$snapHash.GetEnumerator() | %{
$key = $_.Key
$value = $_.Value
$vm.LayoutEx.Snapshot | where {$_.Key.Value -eq $key} | %{
$vmsnId = $_.DataKey
$_.Disk | where{$_.Key -eq $hd.Key} | %{
if($diskFiles -notcontains $_.Chain[-1].FileKey[0] -and $diskFiles -notcontains $_.Chain[-1].FileKey[1]){
$chain = $_.Chain[-1]
}
else{
$preSnapFiles = $_.Chain | %{$_.FileKey} | %{$_}
$vm.layoutEx.Disk | where {$_.Key -eq $hd.Key} | %{
foreach($chain in $_.Chain){
if($preSnapFiles -notcontains $chain.FileKey[0] -and $preSnapFiles -notcontains $chain.FileKey[1]){
break
}
}
}
}
if($firstHD){
$ulmStr += (Set-ULMFromTo ($value[1].Name + “{bg:yellow}”) ($value[0] + “{bg:yellow}”))
$ulmStr += (Set-ULMFromTo $value[0] $vm.LayoutEx.File[$vmsnId].Name.Split(“/”)[-1] $vm.LayoutEx.File[$vmsnId].Size)
}
$ulmStr += (Set-ULMFromTo $value[0] ($value[0] + “-HD” + $hdNr + “{bg:blue}”))
$chain.FileKey | %{
$ulmStr += (Set-ULMFromTo ($value[0] + “-HD” + $hdNr) $vm.LayoutEx.File[$_].Name.Split(“/”)[-1] $vm.LayoutEx.File[$_].Size)
}
}
}
}
$firstHD = $false
}
$ulmStr.TrimEnd(“,`n”)
}
}

# Based on Doug Finke’s original Get-yUMLDiagram function.
# See: http://dougfinke.com/blog/index.php/2009/05/06/use-powershell-and-yuml-to-create-diagrams/
# Added the “scruffy” switch and rearranged some of the lines
#
function Get-yUMLDiagram {
param(
$yUML,
$diagramFileName = $output,
[switch]$show,
[switch]$pdf,
[switch]$scruffy
)

$scruffyPath = “”
if($scruffy){
$scruffyPath = “scruffy/”
}
$base = “http://yuml.me/diagram/” + $scruffyPath + “class/”
$address = $base + $yUML

$wc = New-Object Net.WebClient
if($pdf){
$diagramFileName = $diagramFileName.Replace($diagramFileName.Split(“.”)[-1],”pdf”)
$address += “.pdf”
}
$wc.DownloadFile($address, $diagramFileName)
if($show) {
Invoke-Item $diagramFileName
}
}

$diagram = Get-UMLDiagram $vmName

Get-yUMLDiagram $diagram $output

Thanks Luc!