Category Archives: PowerShell

Checking Domain Controllers for Secure LDAP connections with PowerShell

imageI wanted to blog this quick bit of PowerShell as I could not find it anywhere else on the web whilst searching.

I needed to check the connected domain on a machine to see if SSL was configured and enabled for LDAP, the following script checks to see if SSL is enabled on one of the domain controllers in the current domain and then tries to make a connection to see if it works.

This can of course be altered to list and check all domain controllers easy enough:

$dc = [System.DirectoryServices.ActiveDirectory.Domain]::getCurrentDomain().DomainControllers | Select -First 1
$LDAPS = [ADSI]"LDAP://$($dc.name):636"
try {
	$Connection = [adsi]($LDAPS)
} Catch {
}
If ($Connection.Path) {
	Write-Host "Active Directory server correctly configured for SSL, test connection to $($LDAPS.Path) completed."
} Else {
	Write-Host "Active Directory server not configured for SSL, test connection to LDAP://$($dc.name):636 did not work."
}

SSH PowerShell tricks with plink.exe

image

Recently I needed to perform some actions in PowerCLI from the ESXi Shell, as you may know there are currently no cmdlets from VMware to allow you to run shell commands but one option which is popular within the communities is using a 3rd party tool called plink.exe to run the commands via SSH.

Examples of this can be seen here and here.

Download plink.exe via PowerShell

The script I was writing was for someone who I knew didn’t already have plink installed and I wanted them to have little to no effort when using this script so the first trick I wanted to share was the ability to check for plink.exe and download it if it wasn’t in the same directory as the script, this can be seen below:

$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$PlinkLocation = $myDir + "\Plink.exe"
If (-not (Test-Path $PlinkLocation)){
	Write-Host "Plink.exe not found, trying to download..."
	$WC = new-object net.webclient
	$WC.DownloadFile("http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe",$PlinkLocation)
	If (-not (Test-Path $PlinkLocation)){
		Write-Host "Unable to download plink.exe, please download from the following URL and add it to the same folder as this script: http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe"
		Exit
	} Else {
		$PlinkEXE = Get-ChildItem $PlinkLocation
		If ($PlinkEXE.Length -gt 0) {
			Write-Host "Plink.exe downloaded, continuing script"
		} Else {
			Write-Host "Unable to download plink.exe, please download from the following URL and add it to the same folder as this script: http://the.earth.li/~sgtatham/putty/latest/x86/plink.exe"
			Exit
		}
	}	
}

Accept plink.exe host key automatically

Secondly when connecting to a host for the first time you will need to accept the host key and allow plink.exe to connect to the host, the message is similar to the one below:

image

At the moment there is no option in plink.exe to skip the host key checking, however after some searching and messing around I came upon a solution.

It turns out you can actually send a Y to the script you are running by simply piping “echo Y” to plink.exe, this sends a Y accepting the host key when the question is asked from the command line, this can be scripted like the below example:

Echo Y | Plink.exe…..

Hopefully someone will find these useful in the future as I did with this script.

Listing remote Date and Time with PowerShell

Recently I needed to find the remote time of multiple windows servers on the network and compare these, I wrote a quick function that uses WMI to pull this information and return it in a DateTime object format:

image

The Code

function Get-Time {
	<#
		.SYNOPSIS
			Gets the time of a windows server

		.DESCRIPTION
			Uses WMI to get the time of a remote server

		.PARAMETER  ServerName
			The Server to get the date and time from

		.EXAMPLE
			PS C:\> Get-Time localhost

		.EXAMPLE
			PS C:\> Get-Time server01.domain.local -Credential (Get-Credential)

	#>
	[CmdletBinding()]
	param(
		[Parameter(Position=0, Mandatory=$true)]
		[ValidateNotNullOrEmpty()]
		[System.String]
		$ServerName,

		$Credential

	)
	try {
			If ($Credential) {
				$DT = Get-WmiObject -Class Win32_LocalTime -ComputerName $servername -Credential $Credential
			} Else {
				$DT = Get-WmiObject -Class Win32_LocalTime -ComputerName $servername
			}
	}
	catch {
		throw
	}

	$Times = New-Object PSObject -Property @{
		ServerName = $DT.__Server
		DateTime = (Get-Date -Day $DT.Day -Month $DT.Month -Year $DT.Year -Minute $DT.Minute -Hour $DT.Hour -Second $DT.Second)
	}
	$Times

}

#Example of using this function
$Servers = "localhost", "dc01.domain.local"

$Servers | Foreach {
	Get-Time $_
}

Checking for time skew

We can also use this function to easily check for time skew between two machines, the below code is an example where I check my time between a remote host and the local server to see if it is within 30 seconds…

$RemoteServerTime = Get-Time -ServerName "dc01.domain.local"
$LocalServerTime = Get-Time -ServerName "localhost"

$Skew = $LocalServerTime.DateTime - $RemoteServerTime.DateTime

# Check if the time is over 30 seconds
If (($Skew.TotalSeconds -gt 30) -or ($Skew.TotalSeconds -lt -30)){
	Write-Host "Time is not within 30 seconds"
} Else {
	Write-Host "Time checked ok"
}

Using PowerShell v3.0 CIM cmdlets with VMware ESXi Hosts

I noticed that in PowerShell V3.0 some CIM cmdlets were introduced which allowed PowerShell to be able to interact with CIM providers and gather information, when importing the CIM Cmdlets into my session you can see we have a number of new cmdlets to work with:

image

Even though I know PowerCLI 5.1 R1 (Current release on 29th Oct 2012) does not support PowerShell v3.0 I thought I would check out what I could do with these and what information I could receive using the CIM cmdlets.

As a reminder, Carter Shanklin did some work in this area a long time ago and he ended up writing a function to be able to pull CIM information from ESX hosts, this can be found here, he also includes some links to documentation on the CIM providers the VMware hosts can provide: http://blogs.vmware.com/vipowershell/2009/03/monitoring-esx-hardware-with-powershell.html

As you will see from the video below the new cmdlets cut out most of the hard work Carter had to do and allow us to pull CIM information from the ESXi hosts with ease.

Using PowerShell v3.0 CIM Cmdlets with VMware ESXi Hosts from Alan Renouf on Vimeo.

For your reference, here is the code I used during this demo:

import-module CimCmdlets
$ipaddress = "10.20.177.15"
$HostUsername = "root"
$CIOpt = New-CimSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck -Encoding Utf8 -UseSsl
$Session = New-CimSession -Authentication Basic -Credential $HostUsername -ComputerName $Ipaddress -port 443 -SessionOption $CIOpt
Get-CimInstance -CimSession $Session -ClassName CIM_Fan

vMotion and SvMotion Details with PowerCLI

Today I was asked if there was a way to list the vMotions and SvMotions which had occurred in an infrastructure, not only this but they needed to know which hosts the VMs had moved to, the reason for this was licensing.

Firstly they needed to confirm that certain VMs were firstly setup with DRSAffinityrules as disabled, this one was straight forward in PowerCLI:

Get-VM | Select Name, DRSAutomationLevel

image

Secondly they wanted a list of the vMotions and SvMotions which had taken place over the last week and specifically the source and destination hosts, a post on the VMware PowerCLI Blog gives us most of this information and was easy to adjust to include the source and destination hosts…

image

The adjusted script can be found below:

Function Get-MotionDuration {
    $events = Get-VIEvent -Start (Get-Date).AddDays(-7)
    $relocates = $events |
        where {$_.GetType().Name -eq "TaskEvent" -and $_.Info.DescriptionId -eq "VirtualMachine.migrate" -or $_.Info.DescriptionId -eq "VirtualMachine.relocate"}
    foreach($task in $relocates){
        $tEvents = $events | where {$_.ChainId -eq $task.ChainId} |
            Sort-Object -Property CreatedTime
        if($tEvents.Count){
            New-Object PSObject -Property @{
                Name = $tEvents[0].Vm.Name
                Type = &{if($tEvents[0].Host.Name -eq $tEvents[-1].Host.Name){"svMotion"}else{"vMotion"}}
                StartTime = $tEvents[0].CreatedTime
                EndTime = $tEvents[-1].CreatedTime
                Duration = New-TimeSpan -Start $tEvents[0].CreatedTime -End $tEvents[-1].CreatedTime
				SourceHost = $tEvents[0].Host.Name
				DestinationHost = $tEvents[-1].Host.Name
            }
        }
    }
}


Connect-VIServer MyViServer –User Administrator –Password “Pa$$w0rd”

Get-MotionDuration | FT -AutoSize

Quick Host Profile Reports

Today I needed to grab some quick information on my hosts, which hosts had host profiles enabled, if they were compliant and if not what where the issues ?

With the below script I was easily able to grab this information, as can be seen in the screenshot below:

image

The Script

$HPDetails = @()
Foreach ($VMHost in Get-VMHost) {
	$HostProfile = $VMHost | Get-VMHostProfile
	if ($VMHost | Get-VMHostProfile) {
		$HP = $VMHost | Test-VMHostProfileCompliance
		If ($HP.ExtensionData.ComplianceStatus -eq "nonCompliant") {
			Foreach ($issue in ($HP.IncomplianceElementList)) {
				$Details = "" | Select VMHost, Compliance, HostProfile, IncomplianceDescription
				$Details.VMHost = $VMHost.Name
				$Details.Compliance = $HP.ExtensionData.ComplianceStatus
				$Details.HostProfile = $HP.VMHostProfile
				$Details.IncomplianceDescription = $Issue.Description
				$HPDetails += $Details
			}
		} Else {
			$Details = "" | Select VMHost, Compliance, HostProfile, IncomplianceDescription
			$Details.VMHost = $VMHost.Name
			$Details.Compliance = "Compliant"
			$Details.HostProfile = $HostProfile.Name
			$Details.IncomplianceDescription = ""
			$HPDetails += $Details
		}
	} Else {
		$Details = "" | Select VMHost, Compliance, HostProfile, IncomplianceDescription
		$Details.VMHost = $VMHost.Name
		$Details.Compliance = "No profile attached"
		$Details.HostProfile = ""
		$Details.IncomplianceDescription = ""
		$HPDetails += $Details
	}
}
$HPDetails

PowerShell at VMworld 2012 San Francisco

Its that time again! – VMworld, and let me tell you, this year its going to be epic!

I wanted to give you a list of all the PowerShell and PowerCLI sessions listed in this years Session Catalogue for San Francisco, if you don’t have these booked make sure you add them straight away as room is running out fast !

I am personally looking forward to presenting with some superstars this year such as:

  • Luc “The Master” Dekens
  • Jake “Head in the Clouds” Robinson
  • William “API Guru” Lam
  • Eric “PowerTool” Williams
  • Aidan “I am the center of excellence” Dalgliesh

We have some great decks and some awesome demos planned, don’t miss them.  And if you see me come say hi and tell me how you use PowerCLI, you never know I may have a spare sticker, poster and badge to get rid of.

Sessions

INF-VSP1252 – What’s New with vSphere Automation

Click here to add
In this session Technical Marketing automation experts William Lam and Alan Renouf will take you through VMware Automation.You will learn which products are available, which products to use and how Automation fits into the VMware Suite of products. In this session Alan and William will take you through the exciting features available to use when automating VMware products, both beginners and experts will learn how to use new features to make your life easier and more productive. Monday, Aug 27, 2:30 PM – 3:30 PM

Wednesday, Aug 29, 9:30 AM – 10:30 AM

William Lam – Sr. Technical Marketing Engineer, VMware, Inc.

Alan Renouf – Sr. Technical Marketing Architect, VMware, Inc.

INF-BCO2155 – vCloud DR for Oxford University Computing Services – Real World Example

image
Resiliency is a key aspect of any infrastructure—it is even more important in infrastructure-as-a-service solutions. This session will include a tour of a real world vCloud DR solution deployed at Oxford University Computing Services (OUCS). Throughout the session there will be detailed guidance on how both the management and resource clusters were designed, deployed and automated. Furthermore the details of how SRM in conjunction with VMware vSphereTM PowerCLI (PowerCLI) was used to automate the end-to-end recovery of a vCloud Director–based infrastructure. This session will offer a perfect complimentary follow on from the whitepaper regarding the high-level process produced by Duncan Epping and Chris Colotti and the Automation session by Alan Renouf and Aidan Dalgleish. The paper combined with the Automation session will describe the process and the automation principles whereas this session will describe a complete real world implementation. Monday, Aug 27, 3:30 PM – 4:30 PM

Aidan Dalgleish – Consulting Architect, VMware, Inc.

Adrian Parks – Senior Systems Administrator, Oxford University Computing Services

Gary Blake – Senior Consultant, VMware, Inc.

INF-VSP1329 – PowerCLI Best Practices: The Return!

image
Building on the success of our PowerCLI Best Practices sessions from VMworld 2011, we want to show you our next collection of PowerCLI best practices. This session will show and demonstrate PowerCLI in all its aspects managing and automating not just VMware vSphere® but also VMware vCloud Director®, VMware® View™, VMware vShield™ and more Tuesday, Aug 28, 3:00 PM – 4:00 PM

Wednesday, Aug 29, 8:00 AM – 9:00 AM

Alan Renouf – Sr. Technical Marketing Architect, VMware, Inc.

Luc Dekens – Systems Engineer, Eurocontrol Maastricht.

INF-VSP2448 – Automating Bare Metal to the Cloud and Beyond

image
When working in the cloud automation is key, working at the scale of the cloud VMware customers need an easy and reliable method of deployment which gives guaranteed results 100% of the time. Cisco, VMware and Bluelock will show you how to automate the build of your complete vCloud Director Infrastructure from the bare metal up to the cloud and beyond. Learn how PowerShell can be used to create a single easily readable and adaptable script to ensure your system is built quickly and efficiently, watch as a system is built before your very eyes with no magic tricks or rabbits in sight. Tuesday, Aug 28, 12:00 PM – 1:00 PM

Eric Williams – Technical Marketing Engineer, Cisco Systems Inc.

Alan Renouf – Sr. Technical Marketing Architect, VMware, Inc.

Jake Robinson – Solutions Architect, BlueLock

INF-VSP1856 – Become a Rock Star with PowerCLI and vCenter Orchestrator

image
Automation is the future of cloud, and in this session attendees will learn how to identify areas in their environment that are primed for less administrator interaction. The combination of PowerCLI and VMware® vCenter™ Orchestrator puts considerable power in even the greenest users. Attendees will learn how to identify areas for automation and start learning to discern which tool is best suited for the job and when to use them together. Monday, Aug 27, 4:00 PM – 5:00 PM

Josh Atwell – Systems Administrator, Cisco Systems Inc.

INF-VSP2164 – Automation of vCloud Director Disaster Recovery

image
Resiliency is a key aspect of any infrastructure—it is even more important in infrastructure-as-a-service solutions. This session will include guidance, examples and demonstrations of the use of VMware vSphereTM PowerCLI (PowerCLI) to automate the recovery of a vCloud Director–based infrastructure. In particular the session will focus on the automation of the recovery steps for vCloud Director managed vApp workloads, that cannot be recovered with vSphere Site Recovery Manager (SRM). This session will offer a perfect complimentary follow on from the whitepaper regarding the high-level process released by Duncan Epping and Chris Colotti. The paper discussed the process and this session will describe the automation Tuesday, Aug 28, 4:30 PM – 5:30 PM

Alan Renouf – Sr. Technical Marketing Architect, VMware, Inc.

Aidan Dalgleish – Consulting Architect, VMware, Inc.

Group Discussions

GD27 – PowerCLI with Alan Renouf

image
During this group discussion we will talk about what can be automated, discuss the merits of using PowerShell and PowerCLI, show examples and talk about the best methods of achieving integration. We will also discuss tips and tricks you have learned and the best methods for automating the VMware products. Come prepared with examples and questions and remember this is a Group Discussion! Monday, Aug 27, 10:30 AM – 11:30 AM

Thursday, Aug 30, 12:00 PM – 1:00 PM

Alan Renouf – Sr. Technical Marketing Architect, VMware, Inc.

Hands on Labs

HOL-INF-10 – Script and Develop Your Cloud Solution with PowerCLI and the vSphere Web Client SDK

This lab is presented as two 30 minute lightning labs to help you extend your VMware solution. The PowerCLI module covers automating vSphere and vCloud Director. Novice users will learn to use the tool and more advanced users will get familiar with the new functionality available in the latest release of the product. You will walk away with a better understanding of PowerCLI and how it can help you in your day-to-day work. The vSphere Web Client SDK module teaches you several techniques for extending the vSphere Web Client. The goal of this module is to demonstrate the close integration that is possible with the vSphere Web Client SDK, and the ease with which you can integrate your own solutions into the vSphere Web Client. HOL

Attend the self paced Hands on Lab.

Videos

Still cant decide ?  Take a look at some of the session videos where the presenters explain more information…..

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

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

Never miss an appointment again with PowerShell

If your anything like me then you spend most of your time in PowerShell and sometimes forget to check your appointments in Outlook, wouldn’t it be great if you could see your Outlook calendar straight in PowerShell ?

After doing a little searching and altering this post, I created a nice function for PowerShell which I called

Get-Outlookappointments

This function by default will show 7 days worth of items in your PowerShell window, you can pass it some parameters, NumDays will show that number of days appointments….

SNAGHTML4a7b217

Or you can specify a star date and end date using the parameters “Start” and “End”.

This makes a great addition to your PowerShell profile so every time you open PowerShell you are reminded of what you have coming up for the next week and you can call the function over and over in your PowerShell session when needed.

Script

Function Get-OutlookAppointments {
	param ( 
			[Int] $NumDays = 7,
			[DateTime] $Start = [DateTime]::Now ,
	      	[DateTime] $End   = [DateTime]::Now.AddDays($NumDays)
	)

	Process {
		$outlook = New-Object -ComObject Outlook.Application

		$session = $outlook.Session
		$session.Logon()

		$apptItems = $session.GetDefaultFolder(9).Items
		$apptItems.Sort("[Start]")
		$apptItems.IncludeRecurrences = $true
		$apptItems = $apptItems

		$restriction = "[End] >= '{0}' AND [Start] <= '{1}'" -f $Start.ToString("g"), $End.ToString("g")

		foreach($appt in $apptItems.Restrict($restriction))
		{
		    If (([DateTime]$Appt.Start -[DateTime]$appt.End).Days -eq "-1") {
				"All Day Event : {0} Organized by {1}" -f $appt.Subject, $appt.Organizer
			}
			Else {
				"{0:ddd hh:mmtt} - {1:hh:mmtt} : {2} Organized by {3}" -f [DateTime]$appt.Start, [DateTime]$appt.End, $appt.Subject, $appt.Organizer
			}
			
		}

		$outlook = $session = $null;
	}
}

Get-OutlookAppointments