Tag Archives: PowerShell

Installing PowerShell Web Access on Windows 2012 RC Core

Recently I wanted to check out the Windows 2012 RC build and more specifically some of the new PowerShell features.  I have seen the Web Access mentioned a few times now so wanted to deploy a quick box to test this out.

I decided to try windows core and see how easy it was to get started with PowerShell Web Access, after the install which was very fast I changed my Administrator password and then logged into the box, I was immediately presented with a command prompt, the following steps are what I took to add PowerShell Web Access into my test environment.

Step by Step

Step 1 was to launch PowerShell and add the windows feature for PowerShell Web Access

TinyGrab Screen Shot 05-06-2012 20.31.43

Next I setup the certificates, note that I just used the test certificates as this was a test box but if you are installing this in live you should use the help on Install-PswaWebApplication to see the further parameters needed for a proper certificate.

TinyGrab Screen Shot 05-06-2012 20.36.58

Next I added a single rule to allow the local Administrator access to this machine, again you can obviously setup the rules as needed in your environment with this cmdlet.

TinyGrab Screen Shot 05-06-2012 23.31.00

After this has been completed you should now be able to visit the https site to receive a login window, in my example the URL was https://hostname/pswa

TinyGrab Screen Shot 05-06-2012 23.05.03

Here you must enter the credentials to login to the host…

TinyGrab Screen Shot 05-06-2012 23.29.38

Once logged in you should have a familiar window, as you can see I issued a Get-Command to list all the cmdlets available to me…

TinyGrab Screen Shot 05-06-2012 23.31.50

VMworld Session Voting

Disclaimer: This lady will not be at my session!I’m sure by now you have already seen that the VMworld Voting is open which means its time to have your say on what you want to see at VMworld, if you have not yet signed up for a VMworld account so that you can vote then please do so by following this link.

Now I could do the normal “Vote for me because because PowerCLI will solve world famine” post but I thought I would do something different to the rest, what I’m going to do is just use the coolness of PowerShell to allow you to find my sessions, once you have them on your screen have a read of them for yourself and then you can decide if you ant to vote for them or not.

You can do that by simply changing the username and password parts of the script below and allowing it to log into the VMworld site and display my sessions for you.  This will of course not click the “Vote” button as that would be cheating, it will however give you a nice list of my sessions where you can click to get further information.

If however you like what you see and want to vote then just click the thumb picture to make it green and I will thank you forever more and we will see what we can do about world famine.

Use the Script

$VMworldUser = "myvmworldusername"
$VMworldPassword = "myvmworldpassword"
# Replace the username and password above

$ie = New-Object -com InternetExplorer.Application
$ie.visible=$true
$ie.navigate("http://www.vmworld.com/www.vmworld.com/cfp-login!input.jspa")
while($ie.ReadyState -ne 4) {start-sleep -m 100}
$ie.document.getElementById("username01").value= $VMworldUser
$ie.document.getElementById("password01").value = $VMworldPassword
$ie.document.getElementById("loginformaction").submit()
while($ie.Document.url -ne "https://vmworld2012.activeevents.com/scheduler/publicVoting.do") {start-sleep -s 7}
$ie.document.getElementById("searchEl").value = "Renouf"
$ie.Document.getElementById("displayOptionsForm").submit()

Overview

Here are a list of the submissions I have put forward for VMworld this year:

image

Updated Script to remediate VDS/SvMotion issue

Following my recent post where I showed how we could search for and fix any VMs which had an issue after being Storage vMotioned and attached to a VDS I received a couple of emails from people with a few issues.

Firstly the script was written using the VDS PowerShell fling (Check it out, its cool), some people were not able to use this fling in production systems as it is not officially supported by VMware.

Secondly the fling only supported VDS and not the Nexus 1kv, some customers had this issue with the N1KV so needed a resolution.

The good news…

I have re-written the script to no longer use the fling but instead use the raw API’s, this means all you now need is PowerCLI 5.0.1 and you can run the below script in the same way as before to check and remediate for issues.

Thanks goes to Luc who came up with an easy way to check for free ports on the VDS here.

Remember this does not fix the issue completely, only a patch from VMware will do that but it does however tell you if you have the issue and plug the gap temporarily.

Just as a reminder, here is how the script is used:

Using the script

To check the VMs we can easily pipe a list of VMs into our function which can be seen below.  This can be all VMs in a Cluster, all VMs on a particular host or any other list of VMs you can think of, for my examples below I have shown all VMs attached to a vCenter

image

As you can see from the above screenshot, all VMs are fine apart from VM12 which currently has the problem described in Duncan’s article,  now to fix the issue.

We can use the same script with a –Fix parameter which allows us to fix the issue, when fixing the issue the script will move each of the VMs network connections to a new port on the same portgroup and then move it back again to its original port.   If no free ports are available the script will expand your portgroup temporarily and then decrease the ports when finished.

image

As you can see from the above screenshot, the issue has now been resolved for this VM by using the function with the –Fix parameter and further running of the script in test mode will show all are now fine.

The Script

Function Get-FreeVDSPort ($VDSPG) {
	$nicTypes = "VirtualE1000","VirtualE1000e","VirtualPCNet32","VirtualVmxnet","VirtualVmxnet2","VirtualVmxnet3"
	$ports = @{}

	# Get all the portkeys on the portgroup
	$VDSPG.ExtensionData.PortKeys | Foreach {
		$ports.Add($_,$VDSPG.Name)
	}

	# Remove the portkeys in use  Get-View
	$VDSPG.ExtensionData.Vm | Foreach {
	    $VMView = Get-View $_
		$nic = $VMView.Config.Hardware.Device | where {$nicTypes -contains $_.GetType().Name -and $_.Backing.GetType().Name -match "Distributed"}
	    $nic | where {$_.Backing.Port.PortKey} | Foreach {$ports.Remove($_.Backing.Port.PortKey)}
	}

	# Assign the first free portkey
	if ($ports.Count -eq 0) {
		$null
	} Else {
		$ports.Keys | Select -First 1
	}
}

Function Set-VDSPGNumPorts ($VDSPG, $NumPorts) {
	$spec = New-Object VMware.Vim.DVPortgroupConfigSpec
    $spec.numPorts = $NumPorts
	$spec.ConfigVersion = $VDSPG.ExtensionData.Config.Configversion
    $VDSPG.ExtensionData.ReconfigureDVPortgroup($spec)
}

Function Test-VDSVMIssue {
	Param (
		[parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [PSObject[]]$VM,
		[switch]$Fix
	)
	Process {
		Foreach ($VMachine in $VM){
			Foreach ($NA in ($VMachine | Get-NetworkAdapter)) {
				$VMName = $VMachine.Name
				If (($NA.ExtensionData.Backing.GetType()).Name -eq "VirtualEthernetCardDistributedVirtualPortBackingInfo") {
					$PortKey = $NA.ExtensionData.Backing.Port.PortKey
					$vSwitchID = $NA.ExtensionData.Backing.Port.SwitchUUID
					$Datastore = (($VMachine.ExtensionData.Config.Files.VmPathName).split("]")[0]).Replace("[","")
					$filename = "$($datastore):\.dvsData\$vSwitchID\$PortKey"
					if (-not (Get-PSDrive $datastore -ErrorAction SilentlyContinue)) {
						$NewDrive = New-PSDrive -Name $Datastore -Location (Get-Datastore $Datastore) -PSProvider VimDatastore -Root '\'
					}
					$filecheck = Get-ChildItem -Path $filename -ErrorAction SilentlyContinue
					if ($filecheck) {
						Write-Host -ForegroundColor Green "$VMName $($NA.Name) is OK"
					} Else {
						Write-Host -ForegroundColor Red "Problem found with $VMName $($NA.Name)"
						If ($Fix) {
							Write-Host -ForegroundColor Yellow "Fixing issue..."
							$VDSPG = Get-VirtualPortGroup -Distributed -Name $NA.NetworkName
							$DVPort = $null
							Write-Host -ForegroundColor Yellow "..Finding free port on $($NA.NetworkName)"
							$DVPort = Get-FreeVDSPort $VDSPG
							$Move = $True
							if (-not $DVPort) {
								Write-Host -ForegroundColor Yellow "..No free ports found on $($VDSPG.Name), adding an additional port"
								If (($VDSPG.ExtensionData.Config.Type -ne "lateBinding") -and ($VDSPG.ExtensionData.Config.Type -ne "earlyBinding")) {
									Write "Unable to add a port to $($NA.NetworkName) since dvportgroup is configured as $($VDSPG.PortBinding)"
									Write-Host -ForegroundColor Red "Problem still exists with $VMName please resolve manually"
									$Move = $false
								} Else {
									$CurrentPorts = $VDSPG.NumPorts
									$NewTotalPorts = $VDSPG.NumPorts + 1
									Set-VDSPGNumPorts -VDSPG $VDSPG -NumPorts $NewTotalPorts
									$PGAdded = $true
									$VDSPG = Get-VirtualPortGroup -Distributed -Name $NA.NetworkName
									$DVPort = Get-FreeVDSPort $VDSPG
								}
							}
							If ($Move){
								Write-Host -ForegroundColor Yellow "..Moving $($NA.Name) to another free port on $($VDSPG.Name)"
								$NA | Set-NetworkAdapter -PortKey $DVPort -DistributedSwitch $VDSPG.VirtualSwitch -Confirm:$false | Out-Null
								Write-Host -ForegroundColor Yellow "..Moving $($NA.Name) back to port $PortKey"
								$NA | Set-NetworkAdapter -PortKey $PortKey -DistributedSwitch $VDSPG.VirtualSwitch -Confirm:$false | Out-Null
								Write-Host -ForegroundColor Yellow "..Checking changes were completed"
								$filecheck = Get-ChildItem -Path $filename -ErrorAction SilentlyContinue
								if ($filecheck) {
									Write-Host -ForegroundColor Green "$VMName $($NA.Name) is now fixed and OK"
								} Else {
									Write-Host -ForegroundColor Red "Problem still exists with $VMName please resolve manually"
								}
								If ($PGAdded) {
									Write-Host -ForegroundColor Yellow "..Removing the added port on $($VDSPG.Name)"
									Set-VDSPGNumPorts -VDSPG $VDSPG -NumPorts $CurrentPorts
									$PGAdded = $false
								}
							}
						}
					}
				} Else {
					Write-Host -ForegroundColor Green "$VMName is not connected to a dvSwitch so this issue is not relevant."
				}
			}
		}
		Get-PSDrive | Where { ($_.Provider -like "*VimDatastore") -and ( $_.Name -notlike "*vmstore*")} | Foreach {
			Remove-PSDrive $_ | Out-Null
		}
	}
}

# Example code to check all VMs attached to vCenter for the issue:
# Get-VM | Test-VDSVMIssue

# Example code to fix all VMs attached to vCenter:
# Get-VM | Test-VDSVMIssue -Fix

# Example code to fix all VMs in Cluster01 for the issue:
# Get-Cluster01 | Get-VM | Test-VDSVMIssue

# Example code to fix all VMs in Cluster01:
# Get-Cluster01 | Get-VM | Test-VDSVMIssue -Fix

Optimized PowerShell performance with Cisco UCS PowerTool

imageIn the last post I gave a quick overview of one of the many cool features of the Cisco UCS PowerTool PowerShell Module, I showed how they had made it easy for the admin to pick up their toolkit and use it, how navigation over 1000+ cmdlets could be made easier, if you didn’t read it then you can find the post here.

I quickly realized this was not going to be a one blog post affair as there are so many great features in this PowerShell module which impressed me, features I have not seen before in PowerShell (I may be wrong).

How fast is your code ?

One thing I have seen both developers and scripters fight with is the speed at which things can be done, most times when not using PowerShell to just manage the local machine there is an element of accessing an external system.  There are many ways you can access these external systems depending on the company and the way the cmdlets are written.  Its great that PowerShell often has a certain amount of caching, when objects are retrieved from the remote systems or machines they can be altered locally and then sent back to the original destination.

It’s the sending back and retrieving information which can often cause some PowerShell cmdlets to be slow when working on large systems or when working with multiple systems.  Developers of PowerShell Modules and snapins often do a great job of optimizing this to make things faster.

In Cisco UCS PowerTool I saw a method I had not seen before which I thought was both a very system admin friendly and also optimized way of doing this.

The following example code shows how to create a simple boot policy, for the purpose of this post it doesn’t really matter what the code looks like but keep in mind that after the end of each line, and during the line there will be calls to the Cisco UCS API retrieving and setting data, at the end of the below code we may have called the API around 10 times, add this up into a more complex piece of code and then ask it to work on multiple systems and our external calls soon mount up, each external call having an impact on the final speed of the script.

$BootPolicy = Get-UcsOrg -Level root  | Add-UcsBootPolicy -Descr "Test Boot Policy" -EnforceVnicName "no" -Name "Test-BootPol" -RebootOnUpdate "no"
$BootLan = $BootPolicy | Add-UcsLsbootLan -ModifyPresent -Order "2" -Prot "pxe"
$BootLan | Add-UcsLsbootLanImagePath -BootIpPolicyName "" -ISCSIVnicName "" -ImgPolicyName "" -ImgSecPolicyName "" -ProvSrvPolicyName "" -Type "primary" -VnicName "1"
$BootPolicy | Add-UcsLsbootVirtualMedia -Access "read-only" -Order "1"
$BootStorage = $BootPolicy | Add-UcsLsbootStorage -ModifyPresent -Order "3"
$BootSanImage = $BootStorage | Add-UcsLsbootSanImage -Type "primary" -VnicName "0"
$BootSanImage | Add-UcsLsbootSanImagePath -Lun 0 -Type "primary" -Wwn "20:00:00:00:00:00:C0:00"

How Cisco makes this faster

The Cisco UCS PowerTool team have put some thought into this and as well as the performance enhancements built into the cmdlets they have also introduced a couple of cmdlets to allow you to make a single optimized call to the API – this is a fantastic idea as you can basically build up your code in a nice block and then send it all, optimized for the API in one call to the Cisco UCS API.

Lets take a look at our second example of this code:

Start-UcsTransaction
	$BootPolicy = Get-UcsOrg -Level root  | Add-UcsBootPolicy -Descr "Test Boot Policy" -EnforceVnicName "no" -Name "Test-BootPol" -RebootOnUpdate "no"
	$BootLan = $BootPolicy | Add-UcsLsbootLan -ModifyPresent -Order "2" -Prot "pxe"
	$BootLan | Add-UcsLsbootLanImagePath -BootIpPolicyName "" -ISCSIVnicName "" -ImgPolicyName "" -ImgSecPolicyName "" -ProvSrvPolicyName "" -Type "primary" -VnicName "1"
	$BootPolicy | Add-UcsLsbootVirtualMedia -Access "read-only" -Order "1"
	$BootStorage = $BootPolicy | Add-UcsLsbootStorage -ModifyPresent -Order "3"
	$BootSanImage = $BootStorage | Add-UcsLsbootSanImage -Type "primary" -VnicName "0"
	$BootSanImage | Add-UcsLsbootSanImagePath -Lun 0 -Type "primary" -Wwn "20:00:00:00:00:00:C0:00"
Complete-UcsTransaction

I feel the need, the need for speed**

** Anytime you can get a movie reference in a blog post its gotta be worth it Winking smile

As you can see from the above code, we have added a Start-UcsTransaction at the start and a End-UcsTransaction at the end, so what does this do ?

It allows all the code in between these statements to be gathered by the Cisco UCS PowerTool and optimized, then at the end one call is made to the API sending the complete data.

Performance boost or what ?!

I think the benefits of this are clear, more efficient, optimized and less frequent calls to the API can only mean faster code.

I think its great that Microsoft created PowerShell and third parties are continuing to pick it up as it becomes the default scripting language for the datacenter, in my eyes this is one area where a third party company has taken a fresh new look at the way things are performed and made a clear enhancement.  Very cool stuff, and there is more to come in further posts, I haven’t even got to the best feature yet !

Easily Creating PowerShell Quick References

I needed to provide some examples of PowerShell code recently for a quick reference poster and thought this might be useful for others looking for quick code examples.

All the examples you need can be found by using Get-Help with the –Examples parameter.  Did you know that as with everything else in PowerShell these items are returned as nice objects, we can easily pick the items we need to create a some text which can be copied into a quick reference document.  Of course I am assuming the PowerShell module has fully supported and correctly added help code Winking smile

Just replace the module name below and you are away !

The Code

Get-Command -Module VMware.ImageBuilder | Sort Name | Foreach {
	$Examples = Get-Help $_ -Examples
	Write-Host -ForegroundColor Blue $examples.Name

	$examples.examples.Example | Foreach {
		$Remarks = $_.Remarks | Select -ExpandProperty Text
		$Code = $_ | Select -ExpandProperty Code
		Write-Host -ForegroundColor DarkGreen "# $($Remarks)"
		Write-Host $Code
	}
	Write-Host
}

Example output

Add-EsxSoftwareDepot
# Connect to a depot.
Add-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml
# Connect to a depot, saving it to a variable.
$depot = Add-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml

Add-EsxSoftwarePackage
# Add a package by name to an image profile:
Add-EsxSoftwarePackage -ImageProfile “My custom profile” -SoftwarePackage net-bnx2
# Add a package of a specific name and version:
Add-EsxSoftwarePackage -ImageProfile “My custom profile” -SoftwarePackage “net-bnx2 1.6.7-0.1OEM1”
# Clone an image profile, then add a package by name, in one line using pipelining:
New-EsxImageProfile -CloneProfile “ESX-5.0-234567-standard” -Name “My custom profile” | \
Add-EsxSoftwarePackage net-bnx2

Compare-EsxImageProfile
# Compares Profile 1 with Profile 2.
Compare-EsxImageProfile “Profile 1” “Profile 2”

Export-EsxImageProfile
# Export an ISO image
Export-EsxImageProfile -ImageProfile “Evan’s Profile” -ExportToIso -FilePath c:\isos\evans-iso.iso
# Clone an image profile, add a software package, then export to offline bundle.
New-EsxImageProfile -CloneProfile “ESXi-5.0.0-234567-standard” -Name “Evan’s Profile”
Add-EsxSoftwarePackage -ImageProfile “Evan’s Profile” -SoftwarePackage cisco-vem-v140
Export-EsxImageProfile -ImageProfile “Evan’s Profile” -ExportToBundle -FilePath c:\isos\base-plus-vem.zip

Get-EsxImageProfile
# Display all image profiles from depots and all image profiles the user created during this PowerCLI session:
Get-EsxImageProfile
# Display all ESX 5.0 profiles:
Get-EsxImageProfile -Name “ESX-5.0*”
# Display all image profiles from vendors other than VMware:
Get-EsxImageProfile | ? {$_.Vendor -ne “VMware”}
# List all the VIB packages from a particular image profile:
(Get-EsxImageProfile -Name “Profile A”).VibList

Get-EsxSoftwareChannel
#

Get-EsxSoftwarePackage
# List all the VIBs from all depots in table form:
Get-EsxSoftwarePackage
# List all the VIBs, sorted by date:
Get-EsxSoftwarePackage | Sort-Object ReleaseDate | Format-Table -Property Name,Version,Vendor
# List all the VIBs from VMware and Cisco released after Jan 1, 2010:
Get-EsxSoftwarePackage -Vendor “VMware”,”Cisco” -ReleasedAfter 1/1/2010
# List all the VIBs from vendors other than VMware
Get-EsxSoftwarePackage | ? {$_.Vendor -ne “VMware”}
# List all the base VIBs for the 5.0.0 release:
Get-EsxSoftwarePackage -Name “esx-base” -Version “5.0.0-*”
# Save the results of a VIB query for later:
$vibs = Get-EsxSoftwarePackage -Name “esx-base” -Version “5.0.0-*”

New-EsxImageProfile
# Clone an image profile, give it a new name, and change the acceptance level. (NOTE: The ‘\’ is used to continue the second line of input; either press ENTER after \ or enter everything on one line without the ‘\’).
New-EsxImageProfile -CloneProfile “ESX-5.0-234567-standard” \
-Name “My custom profile” -AcceptanceLevel CommunitySupported
# Create an image profile from scratch, assigning the result to a variable.  Software packages are specified by name.
$ip = New-EsxImageProfile -NewProfile -Name “Built from scratch!” -Vendor “NotVmware” \
-SoftwarePackage esx-base,esx-tboot,misc-drivers
# Create an image profile from scratch, passing in software packages via pipeline
Get-EsxSoftwarePackage -Name esx-base,esx-tboot,misc-drivers |  \
New-EsxImageProfile -NewProfile -Name “Built from scratch!” -Vendor “NotVmware”

Remove-EsxSoftwareDepot
# Connect to a depot, then disconnect from it by URL.
Add-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml
[… do something …]
Remove-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml
# Connect to a depot, saving it to a variable, then disconnect from it later.  Also an example of pipeline input.
$depot = Add-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml
[… do something …]
$depot | Remove-EsxSoftwareDepot
# Disconnect from all software depots
Remove-EsxSoftwareDepot $DefaultSoftwareDepots

Remove-EsxSoftwarePackage
# Remove package foo from my custom profile:
Remove-EsxSoftwarePackage -ImageProfile “My custom profile” -SoftwarePackage foo

Set-EsxImageProfile
# Modify the VIB list of an existing image profile
Set-EsxImageProfile -ImageProfile “Profile of a Fool” -SoftwarePackage esx-base,scsi-ips,esx-tboot
# Change the acceptance level (maybe so that some VIB with a lower acceptance level can be added) of the third image profile from a list (index starts at 0):
$myprofiles = Get-EsxImageProfile
Set-EsxImageProfile -ImageProfile $myprofiles[2] -AcceptanceLevel PartnerSupported

Getting started with Cisco UCS PowerTool

imageToday I was lucky enough to grab some time with Eric Williams and colleagues over at Cisco, they held a one day training course on their UCS PowerTool which is a PowerShell module for managing UCS Systems, if you haven’t seen the Cisco UCS systems I suggest you get out from under that rock and check them out, they are fantastic implementation of a PowerShell module, currently they are available as a beta under the Cisco Developer network here.

Eric and the PowerTool Developers have done a fantastic job on PowerTool, at the moment they have 1498 cmdlets, I wont list them all here as that would be a post unto itself.  A huge amount of cmdlets and that means a huge amount of coverage, they have around 99.1% coverage.

There were many areas in this module that impressed me, most of all was the fact that only 35 of these cmdlets were written manually, the other cmdlets were generated automatically using the UCS Manager XML API and the schema, and I’m not talking about cmdlets which are just basic cmdlets either, these are fully pipeline enabled cmdlets !

In this post I will just mention one of their features which impressed me but I have a list of more to add so make sure you keep an eye out for further posts on this.

Getting Started

The Module comes with a getting started guide which can be found here, this is well worth a read and is full of examples.  At the time of writing this these are the only examples available as the cmdlets do not yet have help so the normal Get-Help cmdletname –Examples will not work.

How do you navigate 1498 cmdlets ?

One of the first things I wondered when I saw they had so many cmdlets was how do you find the one you need, obviously PowerShell has built in methods for this like using Get-Command with wildcards etc but with 1498 cmdlets this would only get you so far.

I was then shown Get-UCSCmdletMeta, this cmdlet is a fantastic way of finding not only cmdlets but also what cmdlets are used in conjunction with that cmdlet and also other cmdlets which you are likely to need, lets start with an example, say I wanted to get the VLANs I had setup in Cisco UCS, I would use the cmdlet as follows:

SNAGHTML13588856

As you can see it shows the verbs we can use with this and also the Noun so we know instantly what cmdlets are available for use with VLAN’s, it doesn’t end their either, it also gives us a PipelineClassId, these are basically the type of classes which can be piped into this cmdlet, that’s pretty cool.. but wait…

The even cooler thing about this is we can also see the cmdlets which this cmdlet can pipe into, to do this we can add a –tree parameter like so:

SNAGHTML135d6b55

Its great to see people putting thought into how to make things easier for users to use their cmdlets, this is a great way of showing the cmdlets and helping find your way around.

Identifying and fixing VMs Affected By SvMotion / VDS Issue

Duncan Epping recently described an issue with virtual machines (VMs) which have moved via Storage vMotion (SvMotion) and are connected to a vNetwork Distributed Switch (VDS), if you are using a configuration where VMs are connected to a VDS and could potentially move via SvMotion then please make sure you read his article here.

William recently showed how we could check for this issue using Perl, on this post you will see a similar script which uses PowerCLI to look for the issue and also resolve the issue fixing the VMs which could potentially have an issue.

In this script I use the VMware VDS Fling which adds VDS cmdlets to PowerCLI, more information and lots of examples on this fling can be found here.  Please make sure you have it installed before using this script and are using a 32 bit PowerShell or PowerCLI console.

Using the script

To check the VMs we can easily pipe a list of VMs into our function which can be seen below.  This can be all VMs in a Cluster, all VMs on a particular host or any other list of VMs you can think of, for my examples below I have shown all VMs attached to a vCenter

image

As you can see from the above screenshot, all VMs are fine apart from VM12 which currently has the problem described in Duncan’s article,  now to fix the issue.

We can use the same script with a –Fix parameter which allows us to fix the issue, when fixing the issue the script will move each of the VMs network connections to a new port on the same portgroup and then move it back again to its original port.   If no free ports are available the script will expand your portgroup temporarily and then decrease the ports when finished.

image

As you can see from the above screenshot, the issue has now been resolved for this VM by using the function with the –Fix parameter and further running of the script in test mode will show all are now fine.

UPDATE: The script has now been updated to support remediation for VMs connected to both a VMware VDS as well as Cisco N1KV. The solution, thanks to one of our internal engineers was to “move” the VM’s dvport from one to another, all while staying within the existing dvPortgroup which will also force the creation of the .dvsdb port file. Once the dvport move has successfully completed, we will move it back to it’s original dvport that it initially resided on. We no longer have to rely on creating a temporally dvPortgroup and best of all, we can now remediate both VDS and N1KV.

Disclaimer: This script is not officially supported by VMware, please test this in a development environment before using on production systems.

The Script

If (-Not (Get-PSSnapin VMware.VimAutomation.VdsComponent -WarningAction SilentlyContinue) ) {
	Add-PSSnapin VMware.VimAutomation.VdsComponent
}

Function Test-VDSVMIssue {
	Param (
		[parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
        [PSObject[]]$VM,
		[switch]$Fix
	)
	Process {
		Foreach ($VMachine in $VM){
			Foreach ($NA in ($VMachine | Get-NetworkAdapter)) {
				$VMName = $VMachine.Name
				If (($NA.ExtensionData.Backing.GetType()).Name -eq "VirtualEthernetCardDistributedVirtualPortBackingInfo") {
					$PortKey = $NA.ExtensionData.Backing.Port.PortKey
					$vSwitchID = $NA.ExtensionData.Backing.Port.SwitchUUID
					$Datastore = (($VMachine.ExtensionData.Config.Files.VmPathName).split("]")[0]).Replace("[","")
					$filename = "$($datastore):\.dvsData\$vSwitchID\$PortKey"
					if (-not (Get-PSDrive $datastore -ErrorAction SilentlyContinue)) {
						$NewDrive = New-PSDrive -Name $Datastore -Location (Get-Datastore $Datastore) -PSProvider VimDatastore -Root '\'
					}
					$filecheck = Get-ChildItem -Path $filename -ErrorAction SilentlyContinue
					if ($filecheck) {
						Write-Host -ForegroundColor Green "$VMName $($NA.Name) is OK"
					} Else {
						Write-Host -ForegroundColor Red "Problem found with $VMName $($NA.Name)"
						If ($Fix) {
							Write-Host -ForegroundColor Yellow "Fixing issue..."
							$VDSPG = Get-VdsDistributedPortgroup $NA.NetworkName
							$DVPort = $null
							Write-Host -ForegroundColor Yellow "..Finding free port on $($NA.NetworkName)"
							$DVPort = Get-VdsDVPort -DVPortgroup $VDSPG -Active:$false | Select -last 1
							$Move = $True
							if (-not $DVPort) {
								Write-Host -ForegroundColor Yellow "..No free ports found on $($VDSPG.Name), adding an additional port"
								If (($VDSPG.PortBinding -eq "Ephemeral") -or ($VDSPG.PortBinding -eq "Dynamic")) {
									Write "Unable to add a port to $($NA.NetworkName) since dvportgroup is configured as $($VDSPG.PortBinding)"
									Write-Host -ForegroundColor Red "Problem still exists with $VMName please resolve manually"
									$Move = $false
								} Else {
									$CurrentPorts = $VDSPG.NumPorts 
									$NewTotalPorts = $VDSPG.NumPorts + 1
									Set-VdsDistributedPortgroup -NumPorts $NewTotalPorts -DVPortgroup $VDSPG | Out-Null
									$PGAdded = $true
									$DVPort = Get-VdsDVPort -DVPortgroup $VDSPG -Active:$false | Select -last 1
								}
							}
							If ($Move){
								Write-Host -ForegroundColor Yellow "..Moving $($NA.Name) to another free port on $($VDSPG.Name)"
								$NA | Set-NetworkAdapter -PortKey $DVPort.Key -DistributedSwitch $VDSPG.VirtualSwitch -Confirm:$false | Out-Null
								Write-Host -ForegroundColor Yellow "..Moving $($NA.Name) back to port $PortKey"
								$NA | Set-NetworkAdapter -PortKey $PortKey -DistributedSwitch $VDSPG.VirtualSwitch -Confirm:$false | Out-Null
								Write-Host -ForegroundColor Yellow "..Checking changes were completed"
								$filecheck = Get-ChildItem -Path $filename -ErrorAction SilentlyContinue
								if ($filecheck) {
									Write-Host -ForegroundColor Green "$VMName $($NA.Name) is now fixed and OK"
								} Else {
									Write-Host -ForegroundColor Red "Problem still exists with $VMName please resolve manually"
								}
								If ($PGAdded) {
									Write-Host -ForegroundColor Yellow "..Removing the added port on $($VDSPG.Name)"
									Set-VdsDistributedPortgroup -NumPorts $CurrentPorts -DVPortgroup $VDSPG | Out-Null
									$PGAdded = $false
								}
							}
						}
					}	
				} Else {
					Write-Host -ForegroundColor Green "$VMName is not connected to a dvSwitch so this issue is not relevant."
				}
			}
		}
		Get-PSDrive | Where { ($_.Provider -like "*VimDatastore") -and ( $_.Name -notlike "*vmstore*")} | Foreach {
			Remove-PSDrive $_ | Out-Null
		}
	}
}

vCheck Exchange Updated

imagePhil has been doing some fantastic work with the Exchange 2010 version of vCheck, his latest version now even supports Exchange 2007 !

He has also updated most of the plugins with new and exciting data, if you have Exchange and you have not yet tried it make sure you give it a whirl, if you have already been using the previous version make sure you update to this great new version.

Download

To download this version of vCheck you can download the following file which includes the base script and all exchange plugins:

http://www.virtu-al.net/vcheck-pluginsheaders/vcheck/

For more information on the base vCheck script and its framework including a demo of how to use it visit this page.

Plugins

All Exchange Plugins are accessible via the Exchange plugins page located here.

Example Page

An example of the Exchange 2010 report can be viewed by clicking here.

Update Log

New in Exchange Plugins v2.0:

Exchange 2007 support

Report on drives with <= x% free space

MAPI Latency report where latency is above user specified threshold

Active DB not mounted on preferred server report

Various bug fixes and code cleanups

All the plugins have been renumbered into a more logical order

Plus, a bonus plugin to select (via vCheck.ps1 -config) the report header image

Added plugin “20 Exchange 20xx Largest Mailboxes by Total Size”, like 18 and 19,
but sorted by the sum of mailbox and dumpster sizes

————————————————————————————-

00 1st Plugin – Select Report Header Image
Sets report header image
For example, download the Exchange header from
http://www.virtu-al.net/featured-scripts/vcheck/vcheck-headers/
and save as vCheck\Headers\Exchange.png, and this will work out of the box
Falls back to vCheck\Header.jpg if specified header can’t be found

10 Exchange 20xx Load Snapin.ps1
Loads Exchange 2007 / Exchange 2010 powershel snapin

11 Exchange 20xx Basic Server Information.ps1
Basic Exchange server info: OS & Service pack, Exchange version, hotfix rollups,
Exchange Edition and Roles

12 Exchange 20xx Drive Details.ps1
Drive details for each of the Exchange servers.  Can be configured to report only
on drives with less than a specified percentage free space

13 Exchange 2010 Database Availability Groups.ps1
Basic info about your DAG groups – Exchange 2010 only

14 Exchange 20xx DB Statistics.ps1
Database statistics – number of mailboxes, sizes, circular logging, and last
backup dates

15 Exchange 2010 DB Status.ps1
Database status info

16 16 Exchange 2010 Active DB not on Preferred Server .ps1
Reports on databases not mounted on their preferred servers

17 Exchange 20xx MAPI Connectivity.ps1
List MAPI connectivity latencies – can be configured to only report on latencies
above a specified level

18 Exchange 20xx PF Statistics.ps1
Public Folder stats

20 Exchange 20xx Largest Mailboxes.ps1
Report on largest mailboxes by Mailbox size

21 Exchange 20xx Largest Dumpster.ps1
Report on largest mailboxes by Dumpster (deleted items) size

22 Exchange 20xx Largest Total Size.ps1
Report on largest mailboxes by Total size (Mailbox + Dumpster)

For each of the above three reports, you can report on the top n mailboxes by size
either across organisation or per DB, and you can also specify a threshold size to
report on.  For obvious reasons, I wouldn’t advise reporting on all mailboxes without
a non-zero threshold

Plugins for Exchange not up to date or installed.ps1
Report on out of date / missing plugins

Report on Plugins.ps1
Report on which plugins were invoked in current run

vCDAudit for vCloud Director

imageSometimes its hard to retrieve a report or data that you want to see in one place from a pre-built GUI, I often see this as a use case with PowerShell, being able to grab the data that you want to see and export it or report on it in a unified and simple way.  With the release of vCheck 6 and the easy to adapt HTML framework I have a very easy way to do just this, with a few simple changes to the plugins we can easily add any product into the reporting framework.

Currently this has been the case for vSphere and Exchange 2010.

A college of mine Tom Stephens who works for VMware Technical Marketing contacted me last week with a request which fits into the vCheck Framework quite nicely.  He was working with a customer who needed to be able to report on their vCD infrastructure, they had a need to be able to audit their vCD infrastructure and return certain data back in a centralized easy to read fashion.  He sent me a few headings of things the customer would like to see, after just a short period of time I was able to send him a working report with what the customer needed (and a little more I think).

This brings me on to what I call “vCDAudit”, unlike the vSphere health check script this is an audit script which retrieves and presents key vCD Data which is otherwise hard to find in a centralized place.

Example Page

An example of the vCDAudit report can be viewed by clicking here.

Download

To download this version of vCheck you can download the following file which includes the base script and all VCDAudit plugins:

http://www.virtu-al.net/vcheck-pluginsheaders/vcheck/

For more information on the base vCheck script and its framework including a demo of how to use it visit this page.

 

vCheck for Exchange 2010

imageOne of the main areas I redesigned in vCheck 6 was the new plugin concept, In my mind this was a nice HTML output which could be used for more than just vSphere checks, the plugins could potentially be any product which has a PowerShell snap-in or module, and even some which don’t 🙂

Shortly after the release I was contacted by Phil Randal who had done just this, he has taken the vCheck framework and written some Exchange 2010 plugins, this now turns the vCheck report into a Exchange monitoring report too.  Awesome stuff !

Now you can have a daily email with your Exchange 2010 details and issues.

Phil has added 6 initial Exchange 2010 plugins which add some great details, these include:

  • Basic Server Information
  • Database Statistics
  • Database Status
  • Public Folder Statistics
  • Mailboxes larger than x amount of MB
  • Mailboxes with deleted items above x amount of MB

So if you have Exchange 2010 then be sure to download this version of vCheck and give it a go, after all it doesn’t cost you a thing and could save you work in the future. Make sure you thank Phil for his hard work on Twitter, his account is @philrandal

Example Page

An example of the Exchange 2010 report can be viewed by clicking here.

Download

To download this version of vCheck you can download it here which includes the base script and all exchange plugins.

For more information on the base vCheck script and its framework including a demo of how to use it visit this page.

Plugins

All Exchange Plugins are accessible via the Exchange 2010 plugins page located here.