Add iSCSI Target to Software iSCSI Initiator on All Hosts in a Datacenter

If you’re like me, you have noticed that adding an iSCSI target to many hosts takes a really long time in the vSphere client. You have to navigate to the configuration tab of each host, enter the storage adapters section, select the iSCSI initiator you want to update, go to properties, to dynamic discovery, add the IP address, and finally rescan the HBA to see the new block device(s).

Many of these steps have a lag time of up to 30 seconds. These steps are obviously not difficult, but this time really starts to add up when you’re updating many hosts.

I’ve created the script below to automate this process, and save some time. When running the script, you’ll be prompted for the vCenter server you’d like to connect to, the IP address of the new iSCSI target, and whether or not you’d like to initiate a rescan on each host after adding the new target IP address.

If there is more than one datacenter in the selected vCenter, you’ll have to choose which datacenter you would like to work with. This script assumes that you want to add the target to all hosts in the datacenter, but you could easily take the section of code that selects the datacenter and reuse it to make a cluster selection.

 


###############################################
# Author: Brad Payne
# Date: 4/5/13
# Purpose: Add a new iSCSI send target to all hosts in a datacenter
###############################################
if( (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null){
Add-PSSnapin VMware.VimAutomation.Core
}
&"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1"

FUNCTION ADD-ISCSITARGET($VC,$IP,$RESCANHBA){
Connect-VIServer $VC

$DATACENTERS = @(Get-Datacenter )
IF($DATACENTERS.COUNT -gt 1){
Write-Host "THERE ARE MORE THAN ONE DATACENTERS IN THIS VCENTER: "
FOR($i=1; $i -lt $datacenters.COUNT; $i++){
Write-Host $i")" $datacenters[$i].NAME
}
$SELECTION = Read-Host "WHICH ONE WOULD YOU LIKE TO CONFIGURE?"
$SELECTION = $SELECTION-1
$THISDATACENTER = Get-Datacenter $datacenters[$SELECTION]
}
ELSE{
$THISDATACENTER = $DATACENTERS[0]
}

$HOSTS = GET-DATACENTER $THISDATACENTER |Get-VMHost
FOR($I=0; $i -lt $HOSTS.COUNT; $i++){
$TARGETEXISTS = $FALSE
$TARGETIPS = @(Get-VMHost $HOSTS[$I] | Get-VMHostHba *32 | Get-IScsiHbaTarget)
FOREACH($TARGET IN $TARGETIPS){
IF($TARGET.ADDRESS -eq $IP){
$TARGETEXISTS = $true
}
}
IF($TARGETEXISTS -eq $false){
GET-VMHOST $HOSTS[$I] | Get-VMHOSTHBA *32 | New-IScsiHbaTarget -Address $IP -Port 3260

IF($RESCANHBA){
GET-VMHOST $HOSTS[$I] | Get-VMHostStorage -RescanAllHba -RescanVmfs
}
}
}
}

$vcenter = Read-Host "ENTER THE VCENTER YOU'D LIKE TO CONNECT TO"
$ISCSITARGETIP = Read-Host "ENTER THE IP ADDRESS OF THE NEW ISCSI TARGET"
$RESCAN = READ-Host "ADDING AN ISCSI TARGET IP ADDRESS REQUIRES RESCANNING OF THE HOST HBA IN ORDER TO SEE ANY NEW LUNS. WOULD YOU LIKE TO RESCAN FOLLOWING ADDING THE TARGET IP? "
WHILE($RESCAN -ne "Y" -and $RESCAN -ne "N"){
Write-Host "THAT IS AN INVALID RESPONSE."
$RESCAN = Read-Host "WOULD YOU LIKE TO RESCAN FOLLOWING ADDING THE TARGET IP? "
}

IF ($RESCAN = "Y"){
$RESCAN = $true
}
ELSE{
$RESCAN = $false
}

ADD-ISCSITARGET $VCENTER $ISCSITARGETIP $RESCAN

Add NFS Datastore to all Hosts in a Chosen Cluster

Have you ever wished you could add a datastore to all hosts for a given cluster at once, rather than having to add it to each host one-by-one? This PowerCLI script was created to accomplish just that.

It’s pretty straight forward – run it and you’ll be prompted for some input, namely:

  • Name of a vCenter
  • If more than one cluster exists in that cluster, a cluster selection
  • IP of NAS hosting the NFS export you wish to mount
  • NFS export path
  • Datastore name

Note: As the script runs, you’ll see some red error text. This is the script returning an error on getting a datastore with the name provided.  There are better (far more elegant) ways to do this, I’ll update the script with a better method down the road…

 

#***************************************************************************
#
# Add NFS Storage to All Hosts of a chosen cluster.
# Author: Brad Payne
# Date: 04/05/11
#
#***************************************************************************
if( (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null){
	Add-PSSnapin VMware.VimAutomation.Core
}
&"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1"

$vCenter = Read-Host "Enter vCenter Name or IP"
Connect-VIServer $vCenter

$clusters = @(Get-Cluster)
if($clusters.count -gt 1){

    for($clusterCount=0;$clusterCount -lt $clusters.count; $clusterCount++){
        $optionvalue = $clusterCount + 1
        Write-Host $optionvalue ")" $clusters[$clusterCount].Name

    }
    $input = Read-Host "Select a Cluster"
    $selectedCluster = $clusters[$input-1]
}
else{
    $selectedCluster = $clusters[0]

}

$ClusterName = $selectedCluster.Name

$Hosts = @(Get-Cluster -Name $ClusterName | Get-VMHost)
Write-Host $Hosts

$NewNFSHost = Read-Host "Enter NFS Host IP"
$NewExportPath = Read-Host "Enter Export Path"
$NewDataStore = Read-Host "Enter name for new DataStore"

#Get-Cluster -Name $ClusterName | Get-VMHost | New-Datastore -Nfs -Name $NewDataStore -Path $NewExportPath -NfsHost $NewNFSHost

for($esxcounter=0;$esxcounter -lt $Hosts.Count; $esxcounter++){
	$dsExists = Get-VMHost $Hosts[$esxcounter].name | Get-Datastore $NewDataStore
	if($dsExists -eq $null){
		New-Datastore -Nfs -VMHost $Hosts[$esxcounter].name -Name $NewDataStore -Path $NewExportPath -NfsHost $NewNFSHost
	}
	else{
		Write-Host -ForegroundColor Red "Datastore already exists on" $Hosts[$esxcounter].name
	}
}

Script to Backup MySQL Database

Being that that this blog is “Proudly Powered by WordPress,” which uses a MySQL database, I wanted to find a way to schedule regular backups of MySQL databases. I am not that well versed with MySQL – all of the DB’s which I work with professionally are either SQL Server or Oracle – so I was looking to MySQL WorkBench to do the scheduling of regular backups, and to my dismay, you can’t schedule backups there.

I am not sure if this is something that Oracle has stripped out, or what, but it’s pretty crazy. So, I created this quick and easy PowerShell script to use the MySQLDump.exe to export the DB to a specified location, and cleanup any backups older than 1 month old.

Use the Task Scheduler to create a task to execute this script daily or weekly, and you’re set with your local backups of your MySQL DB.

Hope someone new to MySQL stumbles across this in less time than I took to realize that this functionality was not in MySQL WorkBench and to write the script. Enjoy!

############################################
# Author: Brad Payne
# Purpose: Backup MySQL databases
# Date: 5/1/2012
############################################

############################################
#  VARIABLES WHICH NEED TO BE DEFINED
############################################
$mysqlpath = <PATH TO FOLDER CONTAINING MYSQLDUMP.EXE>
$backuppath =<BACKUP LOCATION>
$username = <DB USERNAME>
$password = <DB PASSWORD>
$database = <DB NAME>
$errorLog = <LOCATION OF ERROR LOG (INCLUDING FILE NAME)>
############################################
# END OF VARIABLES NEEDING DEFINED
############################################

$date = Get-Date
$timestamp = "" + $date.day + $date.month + $date.year + "_" + $date.hour + $date.minute

$backupfile = $backuppath + $database + "_" + $timestamp +".sql"

CD $mysqlpath
.\mysqldump.exe --user=$username --password=$password --log-error=$errorLog --result-file=$backupfile --databases $database 

CD $backuppath
$oldbackups = gci *.sql*

for($i=0; $i -lt $oldbackups.count; $i++){
	if ($oldbackups[$i].CreationTime -lt $date.AddMonths(-1)){
		$oldbackups[$i] | Remove-Item -Confirm:$false
	}
}

XenApp 6 PowerShell SDK: Enabling Remoting via Enable-XAPSRemoting

I was running through the steps outlined over at http://community.citrix.com/display/ocb/2010/09/07/XenApp+6+SDK+-+Remoting+via+PowerShell+Remoting the other day, and just wanted to comment on one thing that I came across.

I was beginning to get frustrated because I could not successfully run the Enable-XAPSRemoting command on my Citrix Server, because it was telling me that it did not have a certificate to use for SSL communication. I installed the PowerShell SDK for XenApps 6, this server is a web interface so I have IIS installed, I have an internal PKI so rather than using a self-signed certificate as detailed in the Citrix forum, I installed a certificate from my internal CA via the IIS certificate wizard.

Now that I have this certificate installed, I should be able to enable XAPSRemoting, and remotely invoke the Citrix PowerShell commandlets from computers in my domain over an SSL connection, right? Wrong (not yet anyway).

Problem

Issuing the Enable-XPSRemoting command from the Citrix Server returns a response that I do not have a certificate to use for SSL which has CN=servername.domain.local in the subject, and has Server Authentication specified in the Enhance Key Usage field.  Did I screw up my certificate request and create a common name that does not match the FQDN? Is the certificate not in the right store?

First I check that the certificate is there. Since I am already in PowerShell, I check the store from there cd cert:\localmachine\my shows the certificate is there with the proper CN in the subject. Secondly, I fire up the Certificates Snapin from the MMC, and view the certificate. Everything looks good there, it has the “Server Authentication” in the Enhanced Key Usage field, which I am being told is required, and the subject has the proper CN=server.domain.local FQDN. The error message only states these two requirements for my certificate.

Resolution

From the Certificates Snapin in my MMC, I request a computer certificate from my internal CA. Once installed, I run the Enable-XAPSremoting command again, and it executes without error. Going back to view the certificates side-by-side, the only thing that I can tell is that the Enhanced Key Usage has both Server AND Client Authentication.

I am not sure how many people will run into this, but since there is few little information about the XenApp PowerShell SDK at this time, I thought it couldn’t hurt to provide this information.