VMWare Script by: Ryan G

Written by Nick Weber on .

#############################################################
# Script Notes -
# This script will get the DNS hostnames for Windows VMs that are powered on in a vCenter inventory.
# Then... it will use WMI (Windows Credentials!) to grab the partitions from the Windows instances and perform the check below to make
# a true or false statement along with the disk size.
# You will get RPC Server errors for machines with Firewalls enabled and remote management not enabled.
# ###########################################################
# Written to be portable from vautomator
# Written by: Ryan G
# Date: 3/4/2011
# Company: DATALINK
# ###########################################################
# Modified By:
# Modified Date:
# ###########################################################
param
(  
# This parameter is read by Test-ViConnections function to determine what to do about $vc.
# IT IS NOT REQUIRED!!!!! If you pass a vCenter as a Parameter- it will disconenct any current
# and use a connection to the specificed one
[Parameter(Position=0, Mandatory=$false)]  
[string] $pvc = ""
)

# Function checks to see if the ViToolKit is loaded and loads it if not already there.
Function Load-Vitoolkit
{
$snapins = Get-PSSnapin | where {$_.Name -match "VMware.VimAutomation.Core"}
if($snapins -eq $null){add-pssnapin VMware.VimAutomation.Core}
}

# This function kills all connected vi servers with no questions
Function Kill-Connections
{
If($DefaultVIServer)
{
Disconnect-Viserver -Server $DefaultViServer -confirm:$false
echo "Disconnected $DefaultViServer"
}
If($DefaultVIServers)
{
Disconnect-VIServer -Server $DefaultVIServers -Confirm:$false
}
}

# Script to sort out the connected VC. (My personal favorite!)
# 1. Kill connections and attach to one specified as parameter
# 2. If not connected and no parameter, it will prompt user for vc
# 3. If connected, and no parameter, then it will use the existing conection
Function Test-VIConnections
{
If((! $DefaultVIServer) -and (! $pvc))
{
Write-Host "Connection to VirtualCenter not found."
$vc = Read-Host "Enter Virtual Center to connect to."
Connect-VIServer $vc | Out-Null
}
ElseIf($pvc)
{
$vc = $pvc
#Write-Host "VC entered as parameter."
Kill-Connections | Out-Null
Connect-VIServer $vc | Out-Null
}
ElseIf($DefaultVIServer)
{
#Write-Host "You are connected to $DefaultVIServer."
$vc = $DefaultViServer.Name
}
Else
{
Echo "Test-VIConnections state unexpected. I am confused."
}
Return $vc
}

# Function taken from Virtual-Al - Great little Logging feature!
Function Write-CustomOut ($Details)
{
$LogDate = Get-Date -Format T
Write-Host "$($LogDate) $Details"
}

# Function taken from Virtual-Al - Great little Logging feature!
Function Write-CustomLog ($Details)
{
$LogDate = Get-Date -Format T
echo "$($LogDate) $Details" >> $logfile
}

###################################### Start of Script ########################################
# Run function to load the snapin if not
Write-CustomOut "Starting Script"
Write-CustomOut "Checking ViToolKit Status"
Load-ViToolkit

# Run function to sort out how i want to connect to a vCenter
Write-CustomOut "Checking vCenter Connection"
$vc = Test-ViConnections
Write-CustomOut "$vc being used"

# Define our report variables
Write-CustomOut "Defining variables"
$report = @()
$vms = @()
$output = "$vc-alignment-report.csv"
# Get the list of VMs that are PoweredOn
Write-CustomOut "Retreiving list of powered on VMs"
$PoweredOn_vms = get-vm | where {$_.PowerState -eq "PoweredOn"}


# Get the .Net objects of those that are Windows types
$vms_view = $PoweredOn_vms | Get-View | where {$_.Guest.GuestFullName -match "Windows"}

# Pump the DNS host name of the VMs into $vms
Foreach($vm in $vms_view)
{
$vms += $vm.Guest.Hostname
}

# Run each of the DNS names through our WMI command Loop
Foreach($vm in $vms)
{
Write-CustomOut "Checking $vm"
$partitions = gwmi win32_diskpartition -ComputerName $vm | Out-Null
if(! $?){
$report += "$vm had access errors"
Write-CustomOut "$vm had errors accessing"                    
}
Foreach($partition in $partitions)
{
$row = "" | Select VM, Name, SizeGB, Aligned
$row.VM = $vm
$row.Name = $partition.Name
$row.SizeGB = [System.Math]::Round(($partition.Size)/1GB)
$row.Aligned = if($partition.StartingOffset%4096 -eq 0){$true} else {$false}
$report += $row
}
}

# Dump the report to the report file
Write-CustomOut "Generating $output"
$report | Export-Csv $output -NoTypeInformation
Write-CustomOut "Script Completed"
notepad $output