Friday 21 August 2015

PowerCLI to check cross-connect active path correct for VPLEX

Usually hosts set their active path correctly from the disk nearest to the host, but sometimes they need help.  This script will email any paths on any hosts that are wrong.

Assumptions are that you have Site1 and Site2 in the hostnames.  PowerPath is the default path selection method, and it reports CL1 for cluster1 and CL2 for cluster2.   Hostname pattern is near script (I couldn't get it passed as a variable, let me know if you see how to fix that for us all).  
________________________________________________________________

Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer vSphere -User DOM\powercli -Password password -Force
#
#disConnect-VIServer vSphere -confirm:$false
#
#
#SiteA
#SiteA runs on AMP Element MgrA and checks for CL1
$bldghost = "SiteA*"

$correctcluster = "CL2"
$correctcluster = "CL1"

#SiteB
#SiteB runs on AMP Element MgrB and checks for CL2
###$bldghost = "SiteB*"
###$correctcluster = "CL2"

$allhosts = Get-VMHost "SiteA*"

foreach ($esx in Get-VMHost "SiteA*")


{

#write-host "$esx is esxhost"
### PowerPath command rpowermt , then grabbing asb:prox and CL1 or CL2
$wrongpath = rpowermt username=root password=password host=$esx display dev=all | out-string -stream | select-string "asb:prox" | out-string -stream | select-string $correctcluster

### if this variable exists, then it means we have a problem & need an email alert
if ($wrongpath) 

{

#write-host $wrongpath is wrongpath

#write-host vBlock cross connect path wrong for $esx as $bldghost asb:proxy needs to be set to
#$wrongpath

$wrongpathandesx = "
$esx host
=================================================================================
$wrongpath

"
$errormail += $wrongpathandesx

$errorcheck += $wrongpath

}

else 

{

write-host "cluster $correctcluster for active path is correct for asb:proxy cross-connect VPLEX luns on $esx"

}

}

### get Email info from vCenter
$vCenterSettings = Get-View -Id 'OptionManager-VpxSettings'
$MailSender1 = $env:computername+'.uk01.apmn.org'
$MailSender = "vBlock_AMP_ArrayMgr@$MailSender1"
$MailSmtpServer = ($vCenterSettings.Setting | Where-Object { $_.Key -eq "mail.smtp.server"}).Value
$MailSendingTo = "email@email.com"


#write-host $MailSender1 is MailSender1 and $MailSender is MailSender

if ($errorcheck) 

{

#$mailtext = $errormail | Format-List

$emailbody2 = "RDP to $MailSender1 as these active paths should be set to $correctcluster and need the rpowermt set path_latency_monitor and set autostandby=reinitialize commands ran from CLI after sVMotioning to the host to create traffic

$errormail"

$emailbody0 = '<pre>{0}</pre>' -f [System.Net.WebUtility]::HtmlEncode($emailbody2) 


Send-MailMessage -from $MailSender -to $MailSendingTo -subject "alert: VPLEX cross-connect active paths wrong" -body $emailbody0 -BodyAsHtml -smtpServer $MailSmtpServer


}

else

{


$emailbody2 = "cluster $correctcluster for active path is correct for asb:proxy cross-connect VPLEX luns for $bldghost hosts:

$allhosts"

write-host $emailbody2

Send-MailMessage -from $MailSender -to $MailSendingTo -subject "ok: VPLEX cross-connect active paths good" -body $emailbody2 -smtpServer $MailSmtpServer

}

disConnect-VIServer vSphere -confirm:$false

Report Changes to DRS/HA settings

Do your vCenter settings get changed when they shouldn't?  This script will email an alert when anything has changed.  

First you need to run once and it'll create "E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-File.txt" and copy that file to "E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-Baseline.txt".

From then on each time the script runs (schedule in Windows Task Scheduler), a new GetCluster-File is created and compared to the baseline file.

___________________________________________________________________

# created by KC on 2015/06/04
#
#
#pre-reqs are:
# 1.  set vCenter server for Connect command
# 2.  verify/create directory/file
# E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-Baseline.txt (Cam)
# F:\scripts\PowerCLI\logs\HA-DRS-GetCluster-Baseline.txt(Basel)
#
#
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer vSphere
#
# after valid change to HA/DRS settings in vSphere, copy
# E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-File.txt
# overwriting and replacing:
# E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-Baseline.txt
# to prevent alerts by this script
#
#get email variables from vCenter 
#
$vCenterSettings = Get-View -Id 'OptionManager-VpxSettings'
$emailFrom = ($vCenterSettings.Setting | Where-Object { $_.Key -eq "mail.sender"}).Value
$smtpServer = ($vCenterSettings.Setting | Where-Object { $_.Key -eq "mail.smtp.server"}).Value
#set email variables manaully
$emailRcpt = "email@email.com"

$MailSendingTo = "email@email.com"
#
#set variables for baseline file and new cluster-file
#
$GetClusterFile =  'E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-File.txt'
$GetClusterBaseline = 'E:\scripts\PowerCLI\logs\HA-DRS-GetCluster-Baseline.txt'
$GetClusterMail = 'E:\scripts\PowerCLI\logs\HA-DRS-GetClusterMail.txt'
#
#
#collect cluster config info and send to screen
#
Get-Cluster | Sort-Object -Property Name | 
Select-Object -Property Name,HAEnabled,HAAdmissionControlEnabled,
@{N="AdmissionControlPolicy";E={$_.ExtensionData.Configuration.Dasconfig.AdmissionControlPolicy.GetType().Name}},
DrsEnabled,DrsMode,DrsAutomationLevel
#
#
#collect cluster config info and send to file
#
Get-Cluster | Sort-Object -Property Name | 
Select-Object -Property Name,HAEnabled,HAAdmissionControlEnabled,
@{N="AdmissionControlPolicy";E={$_.ExtensionData.Configuration.Dasconfig.AdmissionControlPolicy.GetType().Name}},
DrsEnabled,DrsMode,DrsAutomationLevel | out-file $GetClusterFile
#
# Get remaining cluster info, send to screen
#
Get-Cluster | Select-Object -Property Name,
@{N="CpuFailoverResourcesPercentage";E={$_.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy.CpuFailoverResourcesPercent}},
@{N="MemoryFailoverResourcesPercentage";E={$_.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy.MemoryFailoverResourcesPercent}} 

#
# Get remaining cluster info, appending to file
#
Get-Cluster | Select-Object -Property Name,
@{N="CpuFailoverResourcesPercentage";E={$_.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy.CpuFailoverResourcesPercent}},
@{N="MemoryFailoverResourcesPercentage";E={$_.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy.MemoryFailoverResourcesPercent}} >> $GetClusterFile
#
# load GetCluster info into variable for email later
$hadrs_getclusterfile = Get-Content $GetClusterFile
#$hadrs_baselinefile = Get-Content $GetClusterBaseline
#
#
$Report = Compare-Object -Ref (Get-Content $GetClusterFile) -Diff (Get-Content $GetClusterBaseline) -Verbose | Out-String 

write-output $Report $hadrs_getclusterfile > $GetClusterMail
#
$Same_Or_Diff = Compare-Object -Ref (Get-Content $GetClusterFile) -Diff (Get-Content $GetClusterBaseline) | Measure | select Count
#
#
$z = $Same_Or_Diff.Count
if ( $z -eq 0)
{
write-host $Same_Or_Diff 
write-host "is Same_Or_Diff"
write-host $z 
write-host "is Count of differences, should be equal to 0" 
write-host "which means no change to HA/DRS config at" 

#$Report = "$MailSender HA/DRS config is unchanged, no action needed for $MailSender"
$MailSender 

$Report = (Get-Content $GetClusterFile | out-string)

#commented email so we only get alerts for problems
#email results
#Send-MailMessage -from $emailFrom -to $emailRcpt -subject "HA/DRS Config Alert OK - not changed" -body $Report -smtpServer $SmtpServer
}
#
else
#
{
#
write-host $Same_Or_Diff 
write-host "is Same_Or_Diff"
write-host $z 
write-host "is Count of differences, should not be equal to 0" 
write-host "A change to HA/DRS config at" $MailSender "needs investigation" >> $GetClusterMail
write-host $Report
write-host is email body
#
#
#email results

$Report = (Get-Content $GetClusterMail | out-string)

#Send-MailMessage -from $MailSender -to kevin.cade@napp.co.uk -subject "Alert: HA/DRS Change Config Change Changed" -body $Report -smtpServer $MailSmtpServer

#prepare email
$emailSubject = "Alert: HA/DRS Change Config Changed!" 
$msgBody = $Report
$smtp = New-Object Net.Mail.SmtpClient -arg $smtpServer
#send email
$smtp.Send($emailFrom,$emailRcpt,$emailSubject,$msgBody)

Send-MailMessage -from $emailFrom -to $emailRcpt -subject "HA/DRS Config Alert changed!" -body $Report -smtpServer $SmtpServer


}

disConnect-VIServer vSphere -confirm:$false

PowerCLI VM Host & DataStore affinity

We name our datastores with a three letter prefix which is the same three first letters of our hosts.  Folks who create VMs often forget to create the DRS rules so this script can be scheduled to run via Task Scheduler to alert us of VMs that need fixing:

____________________________________



### add snapin so PowerShell runs with PoweCLI features
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer vSphere
#
$vms = Get-View -ViewType VirtualMachine -Property Name,Datastore,"Runtime.Host",  "Runtime.PowerState" 
### exclude Microsoft SQL Cluster VMs with RDMs that report disks from both sites 
$emailbody = foreach($vm in $vms){ 
    if ($vm.Name -ne "ClusterVM1" -and $vm.Name -ne "ClusterVM2") 
    {
### only report on VMs that are powered on
       if ($vm.Runtime.PowerState -eq "poweredOn") 
       {
### exclude hosts as needed
        $esx = Get-View $vm.Runtime.Host -Property Name
        if ($esx.Name.Split('.')[0] -ne "vh99" )
        {
            $ds = Get-View $vm.Datastore -Property Name
### report those datastores that don't match first three letters of hostname with first three letters of datastore name
            if ($ds | where {$_.Name.Substring(0,2) -notmatch $esx.Name.Substring(0,2)})
            
            {
                      
                       $vm | Select Name,
                        @{N="Host";E={$esx.Name.Split('.')[0]}},
                        @{N="DataStore";E={[string]::Join(',',($ds | %{$_.Name}))}} | out-string
               
            }
        }
        }
    }

### for email alert, get mail info from vCenter database
$vCenterSettings = Get-View -Id 'OptionManager-VpxSettings'
$MailSender = ($vCenterSettings.Setting | Where-Object { $_.Key -eq "mail.sender"}).Value
$MailSmtpServer = ($vCenterSettings.Setting | Where-Object { $_.Key -eq "mail.smtp.server"}).Value
$MailSendingTo = "email@email.com"

### test for VMs with running on wrong host according to datastore
if ($emailbody) 

{

write-host "These VMs are misconfigured and will fail during an outage of either data center, and they will fail with an outage of the link between data centres.  Fix the VMware DRS rule on $MailSender so these VMs run on host and disks in the same data center.  These VMs with disks and hosts spanning two locations are at risk of needless loss of service to our customers:

$emailbody"

$emailbody2 = "These VMs are misconfigured and will fail during an outage of either data center, and they will fail with an outage of the link between data centres.  Fix the VMware DRS rule on $MailSender so these VMs run on host and disks in the same data center.  These VMs with disks and hosts spanning two locations are at risk of needless loss of service to our customers:

$emailbody"

Send-MailMessage -from $MailSender -to $MailSendingTo -subject "alert: VM Host/Disk affinity violations" -body $emailbody2 -smtpServer $MailSmtpServer

}

else


write-host "ok: host/datastore affinity is correct for all VMs in $MailSender" 

$emailbody2 = "host/datastore affinity is correct for all VMs in $MailSender"

Send-MailMessage -from $MailSender -to $MailSendingTo -subject "ok: no VM Host/Disk affinity violations" -body $emailbody2 -smtpServer $MailSmtpServer

}

disConnect-VIServer vSphere -confirm:$false

________________________________________________

Thanks to LucD for doing the real work of this script.