Finding stuff in all the cool datastores you never knew you had (or that you knew you had, you just really didn’t want to click alot)

Lucd has been my number one source of scripts for pretty much like ever. He is always willing to helping out in the community, uber smart and knows his stuff. I often will use his scripts to start and do something else with them, mostly because I don’t know how, and I am lazy. his most awesome script was something that i started to do, and did back in bash in the good ol esx days, since esx pretty much is dead (it’s about freaking time), i needed to convert it PS to make it work, but low and behold, he already did it.

Here. Raiders of the lost VMX

These things are amazing for scripting DR when the client just isn’t big enough to justify SRM

Anywho how this started is I recently had a client’s site the VDR appliance blow up and start making snapshot files with failing the snapshot, since it failed it never removed the vmsn files, and it was only on a few particular datastores. I am not gonna name names, but I’m 99% sure it had to do with the buggy 5.0.1 equallogic firmware and its Atomic Lock and Set, but now that that is fixed its pretty freaking awesome.
so with the permission of LucD himself, here is the modified script to look for vmsn files plus all the other cool stuff it could do beforehand!

without more delay, here it is!
[powershell]
function Register-VMX {
param($entityName = $null,$dsNames = $null,$template = $false,$ignore = $null,$checkNFS = $false,$whatif=$false,$snapshot = $false)

function Get-Usage{
Write-Host "Parameters incorrect" -ForegroundColor red
Write-Host "Register-VMX -entityName -dsNames [,…]"
Write-Host "entityName : a cluster-, datacenter or ESX hostname"
Write-Host "dsNames : one or more datastorename names"
Write-Host "ignore : names of folders that shouldn’t be checked"
Write-Host "template : register guests ($false)or templates ($true) – default : $false"
Write-Host "checkNFS : include NFS datastores – default : $false"
Write-Host "whatif : when $true will only list and not execute – default : $false"
Write-Host "snapshot : finds vmsn files if set to ($true) – default : $false"
}

if($entityName -ne $null -and $dsNames -ne $null){
Get-Usage
exit
}

if($dsNames -eq $null){
switch((Get-Inventory -Name $entityName).GetType().Name.Replace("Wrapper","")){
"Cluster"{
$dsNames = Get-Cluster -Name $entityName | Get-VMHost | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS} | % {$_.Name}
}
"Datacenter"{
$dsNames = Get-Datacenter -Name $entityName | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS} | % {$_.Name}
}
"VMHost"{
$dsNames = Get-VMHost -Name $entityName | Get-Datastore | where {$_.Type -eq "VMFS" -or $checkNFS} | % {$_.Name}
}
Default{
Get-Usage
exit
}
}
}
else{
$dsNames = Get-Datastore -Name $dsNames | where {$_.Type -eq "VMFS" -or $checkNFS} | % {$_.Name}
}

$dsNames = $dsNames | Sort-Object
$pattern = "*.vmx"
if($template){
$pattern = "*.vmtx"
}
if($snapshot){
$pattern = "*.vmsn"
}

foreach($dsName in $dsNames){
Write-Host "Checking " -NoNewline; Write-Host -ForegroundColor red -BackgroundColor yellow $dsName
$ds = Get-Datastore $dsName | Get-View
$dsBrowser = Get-View $ds.Browser
$dc = Get-View $ds.Parent
while($dc.MoRef.Type -ne "Datacenter"){
$dc = Get-View $dc.Parent
}
$tgtfolder = Get-View $dc.VmFolder
$esx = Get-View $ds.Host[0].Key
$pool = Get-View (Get-View $esx.Parent).ResourcePool

$vms = @()
foreach($vmImpl in $ds.Vm){
$vm = Get-View $vmImpl
$vms += $vm.Config.Files.VmPathName
}
$datastorepath = "[" + $ds.Name + "]"

$searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchspec.MatchPattern = $pattern

$taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec)

$task = Get-View $taskMoRef
while ("running","queued" -contains $task.Info.State){
$task.UpdateViewData("Info.State")
}
$task.UpdateViewData("Info.Result")
foreach ($folder in $task.Info.Result){
if(!($ignore -and (&{$res = $false; $folder.FolderPath.Split("]")[1].Trim(" /").Split("/") | %{$res = $res -or ($ignore -contains $_)}; $res}))){
$found = $FALSE
if($folder.file -ne $null){
foreach($vmx in $vms){
if(($folder.FolderPath + $folder.File[0].Path) -eq $vmx){
$found = $TRUE
}
}
if (-not $found){
if($folder.FolderPath[-1] -ne "/"){$folder.FolderPath += "/"}
$vmx = $folder.FolderPath + $folder.File[0].Path
if($snapshot){
Write-Host "`t" $vmx
write-host " Snapshot file found" -ForegroundColor blue -BackgroundColor white
}
if($template){
$params = @($vmx,$null,$true,$null,$esx.MoRef)
}
else{
$params = @($vmx,$null,$false,$pool.MoRef,$null)
}
if((!$whatif) -and (!$snapshot)){
$taskMoRef = $tgtfolder.GetType().GetMethod("RegisterVM_Task").Invoke($tgtfolder, $params)
Write-Host "`t" $vmx "registered"
}
elseif($whatif){
Write-Host "`t" $vmx "registered" -NoNewline; Write-Host -ForegroundColor blue -BackgroundColor white " ==> What If"
}
}
}
}
}
Write-Host "Done"
}
}

# Register-VMX -entityName "MyDatacenter" -snapshot:$true
# Register-VMX -entityName "MyDatacenter"
# Register-VMX -dsNames "datastore1","datastore2"
# Register-VMX -dsNames "datastore1","datastore2" -template:$true
# Register-VMX -entityName "MyDatacenter" -ignore "SomeFolder"
# Register-VMX -dsNames "datastore3","datastore4" -ignore "SomeFolder" -checkNFS:$true
# Register-VMX -entityName "MyDatacenter" -whatif:$true
[/powershell]

One Liners, We All Love Them

CD-Rom
Finds all the vm’s with a cd-rom connected and disconnects them

[powershell]
Get-VM | Where-Object {$_ | Get-CDDrive | Where-Object { $_.ConnectionState.Connected -eq "true" } } | Get-CDDrive | Set-CDDrive -Connected $false -Confirm:$false[/powershell]

Mark the vm’s starting with zT as a template*
[powershell]
foreach ($d in (get-vm zT*)){$vm2 = Get-VM $d | Get-View; $vm2.MarkAsTemplate()}
[/powershell]

Deletes all Snapshots over 2 days old
[powershell]foreach ($snap in (Get-VM | get-snapshot)){if ($snap.Created -lt (Get-Date).AddDays(-2)){Remove-Snapshot $snap -Confirm:false}}[/powershell]

Connects all VM’s with a certain name to the same iso

[powershell]
get-datacenter dc | get-cluster cl | get-vm 2008* | get-cddrive | set-cddrive -IsoPath "[Datastore Name] -isoname.iso" -Connected:$true -Confirm:$false[/powershell]

Let’s Find the HAL level for vm’s

[powershell]
Get-VM |Where {$_.PowerState -eq “PoweredOn“} |Sort Name |Select Name, NumCPU, @{N=“OSHAL“;E={(Get-WmiObject -ComputerName $_.Name-Query “SELECT * FROM Win32_PnPEntity where ClassGuid = ‘{4D36E966-E325-11CE-BFC1-08002BE10318}’“ |Select Name).Name}}, @{N=“OperatingSystem“;E={(Get-WmiObject -ComputerName $_ -Class Win32_OperatingSystem |Select Caption).Caption}}, @{N=“ServicePack“;E={(Get-WmiObject -ComputerName $_ -Class Win32_OperatingSystem |Select CSDVersion).CSDVersion}}
[/powershell]

VMHost
Disable vMotion All the host in a cluster

[powershell]
get-datacenter DC | get-cluster CL | get-vmhost | set-vmhostadvancedconfiguration -Name Migrate.Enabled -Value 0
[/powershell]

Powershell Service Checks – VMware edition

[powershell]
# be tidy – clear the screen 🙂
cls

# show a welcome message
write-host "VMware Service Status"
write-host "——————–"
write-host ""

function checkService ($serviceName, $machineName) {

# do some very basic error checking
if (($serviceName -eq $null) -or ($machineName -eq $null))
{
write-host "Service or machine name missing. Please correct and retry."
}
else
{
# use the .NET abilities of PowerShell to get a list of all services that match the service name we’re looking for
# note that we are checking both the short and display names, i.e. you can check for either
# e.g. "iisadmin" and "IIS Admin Service" will both work
$serviceResults = [System.ServiceProcess.ServiceController]::GetServices($machineName) | where{ (($_.name -eq $serviceName) -or ($_.displayname -eq $serviceName))}

# check to see if the results is an empty object
# if it is empty the requested service wasn’t found
if ($serviceResults -eq $null)
{
# the service wasn’t found so set the result to an empty string (it’s used later)
$isServiceFound = ""
}
else
{
# the service was found so get the service’s name
$isServiceFound = $serviceResults.name
}

# check to see if any service names were returned
if ($isServiceFound -eq "")
{
# the service wasn’t found
$resultDisplay = "Not found"
}
else
{
# the requested service was found so get its status
$serviceStatus = get-service $isServiceFound
$resultDisplay = $serviceStatus.status
}

# return the result of the service check
if ($resultDisplay -eq "Running")
{
# it is running so display an appropriate confirmation in normal text colour
write-host "$serviceName : " -noNewLine
write-host $resultDisplay
}
else
{
# the service isn’t running to display a warning in red text colour
write-host "$serviceName : " -noNewLine
write-host $resultDisplay -foregroundColor(‘red’)
Start-Service "$servicename"
Start-Sleep -s 45
$serviceResults2 = [System.ServiceProcess.ServiceController]::GetServices($machineName) | where{ (($_.name -eq $serviceName) -or ($_.displayname -eq $serviceName))}
$serviceStatus2 = get-service $isServiceFound
$resultDisplay2 = $serviceStatus2.status
$smtpServer = "exchange2010.www.alanrocks.com"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)

$msg.From = "[email protected]"
$msg.To.Add("[email protected]")
$msg.Subject = "$serviceName Service ERROR"
$msg.Body = "Something Broke!!!!!"
$msg.Body += "`n `n$serviceName : $resultDisplay"
$msg.Body += "`n `n `n"
$msg.Body += "I have tried to start the service and "
if ($resultDisplay2 -eq "Running")
{
$msg.Body += "it is now running successfully"
$msg.Body += "`n $serviceName : $resultDisplay2"
Write-Host "I have tried to start the service $serviceName and is now running"
}
else
{
$msg.Body += "it is STILL NOT STARTED"
$msg.Body += "`n $serviceName : $resultDisplay2"
Write-Host "I have tried to start the service $serviceName and is STILL NOT running"
}

$smtp.Send($msg)
}
}
}

# this line dynamicaly loads the .NET assemblies into memory so they can be used by this script
$loadAssemblies = [System.Reflection.Assembly]::LoadWithPartialName(‘system.serviceprocess’)

# setup the list of services we want to check
# modify this array to suit your needs
$serviceList = "SQL Server (SQLEXP_VIM)", "VMware VirtualCenter Server", "VMware VirtualCenter Management Webservices"

# loop through the list of services and check then report on the status of each one
foreach ($serviceEntry in $serviceList)
{
# try and get the service’s status (if it exists)
checkService $serviceEntry ‘localhost’
}

# not important, just for clean-screen reasons again 🙂
write-host ""
[/powershell]