Loop and array when using Invoke-Command

This topic contains 4 replies, has 2 voices, and was last updated by Profile photo of Saz Saz 6 months, 1 week ago.

  • Author
    Posts
  • #62006
    Profile photo of Saz
    Saz
    Participant

    I am trying to write a bit of code that loops and passes an array into a remote session using Invoke-Command and am having issues.

    So far my code is:

    #Collects Credentials
    $username = Read-Host -Prompt "Enter the username for the account" 
    read-host -Prompt "enter password" -assecurestring | convertfrom-securestring | out-file C:\cred.txt
    $password = get-content C:\cred.txt | convertto-securestring
    $credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$username",$password
    
    #Declare variables
    $dns_srv1 = "DNS"
    $dns_srv2 = "DNS2"
    $dns_ip1 = "10.0.0.4"
    $dns_ip2 = "10.0.0.5"
    
    #Declare DNS zones to be created
    $zones="bigfirm.com","bigfirm2.com","bigfirm3.com","bigfirm3.com","bigfirm4.com","bigfirm5.com","bigfirm6.com"
    
    #Declare script to be run on remote server
    $scriptblock = param($zones, $dns_ip1, $dns_srv2) {Add-DnsServerSecondaryZone -MasterServers $dns_ip1 -Name $_ -ZoneFile $_+".dns"}
    
    #Create remote session and invoke script
    $session = New-PSSession -ComputerName $dns_srv2 -Credential $credentials 
    ForEach ($z in $zones)
    {Invoke-Command -Session $session -ScriptBlock $scriptblock}
    
    #close remote session
    Remove-PSSession $Session
    

    However when I run it the variables, $dns_Ip1, $dns_srv2 and $zones isn't being passed into the Invoke-Command statement. Not sure what I'm doing wrong, probably something obvious! 🙂

    Any help gratefully appreciated.

  • #62009
    Profile photo of Don Jones
    Don Jones
    Keymaster

    This:

    #Declare script to be run on remote server
    $scriptblock = param($zones, $dns_ip1, $dns_srv2) {Add-DnsServerSecondaryZone -MasterServers $dns_ip1 -Name $_ -ZoneFile $_+".dns"}
    

    Isn't quite right. The Param() block goes inside the script block.

    #Declare script to be run on remote server
    $scriptblock =  {param($zones, $dns_ip1, $dns_srv2) Add-DnsServerSecondaryZone -MasterServers $dns_ip1 -Name $_ -ZoneFile $_+".dns"}
    

    Additionally:

    {Invoke-Command -Session $session -ScriptBlock $scriptblock}
    

    Isn't what I'd expect. You're missing the -Arguments parameter, which should be an array of values that will map to $zones, $dns_ips1, and $dns_srv2 inside your script block.

    • #62013
      Profile photo of Saz
      Saz
      Participant

      Thanks for the feedback Don.

      I'm not quite sure what you mean by the arguments parameter, "should be an array of values that will map to $zones, $dns_ips1, and $dns_srv2 inside your script block". Are you saying I need to create another array to store those values??

  • #62017
    Profile photo of Don Jones
    Don Jones
    Keymaster
    {Invoke-Command -Session $session -ScriptBlock $scriptblock -Arg @($zones,$dns_ips1,$dns_srv2)}
    

    You can create an array just by using @() and comma-separating your values. Those get listed in the same order as you want them injected into the Param() block.

    See also https://devopscollective.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/remote-variables.html.

    • #62020
      Profile photo of Saz
      Saz
      Participant

      Thanks Don, I totally misread your earlier post. 🙂

You must be logged in to reply to this topic.