Loop and array when using Invoke-Command

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! :slight_smile:

Any help gratefully appreciated.

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.

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??

{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.

Thanks Don, I totally misread your earlier post. :slight_smile: