Automation

 View Only
Expand all | Collapse all

How to pass parameters in a variable in a loop FOREACH ?

Spartacus75

Spartacus75Mar 21, 2013 09:36 AM

Spartacus75

Spartacus75Mar 26, 2013 10:06 AM

Spartacus75

Spartacus75Apr 01, 2013 11:00 PM

  • 1.  How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 21, 2013 09:30 AM

    Hello everyone

    I opened a new topic because I need your lights.

    I have a script that allows me to automatically create multiple virtual machines.

    I would now like to put parameters into a variable so that I can from select from my command prompt the number of machines at create and the name of machines.

    I tried the variable args [] but it does not work in a foreach loop.

    Here my script:

    Connect-VIServer -Server 10.*.*.* -Protocol https -User admin-Password admin

    2..$args[0] | Foreach {
    New-vm -vmhost Server1.rio.paris.eu -Name "$args[1]$_" -Template TestScript -Datastore Database_1

    }

    2..$args[0] | Foreach {
    Start-VM -VM "$args[1]$_"
    }

    In this script, the variable "$args[0]" to indicate the number of machine created and  the variable "args[1]" to indicate the name of the machines.

    But it does not work.

    I hope to have been clear on my problem.

    Thanks so much for your help.



  • 2.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 21, 2013 09:36 AM

    :smileyhappy:



  • 3.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 21, 2013 09:54 AM

    Why don't you used named parameters, that is a lot easier and clearer

    param($Count,$Name)
    
    Connect-VIServer -Server 10.*.*.* -Protocol https -User admin-Password admin
    2..$Count | Foreach {
      New-vm -vmhost Server1.rio.paris.eu -Name "$Name$_" -Template TestScript -Datastore Database_1
    } 2..$Count | Foreach {   Start-VM -VM "$Name$_"
    }

    You can now call the script as follows

    C:\  PS> ./script.ps1 -Count 5 -Name testvm


  • 4.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 25, 2013 10:58 AM

    Hello,

    Thanks you so much Luc, very nice !

    I have another question.

    I have a script that is able to create machines, give a name and the IP parameters. I tested the loops separately, it works well.

    However, when I gather the loops in the same script and that I execute, I got error messages.
    I think that all the loops of script are executed simultaneously.
    As a result, the configuration of name and the IP does not work.

    Are there a powershell command that can verify that the first loop is complete before starting the second loop?

    here is my script:

    param($Count,$Name,$Type,$Ip)

    Connect-VIServer -Server 10.*.*.* -Protocol https -User admin-Password Admin
    2..$Count | Foreach {
      New-vm -vmhost Server.rio.england.eu -Name "$Name$_" -Template $Type -Datastore BASE_OF_30
      }
     
    2..$Count | Foreach {
      Start-VM -VM "$Name$_"}
     
    2..$Count | Foreach {
    $VM = Get-VM "$Name$_"
    $ESXHost = $VM | Get-VMHost
    $secpasswd = ConvertTo-SecureString "admin" -AsPlainText -Force
    $GuestCred = New-Object System.Management.Automation.PSCredential ("admin", $secpasswd)
    Function Set-WinVMIP ($VM, $HC, $GC){
    $Ip++
    $ps1= "c:\ip.bat $Ip $VM"
    Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $ps1

    }
    }


    Set-WinVMIP $VM $HostCred $GuestCred

    Thank so much for your help.



  • 5.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 25, 2013 12:42 PM

    The 2 loops are executed in sequence, the 2nd will not start before the first loop is finished.

    But what probably happens is that VMs that are created by the New-VM cmdlets in the 1st loop, are not yet fully available when you reach the 2 loop.

    You could loop through those VMs, before starting the 2nd, and check if they are available



  • 6.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 25, 2013 03:32 PM

    Thank you for your help Lucd,

    How to loop through those VMs ? How to check if they are available before to running the second script ?

    Thank



  • 7.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 26, 2013 10:06 AM

    Anyone have an idea?:smileyhappy:

    Thank.



  • 8.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 27, 2013 11:18 AM

    Hello everybody,

    I have a big problem.

    I designed my script so that it automatically increments the last decimal of my Ip (10,170,219.%1).

    So my script will be able to create machines, start the machines, give a name and an IP address.

    My problem is that my script can do everything except incrementing the IP decimal. Yet I put in my loop the argument "$ Ip + +" to increment.

    Here is my scrip:

    param($Count,$Name,$Type,$Ip)

    Connect-VIServer -Server 10..*.*.* -Protocol https -User admin -Password admin

    2..$Count | Foreach {
      New-vm -vmhost 007.london.england.eu -Name "$Name$_" -Template $Type -Datastore Data_base007  }
     
    read-host "Press Enter"

    2..$Count | Foreach {
      Start-VM -VM "$Name$_"}
     
    read-host "Press Enter"

    2..$Count | Foreach {
    $VM = Get-VM "$Name$_"
    write-host "$Name$_"
    $ESXHost = $VM | Get-VMHost
    $secpasswd = ConvertTo-SecureString "formation" -AsPlainText -Force
    $GuestCred = New-Object System.Management.Automation.PSCredential ("formation", $secpasswd)
    Function Set-WinVMIP ($VM, $HC, $GC){
    $Ip++
    $ps1= "c:\ip.bat $Ip $VM"
    Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $ps1

    }
    Set-WinVMIP $VM $HostCred $GuestCred
    }

    would you have a solution to this problem?

    Thank you.



  • 9.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 27, 2013 06:41 PM

    The problem is that your $Ip variable contains a string and not an integer.

    The ++ operator only works on numbers.

    You'll have to split out the last number, increment that and join the parts of the IP address back together.

    For example

    $ip = "192.168.1.1"
    $fixed = $ip.Split('.')[0..2]
    $last = [int]($ip.Split('.')[3])
    
    $last..($last + 9) | %{
        [string]::Join('.',$fixed) + "." + $_
    }

    This will create a series of IP addresses starting with 192.168.1.1 and ending with 192.168.1.10



  • 10.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 28, 2013 08:17 PM

    Hello:smileyhappy:,


    Thank you very much for your help, happily that the VMWARE community  is here:smileywink: !
    In fact, when I run my script via the command prompt, I give in parameter a number has  the last decimal of ip address . : Script.sp1 -Name Machine1 Template-type-Ip 24.
    The incrementing will be based on this number for the other machines.
    Thus, the first machine will created with the IP address: 10.170.229.24
    For each machine created the last decimal should increment of 1.
    Example:
    Machine 2 -> 10.170.229.25
    Machine 3 -> 10.170.229.26
    Machine 4 -> 10.170.229.27
    etc....
    To accomplish this objective, it is mandatory that I go in once I enter a number as parameter.
    in fact, my script works, but my script configures all machines with the same IP address. which causes Ip address conflict.
    The problem with your script is that I can not give a number in parameter.
    As you understand the problem?
    Thank you very much.:smileyhappy:


  • 11.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 28, 2013 08:36 PM

    You're having a problem with the scope of the $Ip variable.

    You increment the number ($Ip) inside the function, that change will be gone when you exit the function.

    One solution is to make that a global variable ($global:Ip),

    or change the script like this

    param($Count,$Name,$Type,$Ip)
    
    Connect-VIServer -Server 10..*.*.* -Protocol https -User admin -Password admin
    2..$Count | Foreach {
      New-vm -vmhost 007.london.england.eu -Name "$Name$_" -Template $Type -Datastore Data_base007
    }
    read-host "Press Enter" 2..$Count | Foreach {   Start-VM -VM "$Name$_"
    } read-host "Press Enter" 2..$Count | Foreach {   $VM = Get-VM "$Name$_"  write-host "$Name$_"
      $ESXHost = $VM | Get-VMHost
      $secpasswd = ConvertTo-SecureString "formation" -AsPlainText -Force
      $GuestCred = New-Object System.Management.Automation.PSCredential ("formation", $secpasswd)   Function Set-WinVMIP ($VM, $HC, $GC, $IP){     $ps1 = "c:\ip.bat $IP $VM"
       
    Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $ps1   }   Set-WinVMIP $VM $HostCred $GuestCred,$Ip
     
    $Ip++
    }


  • 12.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Mar 29, 2013 12:25 PM

    Thank you very much, you're the best!:smileyhappy:

    I have a last question.

    How can i proceed for that my loop of configuration is executed after the startup of machines ?

    Indeed, the loop that allows to configure the name and ip address start just after the loop of startup machines. However, at the moment of his execution, the machines have not yet started.

    Again thank you for your help, this is really great!:smileyhappy:



  • 13.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 01, 2013 08:01 PM

    Hello,

    I tried different methods, but my loop of configuration of name and ip address is always executed before the machines are started.
    You have an idea to fix the problem?


  • 14.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 01, 2013 11:00 PM

    :smileyhappy:



  • 15.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 02, 2013 11:24 AM

    Hello everyone,

    is there a command to check if the machine is started or not ?

    I can not solve this problem, my loop of configuration of name and ip address debuted before the machines are started, and therefore, it does not work.

    I would like my script execute the first two loops, then verifies that the machines are started before execute the last loop, is it possible? I find no solution on this issue.

    Thank you for your help:smileyhappy:.

    Here is my script:

    param($Count,$Name,$Type,$Ip)
    
    Connect-VIServer -Server 10..*.*.* -Protocol https -User admin -Password admin
    2..$Count | Foreach {
      New-vm -vmhost 007.london.england.eu -Name "$Name$_" -Template $Type -Datastore Data_base007
    } 2..$Count | Foreach {   Start-VM -VM "$Name$_"
    } read-host "Press Enter"

    2..$Count | Foreach {   $VM = Get-VM "$Name$_"  write-host "$Name$_"
      $ESXHost = $VM | Get-VMHost
      $secpasswd = ConvertTo-SecureString "formation" -AsPlainText -Force
      $GuestCred = New-Object System.Management.Automation.PSCredential ("formation", $secpasswd)   Function Set-WinVMIP ($VM, $HC, $GC, $IP){     $ps1 = "c:\ip.bat $IP $VM"
        Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $ps1   }   Set-WinVMIP $VM $HostCred $GuestCred,$Ip
      $Ip++
    }


  • 16.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 02, 2013 11:43 AM

    There are in fact 2 things you have to look at:

    1) the VM is started. That one is quite easy. Just check the powerstate of the VM

    $vm = Get-VM MyVM
    while ($vm.PowerState -ne "PoweredOn"){   sleep 5
     
    $vm = Get-VM $vm
    }

    2) The OS running inside the VM has to be ready as well.

    You want to change the NIC settings, so you have to make sure that the OS is completely started.

    This can be done in several ways: a ping, a WMI call....

    The simplest method, nd least intelligent, is to just wait a number of seconds (you should determine how long by looking how long it takes the OS to start and become available)



  • 17.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 02, 2013 12:16 PM

    Hello,

    Thank you for your answer.

    In fact, I think that if my script is able to check if the last machine created is started, it should be good.

    Let me explain, my script creates in a first time the machines, then in a second time the starts the machines one by one.

    If my script is capable of checking if the last machine is started, it would mean that all other machines have had time to start, and therefore the OS also had the time to start.

    For this, I must put a condition before my loop of configuration.

    If "the last machine" = "poweron"
    then
    "execute the following loop."

    What do you think?



  • 18.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 02, 2013 01:00 PM

    Why not keep it simple and just check if all the VMs you created are powered on ?

    And then add some time as a kind of grace period.



  • 19.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 02, 2013 01:41 PM

    Yes, that's exactly what I want.

    How to implement this functionality in my script?

    Sorry, I'm a beginner in powershell.

    Thank you very much.



  • 20.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 15, 2013 08:28 AM

    Hello everyone,

    I inserted your piece of code in my script "$vm = Get-VM MyVM
    while ($vm.PowerState -ne "PoweredOn"){
      sleep 5
      $vm = Get-VM $vm
    }
    "

    The problem is that it does not work, I made ​​a mistake?

    Mon script:

    param($Count,$Name,$Type,$Ip)

    Connect-VIServer -Server 10.*.*.* -Protocol https -User admin -Password admin
    2..$Count | Foreach {
      New-vm -vmhost u007.london.server.com -Name "$Name$_" -Template $Type -Datastore 007_datastore  }

    2..$Count | Foreach {
      Start-VM -VM "$Name$_"}
     
    $vm = Get-VM "$Name$_" while ($vm.PowerState -ne "PoweredOn"){
    sleep 5  $vm = Get-VM $vm}


    2..$Count | Foreach  {
    $VM = Get-VM "$Name$_"
    write-host "$Name$_"
    $ESXHost = $VM | Get-VMHost
    $secpasswd = ConvertTo-SecureString "formation" -AsPlainText -Force
    $GuestCred = New-Object System.Management.Automation.PSCredential ("formation", $secpasswd)
    Function Set-WinVMIP ($VM, $HC, $GC, $Ip){

    $ps1= "c:\ip.bat $Ip $VM"
    Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $ps1
    }
    Set-WinVMIP $VM $HostCred $GuestCred $Ip
    $Ip++
    }

    Thank you.



  • 21.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 15, 2013 08:43 AM

    There is a <CR><LF> missing it seems.

    The lines should look like this

    $vm = Get-VM $Name$_
    while ($vm.PowerState -ne PoweredOn){   sleep 5
      $vm = Get-VM $vm
    }


  • 22.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 15, 2013 11:34 AM

    Hello LUCD,

    Thank you for your availability.

    Yes I actually put the code as follows:

    "

    $vm = Get-VM "$Name$_"
    while ($vm.PowerState -ne "PoweredOn"){   sleep 5
      $vm = Get-VM $vm
    }"

    But it does not work, I get the following error: "Get-VM: Can not validate argument on parameter 'Name'. Argument is null The gold empty."

    The code is there in the right place in the script ?

    Thanks you.



  • 23.  RE: How to pass parameters in a variable in a loop FOREACH ?

    Posted Apr 15, 2013 11:39 AM

    Those lines should be in a foreach loop, like the earlier code in the script.

    Then the $_ variable will hold the number to be added to the basename.

    2..$Count | Foreach {
      $vm = Get-VM "$Name$_"
      while ($vm.PowerState -ne "PoweredOn"){
        sleep 5
        $vm = Get-VM $vm
      }
    }

    This will wait for all VM to be powered on.