2009-05-13

Powershell: Toggle network connection status on virtual machines in VMware (take 2)

There been some time since I wrote the script and it is now in production.

Some changes have been made, both for functionality and security reasons.

When I added the script as an scheduled task, running as a logged in user, all was fine, but when it run as a non-interactive user, it failed to log in to the Virtual Centre (VC). Therefore we made a local user, added this an administrator for the virtual machine in VC and changed the script to use a specified username and password.

While trying to debug this when running as a scheduled task, we needed some kind of logging, and a simple and well known way to do this is by email. The new version has a possibility to send status emails (configurable).

I want to be sure that only one adapter is enabled at the time, so a small check to prevent enabling both cards is built in (the $prev check). An other thing I do, was to sort the adapters so that the script first disables the active card and then enables the inactive. This way, the virtual host is without connection on both cards for a very short time, but that is more secure than it was, there both cards would be enabled at the same time (usually every second time it toggled)

The code:
# Toggle connection state on NICs on a virtual machine
#
# Usage:
# powershell -noprofile -c -nologo -noninteractive "& 'C:\path to\script\toggle.ps1'"
#
# Copyright (c) 2009 Rune Nordbøe Skillingstad <rune.skillingstad@ntnu.no>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 dated June, 1991.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.

# Configure
# Seems like there is a problem authenticating without user/password
# when running this script uninteractive as a schedule.
$VIServer = "localhost"
$VIUser = "toggle-user"
$VIPassword = "secret"
$ComputerName = "myvirtualhost"

# Set sendmail = 1 for status emails
$sendmail = 0
$mailfrom = "Virtual Center <virtualcentre@mydomain.tld>"
$mailto = "user@mydomain.tld"
$smtpServer = "10.140.80.100"

# Add this to a schedule:
# You might want to change Execution Rights to Unrestricted (as I haven't
# signed this remote, RemoteSigned will not work)

# Magic ignoring warnings
$wpref = $WarningPreference
$WarningPreference ="SilentlyContinue"
Add-PSsnapin VMware.VimAutomation.Core
$server = Connect-VIServer -Server $VIServer -Protocol https -User $VIUser -Password $VIPassword
# Reset warings
$WarningPreference = $wpref

$body = $VIUser + " is toggling connection status on network adapters on " + $ComputerName + "`n"

if($server) {
$adapters = Get-NetworkAdapter $ComputerName

$prev = ""
# Sort so connected is disabled first
foreach($adapter in $adapters | Sort-Object @{Expression={$_.ConnectionState.Connected};Descending=$true;}) {
if(!$adapter -or $adapter.NetworkName -eq "") {
$body += "Ignoring unnamed adapter`n"
continue
}
if($prev -eq $adapter.ConnectionState.Connected) {
$body += "Detecting same status for " + $adapter.NetworkName + " as previous adapter.. ignoring`n"
} else {
if(!$adapter.ConnectionState.Connected) {
$body += "Enabling " + $adapter.NetworkName + "`n"
$ignore = Set-NetworkAdapter $adapter -Connected:$true -Confirm:$false
} else {
$body += "Disabling " + $adapter.NetworkName + "`n"
$ignore = Set-NetworkAdapter $adapter -Connected:$false -Confirm:$false
}
}
$prev = $adapter.ConnectionState.Connected
}
} else {
$body = $body + "Problems connecting to VI server"
}

if($sendmail -eq 1) {
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $mailfrom
$msg.To.Add($mailto)
$msg.Subject = “VMware Network Toggler”
$msg.Body = $body
$smtp.Send($msg)
}

No comments:

Post a Comment