线程不会创建多个VM(会话问题)

时间:2016-02-29 23:06:12

标签: multithreading powershell session vmware vcenter

数据来自* .CSV文件。脚本应该在我的测试用例2中创建同一个vcenter但在不同线程中的VM。需要指导如何解决这个问题。

cls

Add-PSSnapin VMware.VimAutomation.Core | Out-Null 

#import VM settings
$VMs = Import-CSV '...\Data.csv' -UseCulture

#array for connections
$server = @()
#threads
$Throttle = 2

# Create session state
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()

# Create runspace pool consisting of runspaces
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $Throttle, $sessionState, $Host)
$RunspacePool.Open()

#array for jobs
$Jobs = @()
$global:DefaultVIServer



$ScriptBlocky = {
    Param ($VM, $ses) 

    Add-PSSnapin VMware.VimAutomation.Core | Out-Null 
    Write-Host $VM.vm_name "Father session:    "  $ses.SessionSecret

    $sessionf = Connect-VIServer $VM.vs_xstream__vc_host  -Session $ses.SessionSecret -wa 0
    Write-Host $VM.vm_name "Child session:    "   $sessionf.SessionId


    $domain_name = $VM.FQDN.split('.')
    Write-Host  $domain_name
    #Random for testing purposes
    $OSspec = ("BasicLinuxSpec_rand{0}" -f (Get-Random))
    # Create new OS Customization Specification template for further usage
    New-OSCustomizationSpec –Name $OSspec –Domain ("{0}.{1}" -f $domain_name[1],$domain_name[2]) –DnsServer $VM.DNS,$VM.DNS2 –NamingScheme VM –OSType Linux 

    Get-OSCustomizationSpec $OSspec -Server $VM.vs_xstream__vc_host | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $VM.Ipaddress -SubnetMask $VM.NetMask -DefaultGateway $VM.Gateway 

    Write-Host $VM.vm_name "OSspec:    "$OSspec

    Write-Host $VM.vm_name "Cluster:    "$VM.Cluster
    Write-Host $VM.vm_name "Host:    "$VM.vs_xstream__vc_host
    # Selecting random Cluster for VMs deployment
    $ClusterHost = Get-Cluster $VM.Cluster -server $VM.vs_xstream__vc_host | Get-VMHost  | Get-Random
    Write-Host "================="
    Write-Host $VM.vm_name "ClusterHost    "  $ClusterHost
    Write-Host "================="

    New-Vm -VMhost $ClusterHost -Name $VM.vm_name -Server $VM.vs_xstream__vc_host -Datastore $VM.Datastore -Template $VM.Template -Description $VM.Description -DiskStorageFormat "Thin" -OScustomizationSpec $OSspec

    Remove-OSCustomizationSpec $OSspec -Server $VM.vs_xstream__vc_host -confirm:$false


}

Write-Host ("Starting script: {0}" -f (Get-Date))
$startTime = Get-Date

$count = 0
ForEach($VM in $VMs)
{
    $count  = $count + 1

    Write-Host  $VM.vs_xstream__vc_host

    Write-Host "Current connections:"
    $Global:DefaultVIServers.count

    $ses = Connect-VIServer $VM.vs_xstream__vc_host  -User $VM.vs_xstream__vc_admin -Password $VM.vs_xstream__vc_password -wa 0

    $Job = [powershell]::create()
    $Job.RunspacePool = $RunspacePool
    $Job.AddScript($ScriptBlocky).AddParameter("VM", $VM).AddParameter("ses", $ses)

    Write-Host "Adding job to jobs list"
    $Jobs += New-Object PSObject -Property @{
        RunNum = $count
        Job = $Job
        Result = $Job.BeginInvoke()
        }

     #Disconnect-VIServer $VM.vs_xstream__vc_host -Confirm:$false -Force
}


Write-Host "Waiting.." -NoNewline
Do {
   Write-Host "." -NoNewline
   Start-Sleep -Seconds 1
} While ( $Jobs.Result.IsCompleted -contains $false)

$endTime = Get-Date
$totalSeconds = "{0:N4}" -f ($endTime-$startTime).TotalSeconds
Write-Host "All jobs finished in $totalSeconds seconds"

结果:

Name                           Port  User                          
----                           ----  ----                          
10.xxx.xx.10                   443   VSPHERE.LOCAL\do1xstream      
Starting script: 2/29/2016 2:48:20 PM
10.xxx.xx.10
Current connections:
1

Adding job to jobs list
10.xxx.xx.10
Current connections:
1
The specified mount name 'vmstores' is already in use.
The specified mount name 'vis' is already in use.
virtual38 Father session:     f8bafd42e6b7c85aa313e2896eba11c0f9f876cf

Adding job to jobs list
virtual38 Child session:     f8bafd42e6b7c85aa313e2896eba11c0f9f876cf
virtual38 domain com
Waiting...virtual39 Father session:       f8bafd42e6b7c85aa313e2896eba11c0f9f876cf
virtual39 Child session:     
virtual39 domain com
virtual39 OSspec:     BasicLinuxSpec_rand618798101
virtual39 Cluster:     do1mgmt
virtual39 Host:     10.xxx.xx.10
=================
virtual39 ClusterHost     
=================
virtual38 OSspec:     BasicLinuxSpec_rand581276505
virtual38 Cluster:     do1mgmt
virtual38 Host:     10.xxx.xx.10
.=================
virtual38 ClusterHost     10.xxx.xx.2
=================
..............

结果显示,因为virtual38排在第一位,它具有会话信息并可以执行操作。

也许我错了,我认为会话isssue阻止创建第二个VM(virtual39)

更新/通知:我意识到当线程$ Throttle = 1时,两个VM都被创建,当我设置$ Throttle = 2或更多时,则只创建其中一个(第一个)。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

信不信由你,但我发现了什么问题。脚本正在运行,但是当连接到新会话或现有会话(甚至是不同的vCenter,何时需要在多个vCenter环境中创建VM)时,会修改DefaultVIServers变量并删除会话。

解决方案:  *在所有其他操作之前创建与vCenter的所有连接,以便连接稳定。例如:

# Iterate and connect to all vCenters so connections to them will be stable and read only
ForEach($VM in $VMs)
{
   If ($VM.Use -eq 1) 
   {   
      If($server.Contains($VM.vs_xstream__vc_host) -eq $FALSE)
      {   
        $server += $VM.vs_xstream__vc_host
        $AllSessions += Connect-VIServer $VM.vs_xstream__vc_host -User $VM.vs_xstream__vc_admin -Password $VM.vs_xstream__vc_password -NotDefault
        Write-Host "Connected to:  " $VM.vs_xstream__vc_host
      }
   }
}

完成所有工作后,我只需断开与所有会话的连接

# Disconnect all created sessions
ForEach($item in $server)
{
   Write-Host ("Disconnecting from {0}...." -f ($item))
   Disconnect-VIServer $item  -Confirm:$false
}

现在脚本运行良好,可以在不同或相同的vCenter中创建VM。如果有人会遇到任何问题,请告诉我。