<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>http://vwiki.co.uk/index.php?action=history&amp;feed=atom&amp;title=VI-DB_db-base-data-v2.2.ps1</id>
	<title>VI-DB db-base-data-v2.2.ps1 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://vwiki.co.uk/index.php?action=history&amp;feed=atom&amp;title=VI-DB_db-base-data-v2.2.ps1"/>
	<link rel="alternate" type="text/html" href="http://vwiki.co.uk/index.php?title=VI-DB_db-base-data-v2.2.ps1&amp;action=history"/>
	<updated>2026-04-19T05:26:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>http://vwiki.co.uk/index.php?title=VI-DB_db-base-data-v2.2.ps1&amp;diff=1583&amp;oldid=prev</id>
		<title>Sstrutt: Initial creation</title>
		<link rel="alternate" type="text/html" href="http://vwiki.co.uk/index.php?title=VI-DB_db-base-data-v2.2.ps1&amp;diff=1583&amp;oldid=prev"/>
		<updated>2011-12-19T10:09:27Z</updated>

		<summary type="html">&lt;p&gt;Initial creation&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;# ========================================================================================================================================&lt;br /&gt;
  Database Base Data Getter&lt;br /&gt;
  =========================================================================================================================================&lt;br /&gt;
  Simon Strutt        Jan 2011&lt;br /&gt;
  =========================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
 Version 1 &lt;br /&gt;
  - Initial creation&lt;br /&gt;
&lt;br /&gt;
 Version 1.1 - Mar 2011&lt;br /&gt;
 - Bugfix: Where VC provides no VM FolderID, VM is assigned incorrect VC folder path - now catch as error&lt;br /&gt;
 - Bugfix: VM&amp;#039;s having no IPAddress in vCentre not handled properly, causing errors - now handled silently&lt;br /&gt;
 - Bugfix: Added vmvcid to better handle Lab Manager v4 VM&amp;#039;s with duplicate UUIDs&lt;br /&gt;
 - Bugfix: ESX&amp;#039;s moving clusters causes duplicate ESX entries - old ESX/cluster entry now gets expired&lt;br /&gt;
 - Added snapshot info&lt;br /&gt;
&lt;br /&gt;
 Version 1.2 - Mar 2011&lt;br /&gt;
 - Bugfix: Snapshot sizes not right (known PowerCLI bug in Get-Snapshot that I&amp;#039;d wrongly assumed to be fixed)&lt;br /&gt;
 - Added population of snap.vrange (is snapshot a vRanger snapshot)&lt;br /&gt;
 - Added ESX extended data (inc IP - needs further work), ntp, hba and nic info&lt;br /&gt;
 - Consolidated SQL query strings&lt;br /&gt;
&lt;br /&gt;
Version 1.2.1 - Mar 2011&lt;br /&gt;
 - Bugfix: Standalone ESX&amp;#039;s cause SQL INSERT error (as clid isn&amp;#039;t defined)&lt;br /&gt;
 - Bugfix: Script crash when unable to get ESX NIC/HBA info (happens when ESX not connected)&lt;br /&gt;
 - Bugfix: ESX name wrong when known by VC with IP Address (name now extracted with regex to handle name being IP)&lt;br /&gt;
 &lt;br /&gt;
Version 1.2.2 - Apr 2011&lt;br /&gt;
 - Workaround: DV switch doesn&amp;#039;t have VLAN ID in same place as Port Group causing SQL INSERT fail, caught and set to NULL&lt;br /&gt;
 &lt;br /&gt;
Version 2.0 - Jun 2011&lt;br /&gt;
 - Changed to Async/PS Jobs in order to run against multiple vCentre&amp;#039;s simultaneously&lt;br /&gt;
  - vCentre data mining moved to sub-script&lt;br /&gt;
  - Moved MySQL functions out to library file (shared between main and sub-script)&lt;br /&gt;
  - Enforce run in 32 bit environment (PowerCLI bug workaround, vSphere scripts crash Powershell when launched as background jobs in 64bit)&lt;br /&gt;
 - Added basic support for vApp VM&amp;#039;s (name add to vm_ext, vm folder now supported)&lt;br /&gt;
 - Added logging of errors to database&lt;br /&gt;
 - Added sanity checks (make sure total no of clusters, ESXs, VMs in db matches VC)&lt;br /&gt;
 - Added basic support for distributed switches, and added special network types (mgmt, vmk, ft)&lt;br /&gt;
 - Improved deleted VM handling&lt;br /&gt;
 - Change logging timestamp from xxx secs to hh:mm:ss.msec&lt;br /&gt;
 - Bugfix: Old VMDK&amp;#039;s / vNIC&amp;#039;s don&amp;#039;t get removed from VM&amp;#039;s - additional now deleted NOT WORKING YET, NIC&amp;#039;s get added and deleted on some VM&amp;#039;s  **** TO FIX ****&lt;br /&gt;
 &lt;br /&gt;
Version 2.1 - Sep 2011&lt;br /&gt;
 - Added check for sub-script fail&lt;br /&gt;
 &lt;br /&gt;
Version 2.2 - Nov 2011&lt;br /&gt;
 - Allow db override via command line param&lt;br /&gt;
&lt;br /&gt;
 Future improvements&lt;br /&gt;
 - Add daily capacity report&lt;br /&gt;
 - Bugfix: ESX&amp;#039;s moving clusters should be handled by main INSERT UPDATE, remove/rework ESX duplicate bugfix - maybe catch as major error?&lt;br /&gt;
 - Add HA settings (isolation response, admin control, etc)&lt;br /&gt;
 - Add VM CBT&lt;br /&gt;
 - Add VM custom attributes&lt;br /&gt;
 - Add VM resource limits / shares&lt;br /&gt;
 - Calculate total VM disk usage - not sure really required&lt;br /&gt;
 - Add state change datetime stamp&lt;br /&gt;
 - Catch all Powershell execptions in order to increment counter (add errors to db at later date)&lt;br /&gt;
 - Add who did what (event log extracting)&lt;br /&gt;
&lt;br /&gt;
 ==========================================================================================================================================#&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$start = Get-Date&lt;br /&gt;
$UserFile = &amp;quot;User.fil&amp;quot;&lt;br /&gt;
$PassFile = &amp;quot;Pass.fil&amp;quot;                  # Encrypted file to store password in&lt;br /&gt;
$Logfile = &amp;quot;db-base-data.log&amp;quot;&lt;br /&gt;
$LogStamp = &amp;quot;Time&amp;quot;                      # Log timestamp format (Duration or Time (stamp))&lt;br /&gt;
&lt;br /&gt;
$UpdateScriptRun = 1                    # Log to database&lt;br /&gt;
$Debug = 0                              # Run in debug mode (use test db etc)&lt;br /&gt;
&lt;br /&gt;
# Include library files&lt;br /&gt;
. .\lib\Standard-v4.ps1&lt;br /&gt;
#. .\lib\PowerCLI-helper-v1.1.ps1&lt;br /&gt;
#. .\temp\DS-LUN-v4.ps1&lt;br /&gt;
#. .\lib\getsnapshotsize-1.ps1&lt;br /&gt;
. .\lib\MySQL-v1.ps1&lt;br /&gt;
$SubScriptName = &amp;quot;db-base-data-sub-v2.8.ps1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# DB connection stuff...&lt;br /&gt;
$DBuser = &amp;#039;powercli&amp;#039; &lt;br /&gt;
$DBpass = &amp;#039;powercli&amp;#039; &lt;br /&gt;
$database = &amp;#039;vi&amp;#039;&lt;br /&gt;
$MySQLHost = &amp;#039;192.168.196.128&amp;#039; &lt;br /&gt;
&lt;br /&gt;
$MaxRunningJobs = 4&lt;br /&gt;
$LaunchDelay = 15                      # Pause following a job launch (launched jobs tend to hammer the CPU initially)&lt;br /&gt;
$JobPollThrottle = 1                   # Period of sleep between job status polls&lt;br /&gt;
&lt;br /&gt;
$LabMgrSvr = &amp;quot;ukb-sr-lbmgr-10&amp;quot;&lt;br /&gt;
$UpdateLM = 1&lt;br /&gt;
&lt;br /&gt;
$Major_Error = 0                       # Major error counter&lt;br /&gt;
$ErrorLog = @()                        # Minor error tracker&lt;br /&gt;
&lt;br /&gt;
if ($Debug) {&lt;br /&gt;
    $database = &amp;#039;vi_test&amp;#039;&lt;br /&gt;
    $Logfile = &amp;quot;db-base-data-debug.log&amp;quot;&lt;br /&gt;
    $LogNonQueries = 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Start-Transcript -Path $Logfile&lt;br /&gt;
Log &amp;quot;Started script run at $start&amp;quot; &lt;br /&gt;
&lt;br /&gt;
$ScriptVer = [regex]::matches(($MyInvocation.MyCommand.Name), &amp;quot;(?&amp;lt;=v)[0-9]+(\.[0-9])+(?=.)&amp;quot;)&lt;br /&gt;
$SubScriptVer = [regex]::matches($SubScriptName, &amp;quot;(?&amp;lt;=v)[0-9]+(\.[0-9])+(?=.)&amp;quot;)&lt;br /&gt;
Log (&amp;quot;Script version is $ScriptVer, sub-script ver $SubScriptVer (&amp;quot; + (Get-PowerCLIversion).UserFriendlyVersion + &amp;quot; / Powershell &amp;quot; + (get-host).Version.ToString() + &amp;quot;)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if ($args[0]) {&lt;br /&gt;
    Log (&amp;quot;Database changed from [$database] to [&amp;quot; + $args[0] + &amp;quot;] by command line param.&amp;quot;)&lt;br /&gt;
    $database = $args[0]&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Log (&amp;quot;Database         : $database&amp;quot;)&lt;br /&gt;
Log (&amp;quot;Max running jobs : $MaxRunningJobs&amp;quot;)&lt;br /&gt;
Log (&amp;quot;Launch delay     : $LaunchDelay secs&amp;quot;)&lt;br /&gt;
Log (&amp;quot;Job poll interval: $JobPollThrottle secs&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# =============================================================================================&lt;br /&gt;
# Lab Manager SOAP connection functions (adapted from POSH - http://poshcode.org/753)&lt;br /&gt;
&lt;br /&gt;
function New-ObjectFromProxy {&lt;br /&gt;
	param($proxy, $proxyAttributeName, $typeName)&lt;br /&gt;
&lt;br /&gt;
	# Locate the assembly for $proxy&lt;br /&gt;
	$attribute = $proxy | gm | where { $_.Name -eq $proxyAttributeName }&lt;br /&gt;
	$str = &amp;quot;`$assembly = [&amp;quot; + $attribute.TypeName + &amp;quot;].assembly&amp;quot;&lt;br /&gt;
	invoke-expression $str&lt;br /&gt;
&lt;br /&gt;
	# Instantiate an AuthenticationHeaderValue object.&lt;br /&gt;
	$type = $assembly.getTypes() | where { $_.Name -eq $typeName }&lt;br /&gt;
	return $assembly.CreateInstance($type)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function Connect-LabManager {&lt;br /&gt;
	param($server, $credential)&lt;br /&gt;
    &lt;br /&gt;
    Write-Host &amp;quot;Connecting to $server...&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	# Log in to Lab Manager&amp;#039;s web service.&lt;br /&gt;
	$server = &amp;quot;https://&amp;quot; + $server + &amp;quot;/&amp;quot;&lt;br /&gt;
	$endpoint = $server + &amp;quot;LabManager/SOAP/LabManager.asmx&amp;quot;&lt;br /&gt;
    try {&lt;br /&gt;
	   $proxy = new-webserviceproxy -uri $endpoint -cred $credential -ErrorAction:Stop&lt;br /&gt;
    } catch {&lt;br /&gt;
        Write-Host $_&lt;br /&gt;
        if ($_.ErrorDetails.Message -match &amp;quot;401: Unauthorized&amp;quot;) {&lt;br /&gt;
            Remove-Item $UserFile&lt;br /&gt;
            Remove-Item $PassFile&lt;br /&gt;
            Write-Host &amp;quot;User/pass credential cache files have been deleted&amp;quot;&lt;br /&gt;
        } else {&lt;br /&gt;
             Write-Host $_.Exception.Message&lt;br /&gt;
             Write-Host $_.Exception.GetType().FullName&lt;br /&gt;
        }     &lt;br /&gt;
        PressAnyKeyToExit&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
	# Before continuing we need to add an Authentication Header to $proxy.&lt;br /&gt;
	$authHeader = New-ObjectFromProxy -proxy $proxy -proxyAttributeName &amp;quot;AuthenticationHeaderValue&amp;quot; -typeName &amp;quot;AuthenticationHeader&amp;quot;&lt;br /&gt;
	$authHeader.username = $credential.GetNetworkCredential().UserName&lt;br /&gt;
	$authHeader.password = $credential.GetNetworkCredential().Password&lt;br /&gt;
	$proxy.AuthenticationHeaderValue = $authHeader&lt;br /&gt;
	return $proxy&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function Ignore-SslErrors {&lt;br /&gt;
	# Create a compilation environment&lt;br /&gt;
	$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider&lt;br /&gt;
	$Compiler=$Provider.CreateCompiler()&lt;br /&gt;
	$Params=New-Object System.CodeDom.Compiler.CompilerParameters&lt;br /&gt;
	$Params.GenerateExecutable=$False&lt;br /&gt;
	$Params.GenerateInMemory=$True&lt;br /&gt;
	$Params.IncludeDebugInformation=$False&lt;br /&gt;
	$Params.ReferencedAssemblies.Add(&amp;quot;System.DLL&amp;quot;) &amp;gt; $null&lt;br /&gt;
	$TASource=@&amp;#039;&lt;br /&gt;
	  namespace Local.ToolkitExtensions.Net.CertificatePolicy {&lt;br /&gt;
	    public class TrustAll : System.Net.ICertificatePolicy {&lt;br /&gt;
	      public TrustAll() { &lt;br /&gt;
	      }&lt;br /&gt;
	      public bool CheckValidationResult(System.Net.ServicePoint sp,&lt;br /&gt;
	        System.Security.Cryptography.X509Certificates.X509Certificate cert, &lt;br /&gt;
	        System.Net.WebRequest req, int problem) {&lt;br /&gt;
	        return true;&lt;br /&gt;
	      }&lt;br /&gt;
	    }&lt;br /&gt;
	  }&lt;br /&gt;
&amp;#039;@ &lt;br /&gt;
	$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)&lt;br /&gt;
	$TAAssembly=$TAResults.CompiledAssembly&lt;br /&gt;
&lt;br /&gt;
	## We now create an instance of the TrustAll and attach it to the ServicePointManager&lt;br /&gt;
	$TrustAll=$TAAssembly.CreateInstance(&amp;quot;Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll&amp;quot;)&lt;br /&gt;
	[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# =============================================================================================&lt;br /&gt;
# Other funcs&lt;br /&gt;
&lt;br /&gt;
function Log-Error($text, $vcid=&amp;#039;NULL&amp;#039;, $sev=3) {&lt;br /&gt;
#    if (!$ErrorLog) {&lt;br /&gt;
#        $ErrorLog = @()&lt;br /&gt;
#    }&lt;br /&gt;
    $script:ErrorLog += $text&lt;br /&gt;
    Log (&amp;quot;ERROR: &amp;quot; + $text)&lt;br /&gt;
    Log (&amp;quot;Error count now &amp;quot; + $ErrorLog.Length)&lt;br /&gt;
    if ($UpdateScriptRun) {&lt;br /&gt;
        ExecuteMySQLNonQuery(&amp;quot;INSERT INTO script_run_error (runid, sev, vcid, text) VALUES ($runid, $sev, $vcid, &amp;#039;&amp;quot; + (EscQuote $text) + &amp;quot;&amp;#039;);&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# ========================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Pre Amble ==============================================================================================================================&lt;br /&gt;
&lt;br /&gt;
# Check running in x86 environment&lt;br /&gt;
if ($env:PROCESSOR_ARCHITECTURE -notmatch &amp;#039;x86&amp;#039;) {&lt;br /&gt;
    Log-Error -text &amp;quot;Script in not running in 32-bit mode, Powershell will crash if running jobs against vSphere VC&amp;#039;s, exiting...&amp;quot; -sev 1&lt;br /&gt;
    Stop-Transcript&lt;br /&gt;
    Exit&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Connect to MySQL database&lt;br /&gt;
$SQLconn = ConnectMySQL $DBuser $DBpass $MySQLHost $database&lt;br /&gt;
&lt;br /&gt;
# Create script_run entry&lt;br /&gt;
if ($UpdateScriptRun) {&lt;br /&gt;
    ExecuteMySQLNonQuery(&amp;quot;INSERT INTO script_run (start, version) VALUES (NOW(), &amp;#039;$ScriptVer ($SubScriptVer)&amp;#039;);&amp;quot;)&lt;br /&gt;
    $runid = ExecuteMySQLScalar(&amp;quot;SELECT LAST_INSERT_ID();&amp;quot;)&lt;br /&gt;
    Log(&amp;quot;Script run ID is $runid&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Get list of VC&amp;#039;s (checks the SQL connection is in good working order as well, additional columns for job management)&lt;br /&gt;
$VCs = @()&lt;br /&gt;
$SQLres = ExecuteMySQLQuery(&amp;quot;SELECT vcid, name FROM vc;&amp;quot;)&lt;br /&gt;
foreach ($res in $SQLres) {&lt;br /&gt;
    if (!$res.vcid) {&lt;br /&gt;
        Continue&lt;br /&gt;
    }&lt;br /&gt;
    $vc = &amp;quot;&amp;quot; | Select vcid, name, job, state&lt;br /&gt;
    $vc.vcid = $res.vcid&lt;br /&gt;
    $vc.name = $res.name&lt;br /&gt;
    $vc.state = &amp;quot;To Start&amp;quot;&lt;br /&gt;
    $VCs += $vc&lt;br /&gt;
}    &lt;br /&gt;
&lt;br /&gt;
# Load password credential from encrypted file&lt;br /&gt;
$Pass = Get-Content $PassFile | ConvertTo-SecureString&lt;br /&gt;
$User = Get-Content $UserFile&lt;br /&gt;
$cred = New-Object System.Management.Automation.PsCredential($User, $Pass)&lt;br /&gt;
&lt;br /&gt;
# Connect to VC&amp;#039;s in order to confirm user/pass is correct&lt;br /&gt;
foreach ($vc in $VCs) {&lt;br /&gt;
    # Connect to vCentre&lt;br /&gt;
    try {&lt;br /&gt;
        Log(&amp;quot;Testing credentials - connecting to &amp;quot; + $vc.name)&lt;br /&gt;
        $VCconn = Connect-VIServer -Server $vc.name -Credential $cred -WarningAction SilentlyContinue -ErrorAction &amp;quot;Stop&amp;quot;&lt;br /&gt;
    } catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidLogin] {&lt;br /&gt;
        Log(&amp;quot;Unable to connect to vCentre, invalid logon error !!&amp;quot;)&lt;br /&gt;
        Log(&amp;quot;Abandoning further script processing in order to prevent potential account lockout.&amp;quot;)&lt;br /&gt;
        Log-Error -text &amp;quot;vCentre invalid login error, script halt to prevent potential account lockout.&amp;quot; -vcid $vc.vcid -sev 1&lt;br /&gt;
        ExecuteMySQLNonQuery(&amp;quot;UPDATE script_run SET end=NOW(), error=99 WHERE runid=$runid;&amp;quot;)&lt;br /&gt;
        DisconnectMySQL&lt;br /&gt;
        Stop-Transcript&lt;br /&gt;
        Exit&lt;br /&gt;
    } catch {&lt;br /&gt;
        Log-Error -text (EscQuote (&amp;quot;Unable to connect to vCentre - &amp;quot; + $_)) -vcid $vc.vcid -sev 2&lt;br /&gt;
        $Major_Error += 1&lt;br /&gt;
        Continue&lt;br /&gt;
    }&lt;br /&gt;
    Log(&amp;quot;Credentials validated successfully&amp;quot;)&lt;br /&gt;
    Break&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Disconnect any existing VI Server sessions (otherwise you can end up with duplicate data)&lt;br /&gt;
if ($DefaultVIServers.Count) {&lt;br /&gt;
    Log(&amp;quot;Disconnect all existing vCentre server connections...&amp;quot;)&lt;br /&gt;
    Disconnect-VIServer -Server * -Force -Confirm:$false&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Business Loop ============================================================================================================================&lt;br /&gt;
&lt;br /&gt;
# Get current directory to pass to jobs&lt;br /&gt;
$pwd = Get-Location&lt;br /&gt;
&lt;br /&gt;
$JobsRunning = 0&lt;br /&gt;
&lt;br /&gt;
While (1) {&lt;br /&gt;
    # Launch control&lt;br /&gt;
    if ($VCs |?{$_.state -eq &amp;quot;To Start&amp;quot;}) {             # Anymore jobs to start?&lt;br /&gt;
        if ($JobsRunning -lt $MaxRunningJobs) {         # Capacity to start a another job?&lt;br /&gt;
            #Log(&amp;quot;Jobs still to start, Jobs running: $JobsRunning, Max Running Jobs: $MaxRunningJobs&amp;quot;)&lt;br /&gt;
            foreach ($vc in $VCs) {&lt;br /&gt;
                # Find next job to start&lt;br /&gt;
                if ($vc.state -eq &amp;quot;To Start&amp;quot;) {&lt;br /&gt;
                    $vars = ($vc.name, $vc.vcid, $cred, $DBuser, $DBpass, $database, $MySQLHost, $runid, $pwd)&lt;br /&gt;
                    Log (&amp;quot;Starting job for &amp;quot; + $vc.name)&lt;br /&gt;
                    $vc.job = Start-Job -FilePath $SubScriptName -InitializationScript $JobScript -Name $vc.name -InputObject $vars&lt;br /&gt;
                    $vc.state = $vc.job.JobStateInfo.state&lt;br /&gt;
                    $JobsRunning += 1&lt;br /&gt;
                    Start-Sleep $LaunchDelay&lt;br /&gt;
                    Break&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    # Landing handling&lt;br /&gt;
    foreach ($vc in $VCs) {&lt;br /&gt;
        if (($vc.state -ne &amp;quot;To Start&amp;quot;) -and ($vc.state -ne $vc.job.JobStateInfo.state)) {&lt;br /&gt;
            Log ($vc.name + &amp;quot; job state now &amp;quot; + $vc.job.JobStateInfo.state)&lt;br /&gt;
            $vc.state = $vc.job.JobStateInfo.state&lt;br /&gt;
            $JobsRunning -= 1&lt;br /&gt;
            if ($vc.state.ToString() -eq &amp;quot;Completed&amp;quot;) {&lt;br /&gt;
                Log ($vc.name + &amp;quot; writing log to db-base-data-&amp;quot; + $vc.name + &amp;quot;.log&amp;quot;)&lt;br /&gt;
                # Nasty logging handling (Receive-Job StdOut to console only, can&amp;#039;t redirect to file, can only catch StdErr to file)&lt;br /&gt;
                Stop-Transcript&lt;br /&gt;
                Start-Transcript -Path (&amp;quot;db-base-data-&amp;quot; + $vc.name + &amp;quot;.log&amp;quot;)&lt;br /&gt;
                Receive-Job -Id $vc.job.Id&lt;br /&gt;
                Stop-Transcript&lt;br /&gt;
                Start-Transcript -Path $Logfile -Append&lt;br /&gt;
            } else {&lt;br /&gt;
                Log-Error -text ($vc.name + &amp;quot; data collection &amp;quot; + $vc.state) -vcid $vc.vcid -sev 2&lt;br /&gt;
                Log ($vc.name + &amp;quot; writing log to db-base-data-&amp;quot; + $vc.name + &amp;quot;.log&amp;quot;)&lt;br /&gt;
                Stop-Transcript&lt;br /&gt;
                Start-Transcript -Path (&amp;quot;db-base-data-&amp;quot; + $vc.name + &amp;quot;.log&amp;quot;)&lt;br /&gt;
                Receive-Job -Id $vc.job.Id&lt;br /&gt;
                Stop-Transcript&lt;br /&gt;
                Start-Transcript -Path $Logfile -Append&lt;br /&gt;
            }&lt;br /&gt;
            $VCs | Select -Property Name, State&lt;br /&gt;
        }&lt;br /&gt;
        #Log ($vc.name + &amp;quot; job state is &amp;quot; + $vc.job.JobStateInfo.state)&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    #Log (&amp;quot;Jobs running: $JobsRunning, Max Running Jobs: $MaxRunningJobs&amp;quot;)&lt;br /&gt;
   &lt;br /&gt;
    # No jobs running / none still to start?&lt;br /&gt;
    if (($JobsRunning -eq 0) -and !($VCs |?{$_.state -eq &amp;quot;To Start&amp;quot;})) {&lt;br /&gt;
        Log (&amp;quot;All jobs completed&amp;quot;)    &lt;br /&gt;
        Break&lt;br /&gt;
    }&lt;br /&gt;
    Start-Sleep $JobPollThrottle&lt;br /&gt;
}&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
#Lab Manager ---------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
if ($UpdateLM) {&lt;br /&gt;
    # Connect to Lab Manager server&lt;br /&gt;
    try {&lt;br /&gt;
        Log(&amp;quot;Connecting to &amp;quot; + $LabMgrSvr)&lt;br /&gt;
        Ignore-SslErrors&lt;br /&gt;
        $labManager = Connect-LabManager -server $LabMgrSvr -credential $cred&lt;br /&gt;
    } catch {&lt;br /&gt;
        Log-Error -text (&amp;quot;Unable to connect to Lab Manager - &amp;quot; + $_) -vcid 0 -sev 2&lt;br /&gt;
        $Major_Error += 1&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ($labManager) {&lt;br /&gt;
        # Get List of VM&amp;#039;s&lt;br /&gt;
        Log(&amp;quot;Getting Lab Manager VM info...&amp;quot;)&lt;br /&gt;
        $lmVMs = @()&lt;br /&gt;
        $lmConfigs = $labManager.ListConfigurations(1) &lt;br /&gt;
        foreach ($config in $lmConfigs) {&lt;br /&gt;
            if ($config.isDeployed) { &lt;br /&gt;
                $confVMs = $labManager.ListMachines($config.id)&lt;br /&gt;
                foreach ($vm in $confVMs) {&lt;br /&gt;
                    if ($vm.isDeployed) {&lt;br /&gt;
                        $VMrow = &amp;quot;&amp;quot; | Select Path, ConfigOrg, ConfigName, VMname, VMextIP&lt;br /&gt;
                        $VMrow.Path = $config.bucketName + &amp;quot;\\\\&amp;quot; + $config.name&lt;br /&gt;
                        $VMrow.ConfigOrg = $config.bucketName&lt;br /&gt;
                        $VMrow.ConfigName = $config.name&lt;br /&gt;
                        $VMrow.VMname = $vm.name&lt;br /&gt;
                        $VMrow.VMextIP = $vm.externalIP&lt;br /&gt;
                        $lmVMs = $lmVMs + $VMrow&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        foreach ($vm in $lmVMs) {&lt;br /&gt;
            # Get VM&amp;#039;s db ID&lt;br /&gt;
            $query = &amp;quot;SELECT vmid FROM vm JOIN vm_ext USING (vmid) WHERE vc_path LIKE(&amp;#039;%&amp;quot; + $vm.ConfigOrg + &amp;quot;\\\\&amp;quot; + $vm.ConfigName + &amp;quot;%&amp;#039;) AND name LIKE(&amp;#039;%&amp;quot; + $vm.VMname + &amp;quot;&amp;#039;);&amp;quot;&lt;br /&gt;
            $vmid = ExecuteMySQLScalar($query)&lt;br /&gt;
            if (!$vmid) {&lt;br /&gt;
                #Log ($query)&lt;br /&gt;
                Log-Error -text (&amp;quot;Unable to find db id for Labs VM: &amp;quot; + $vm.ConfigName + &amp;quot;\&amp;quot; + $vm.VMname) -vcid 0&lt;br /&gt;
                Continue&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            $query = &amp;quot;INSERT INTO vm_nic (vmid, num, type) VALUES ($vmid, 0, &amp;#039;Labs NAT&amp;#039;) &amp;quot;&lt;br /&gt;
            $query += &amp;quot;ON DUPLICATE KEY UPDATE vnicid=LAST_INSERT_ID(vnicid);&amp;quot;&lt;br /&gt;
            ExecuteMySQLNonQuery($query)&lt;br /&gt;
                &lt;br /&gt;
            # Get vnicid from last query&lt;br /&gt;
            $vnicid = ExecuteMySQLScalar(&amp;quot;SELECT LAST_INSERT_ID();&amp;quot;)&lt;br /&gt;
                &lt;br /&gt;
            # Find related IP(s)&lt;br /&gt;
            $query = &amp;quot;INSERT INTO vm2ip (vmid, vnicid, ip) VALUES ($vmid, $vnicid, INET_ATON(&amp;#039;&amp;quot; + $vm.VMextIP + &amp;quot;&amp;#039;)) &amp;quot;&lt;br /&gt;
            $query += &amp;quot;ON DUPLICATE KEY UPDATE ip=INET_ATON(&amp;#039;&amp;quot; +  $vm.VMextIP + &amp;quot;&amp;#039;);&amp;quot;&lt;br /&gt;
            ExecuteMySQLNonQuery($query)&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Post Amble =================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
foreach ($vc in $VCs) {&lt;br /&gt;
    if (ExecuteMySQLScalar(&amp;quot;SELECT COUNT(*) AS fail FROM script_run_error WHERE runid=$runid AND sev=0;&amp;quot;)) {&lt;br /&gt;
        Log(&amp;quot;Script run for &amp;quot; + $vc.name + &amp;quot; exited cleanly&amp;quot;)&lt;br /&gt;
    } else {&lt;br /&gt;
        Log-Error -text (&amp;quot;Script run on &amp;quot; + $vc.name + &amp;quot; did not exit cleanly&amp;quot;) -vcid $vc.vcid -sev 1&lt;br /&gt;
    }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
# Summarise error reporting&lt;br /&gt;
$RunErrors = ExecuteMySQLQuery(&amp;quot;SELECT SUM(IF(sev=1 or sev=2,1,0)) AS major, SUM(IF(sev=3,1,0)) AS minor FROM script_run_error WHERE runid=$runid;&amp;quot;)&lt;br /&gt;
Log(&amp;quot;Summary error report: &amp;quot; + $RunErrors[1].major + &amp;quot; major errors, &amp;quot; + $RunErrors[1].minor + &amp;quot; minor errors&amp;quot;)&lt;br /&gt;
ExecuteMySQLNonQuery(&amp;quot;UPDATE script_run SET end=NOW(), error=&amp;quot; + $RunErrors[1].major + &amp;quot;, warn=&amp;quot; + $RunErrors[1].minor + &amp;quot; WHERE runid=$runid;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
DisconnectMySQL&lt;br /&gt;
Stop-Transcript&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:PowerCLI Script]]&lt;/div&gt;</summary>
		<author><name>Sstrutt</name></author>
	</entry>
</feed>