Moose
Moose

Reputation: 755

Sending each line from text file to remote computer?

This is my script to whitelist IP in a remote system. I want my script to read data from a text file on my local system and then foreach line I want to execute the scriptblock on the remote server.

Text file looks like this:

url1
url2
url3

Here is my code:

Invoke-Command -ComputerName $($server.text) -Credential ciqdev\riteshthakur {
  param($a, $b, $c, $url)

  Set-Location "C:\Windows\System32\inetsrv"
$url | foreach {
  .\appcmd.exe set config "$_" -section:system.webServer/security/ipSecurity /+"[ipAddress='$($a)',allowed='$($c)',subnetMask='$($b)']" /commit:apphost 
}
} -ArgumentList $ip.text, $mask.text, $allowed, (get-content "File location")

This adds provided ip to all the pages in all the websites in IIS. Please help.

Upvotes: 1

Views: 98

Answers (2)

user189198
user189198

Reputation:

EDIT: Improved efficiency by generating the command dynamically, and invoking it once.

I'd suggest using a technique similar to the following, where you read in the text file as an array of lines, and then iterate over each line, generating the commands that you want to run on the remote system.

Once you've generated the command as a string, you simply call the static [ScriptBlock]::Create() method to create a ScriptBlock object, based on the command string, and pass that into Invoke-Command.

I'd suggest you get familiar with the concept of PowerShell Splatting, which I talk about in this YouTube video: https://www.youtube.com/watch?v=CkbSFXjTLOA. It's a really powerful concept, and helps make your code easier to read. The example code below uses PowerShell Splatting (available in PowerShell 3.0 and later).

### Read the text file on the local system
$Whitelist = Get-Content -Path IPwhitelist.txt;

### Generate the stub for the remote command
$RemoteCommand = @'
param($a, $b, $c)

Set-Location -Path C:\Windows\System32\inetsrv
'@

### Add more commands to the remote command
foreach ($Line in $Whitelist) {
    $RemoteCommand += '{1}.\appcmd.exe set config "{0}" -section:system.webServer/security/ipSecurity /+"[ipAddress=''$($a)'',allowed=''$($c)'',subnetMask=''$($b)'']" /commit:apphost' -f $Line, "`n";
}

### Invoke the entire remote command (once)
$Command = @{
    ComputerName = $Server.Text
    Credential = Get-Credential -Credential ciqdev\riteshthakur
    ScriptBlock = [ScriptBlock]::Create($RemoteCommand);
    ArgumentList = @($ip.text, $mask.text, $allowed)
    }
Invoke-Command @Command;

Upvotes: 2

Martin Brandl
Martin Brandl

Reputation: 58991

Just read the file using the Get-Content cmdlet and iterate over each item using the Foreach-Object cmdlet:

Invoke-Command -ComputerName $($server.text) -Credential ciqdev\riteshthakur {
  param($a, $b, $c, $urls)

  Set-Location "C:\Windows\System32\inetsrv"
  $urls | Foreach {
    .\appcmd.exe set config $_ -section:system.webServer/security/ipSecurity /+"[ipAddress='$($a)',allowed='$($c)',subnetMask='$($b)']" /commit:apphost
  }
} -ArgumentList $ip.text, $mask.text, $allowed, (Get-Content 'Path_to_your_file')

Upvotes: 2

Related Questions