Lab Manager Configuration IP List
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
<#
=============================================================================================
Lab Manager VM NAT Getter
=============================================================================================
Simon Strutt - November 2010
=============================================================================================
Version 1
- Initial creation!
Version 1.1 - Dec 2010
- Added bucketName when displaying list of config's to better handle config's with same name in different workspaces
Version 1.2 - Jan 2011
- Added sorting by VM name
Version 1.3 - Feb 2011
- Configuration selection menu...
-- Now sorted by name
-- Displays configs in yellow if they're not shared
Version 2.0 - Apr 2011
- Changed from single run to modular, continuous operation
- Added RDP port test
=============================================================================================
#>
$UserFile = "User.fil"
$PassFile = "Pass.fil" # Encrypted file to store password in
$LabMgrSvr = "labmgr-svr" # Lab Manager server hostname
$ScriptName = ($MyInvocation.MyCommand.Name).Replace(".ps1", "")
$host.UI.RawUI.WindowTitle = $ScriptName
# =============================================================================================
# Basic helper functions
function PressAnyKeyToExit {
Write-Host "Press any key to exit..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
$labManager.Dispose()
Exit
}
# =============================================================================================
# Lab Manager SOAP connection functions (adapted from POSH - http://poshcode.org/753)
function New-ObjectFromProxy {
param($proxy, $proxyAttributeName, $typeName)
# Locate the assembly for $proxy
$attribute = $proxy | gm | where { $_.Name -eq $proxyAttributeName }
$str = "`$assembly = [" + $attribute.TypeName + "].assembly"
invoke-expression $str
# Instantiate an AuthenticationHeaderValue object.
$type = $assembly.getTypes() | where { $_.Name -eq $typeName }
return $assembly.CreateInstance($type)
}
function Connect-LabManager {
param($server, $credential)
Write-Host "Connecting to $server..."
# Log in to Lab Manager's web service.
$server = "https://" + $server + "/"
$endpoint = $server + "LabManager/SOAP/LabManager.asmx"
try {
$proxy = new-webserviceproxy -uri $endpoint -cred $credential -ErrorAction:Stop
} catch {
Write-Host $_
if ($_.ErrorDetails.Message -match "401: Unauthorized") {
Remove-Item $UserFile
Remove-Item $PassFile
Write-Host "User/pass credential cache files have been deleted"
} else {
Write-Host $_.Exception.Message
Write-Host $_.Exception.GetType().FullName
}
PressAnyKeyToExit
}
# Before continuing we need to add an Authentication Header to $proxy.
$authHeader = New-ObjectFromProxy -proxy $proxy -proxyAttributeName "AuthenticationHeaderValue" -typeName "AuthenticationHeader"
$authHeader.username = $credential.GetNetworkCredential().UserName
$authHeader.password = $credential.GetNetworkCredential().Password
$proxy.AuthenticationHeaderValue = $authHeader
return $proxy
}
function Ignore-SslErrors {
# Create a compilation environment
$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
$Compiler=$Provider.CreateCompiler()
$Params=New-Object System.CodeDom.Compiler.CompilerParameters
$Params.GenerateExecutable=$False
$Params.GenerateInMemory=$True
$Params.IncludeDebugInformation=$False
$Params.ReferencedAssemblies.Add("System.DLL") > $null
$TASource=@'
namespace Local.ToolkitExtensions.Net.CertificatePolicy {
public class TrustAll : System.Net.ICertificatePolicy {
public TrustAll() {
}
public bool CheckValidationResult(System.Net.ServicePoint sp,
System.Security.Cryptography.X509Certificates.X509Certificate cert,
System.Net.WebRequest req, int problem) {
return true;
}
}
}
'@
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
$TAAssembly=$TAResults.CompiledAssembly
## We now create an instance of the TrustAll and attach it to the ServicePointManager
$TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll
}
# ===============================================================================================
# TCP Port test function (adapted from POSH - http://poshcode.org/85)
function Test-Port {
Param([string]$srv,$port=3389,$timeout=3000)
# Does a TCP connection on port 3389 (RDP), port and timeout can be overriden
$ErrorActionPreference = "SilentlyContinue"
# Create TCP Client
$tcpclient = new-Object system.Net.Sockets.TcpClient
# Tell TCP Client to connect to machine on Port
$iar = $tcpclient.BeginConnect($srv,$port,$null,$null)
# Set the wait time
$wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
# Check to see if the connection is done
if(!$wait)
{
# Close the connection and report timeout
$tcpclient.Close()
Write-Host "Connection Timeout" -BackgroundColor DarkRed
Return
}
else
{
# Close the connection and report the error if there is one
$error.Clear()
$tcpclient.EndConnect($iar) | out-Null
if (!$?) {
write-host $error[0] -BackgroundColor DarkRed
$failed = $true
}
$tcpclient.Close()
}
# Return $true if connection Establish else $False
if (!$failed) {
Write-Host "Connection successful" -BackgroundColor DarkGreen
}
}
# Bussiness functions ==========================================================================
function Select-Configuration {
# Get list of configurations, query user which to do, and return selected config ID
$ConfIDs = @()
$confID = -99
# Get list of config's and display deployed only
Write-Host ("Deployed configurations...`n")
$Configs = $labManager.ListConfigurations(1)
$Configs = $Configs | Sort name
foreach ($config in $Configs) {
if ($config.isDeployed) {
if ($FontColour -eq "Gray") {
$FontColour = "White"
} else {
$FontColour = "Gray"
}
if ($config.isPublic) {
Write-host -ForegroundColor $FontColour ("ID " + $config.id + " - " + $config.name + " [" + $config.bucketName + "]")
} else {
Write-Host -ForegroundColor Yellow ("ID " + $config.id + " - " + $config.name + " [" + $config.bucketName + "] - Not Shared !!")
}
$ConfIDs += $config.ID # List of config ID's (with which to validate user input)
}
}
# Get config ID from user
While (!($ConfIDs -contains $ConfID)) { # Don't leave loop until user selected config ID is valid!
$ConfID = Read-Host "`nSelect a configuration ID [0 to quit]"
if (!$ConfID -or ($ConfID -eq 0)) {
# Dump the Lab Manager connection
$labManager.Dispose()
exit
} elseif (!($ConfIDs -contains $ConfID)) {
Write-Host "Invalid, should be one of" ([string]::join(", ", $ConfIDs))
}
}
Return $labManager.GetConfiguration($ConfID)
}
function Get-ConfigVMs {
Param($objConfig)
$VMs = @()
# Get VM's for selected config
$labManager.ListMachines($objConfig.id) | foreach {
$vm = "" | Select VM_Name, VM_IntIP, VM_ExtIP, VM_State
$vm.VM_Name = $_.name
$vm.VM_IntIP = $_.internalIP
$vm.VM_ExtIP = $_.externalIP
$vm.VM_State = $_.status # 1=Off, 2=On, 3=Suspended, 4=Stuck, 128=Invalid
$VMs = $VMs + $vm
}
$VMs = $VMs | Sort VM_Name
#$VMs | Select VM_Name, VM_IntIP, VM_ExtIP | Format-Table
Return $VMs
}
function Send-ConfigIPs {
Param($objConfig, $objConfVMs)
# Email results to user
$EmailTo = $env:username + "@michaelpage.com"
$tmp = Read-Host "Email to [$EmailTo]"
if ($tmp) {$EmailTo = $tmp}
Write-Host "Emailing $EmailTo..." -nonewline
# Create HTML for email
[string]$msgHTML = "<!-- Genenerated by $ScriptName at " + (Get-Date).ToString() + " hrs -->`n"
$msgHTML += "<html xmlns='http://www.w3.org/TR/REC-html40'>`n`n<head>`n<meta http-equiv=Content-Type content='text/html; charset=uk'`n>"
$msgHTML += "<meta name=Generator content='Lab Manager NATs script'>`n<meta name=Author content='Simon Strutt'>`n</head>`n`n"
$msgHTML += "<body style='font-family: arial; font-size: 10;'><table style='font-family: arial; font-size: 11';><tr><td>`nConfiguration:<td><b>" + $objConfig.name + "</b><tr><td>`nWorkspace:<td>" + $objConfig.bucketName
$msgHTML += "<tr><td>`nDescription:<td>" + $objConfig.description + "<tr><td>Info correct at:<td>" + (Get-Date).ToString() + " hrs</table>`n"
$msgHTML += "<br><br>`n`n"
$msgHTML += "<table border=1 style='border-width: 1px; border-spacing: 0; border-color: black; background-color: #faf0e6; font-family: arial; font-size: 11; font-weight: bold'>`n"
$msgHTML += "<tr style='border-width: 2px; background-color: #fcf7f8;'><th>VM Name<th>Internal IP<th>External IP`n"
foreach ($vm in $objConfVMs) {
$msgHTML += "<tr><td>" + $vm.VM_Name + "<td style='font-weight: normal'>" + $vm.VM_IntIP + "<td>" + $vm.VM_ExtIP
}
$msgHTML += "</table>`n`n<br><br>`n<table style='font-family: arial; font-size: 10; color: #888888'>`n<tr><td>Generated by script: <td>$ScriptName"
$msgHTML += "`n</table>`n`n</body></html>"
#Send via email
$smtp = New-Object Net.Mail.SmtpClient -arg "mailrelay.uk.michaelpage.local"
$msg = New-Object Net.Mail.MailMessage
$msg.From = "VI-Mgmt@michaelpage.local"
$msg.To.Add($EmailTo)
$msg.Subject = "Lab Manager configuration: " + $objConfig.name
$msg.IsBodyHTML = $true
$msg.Body = $msgHTML
try {
$smtp.Send($msg)
} catch {
Write-Host "`n" $_
Write-Host "`nCopy text above if you want to retain the info."
PressAnyKeyToExit
}
Write-Host "sent !`n"
}
function Test-Access {
Param($objConfVMs)
# Check RDP access to powered-on VM's
Write-Host -ForegroundColor white "`nTesting RDP (TCP port) access to powered on servers..."
foreach ($vm in $objConfVMs) {
if ($vm.VM_State -eq 2) {
Write-Host ($vm.VM_Name).PadRight(16) ($vm.VM_ExtIP).PadRight(15) -nonewline
Test-Port $vm.VM_ExtIP
}
}
}
# ===============================================================================================
# Faff around with credentials and connect to Lab Manager server
# Check for credential files, create if required
if (!(Test-Path $UserFile) -or !(Test-Path $PassFile)) {
Write-Host "Credential files not found"
$cred = Get-Credential -Credential ($env:userdomain + "\" + $env:username)
$cred.UserName | Set-Content $UserFile -Force
$cred.Password | ConvertFrom-SecureString | Set-Content $PassFile -Force
Write-Host "Credentials saved"
}
# Load password credential from encrypted file
$pass = Get-Content $PassFile | ConvertTo-SecureString
$user = Get-Content $UserFile
$cred = New-Object System.Management.Automation.PsCredential($user, $pass)
# Connect to Lab Mgr server
Ignore-SslErrors
$labManager = Connect-LabManager -server $LabMgrSvr -credential $cred
Write-Host "Sucessfully connected to Lab Manager web service!"
# ==============================================================================================
# Get list of configurations, query user which to do, then get list of VM's and IP's
$option = 1
$Config = Select-Configuration
$host.UI.RawUI.WindowTitle = $ScriptName + " - " + $Config.name
While (1) {
Write-Host -ForegroundColor white ("`n" + $Config.name + " (" + $Config.description + ")`n")
Write-Host "1 - Email IP addresses"
Write-Host "2 - Check RDP access"
Write-Host "3 - Change config"
Write-Host "0 - Exit"
$tmp = Read-Host "`nSelect an option [$option]"
if ($tmp) {$option = $tmp}
if ($option -notmatch "0|1|2|3") {
Write-Host "$option is invalid"
$option = 0
} elseif ($option -eq 0) {
# Dump the Lab Manager connection
$labManager.Dispose()
exit
} elseif ($option -eq 1) {
$ConfVMs = Get-ConfigVMs $Config
Send-ConfigIPs $Config $ConfVMs
} elseif ($option -eq 2) {
$ConfVMs = Get-ConfigVMs $Config
Test-Access $ConfVMs
} elseif ($option -eq 3) {
$Config = Select-Configuration
$host.UI.RawUI.WindowTitle = $ScriptName + " - " + $Config.name
} else {
Write-Host "Unexpected error...!"
}
}
PressAnyKeyToExit