VMware Cloud Community
Vimal348
Enthusiast
Enthusiast
Jump to solution

Adding a new Firewall Rule in each ESX hosts

Hello,

Can someone please help me on this:
We have almost 400 ESX hosts sitting in multiple vCenters. As a part of syslog configuration we have to add a new rule in each ESX hosts since we are using a different port for its communication as per syslog team. Some of the esx hosts already have that Firewall rule created. But many of them are missing.

Here I have the ESX hosts name (FQDN) in one notepad, that require the new firewall rule needed. Lets say notepad name is; 'ESXhostName' and its location is: D:\ESX

To create new Firewall rule in esx host, I have copied the firewall xml file (Lets say it name is: 'CompanyFirewall') in my local drive: D:\File\CompanyFirewall.xml

This is the xml file:

<service id="0032">

<id>concast backport</id>

<rule id='0000'>

<direction>outbound</direction>

<protocol>udp</protocol>

<porttype>dst</porttype>

<port>2004</port>

</rule>

<enabled>true</enabled>

<required>false</required>

</service>

Task:

Adding this xml file in each esx hosts is time consuming. Hence can someone please help me creating a script that I can

> Get the esx hosts from that notepad and

> login with root credentials and

> copy the xml file from my local drive and paste it in the esx hosts firewall location: /etc/vmware/firewall and (Not sure how can it possible)

> Refresh the firewall for each esx host (We may need to modify this command as per the script)

Got the below commands for refreshing the firewall from this link: vSphere PowerCLI - Configure syslog on VMware ESXi hosts and Enable security profile firewall | vGee...

$esxcli =  Get-EsxCli -VMHost esxi002.vcloud-lab.com -V2

$esxcli.network.firewall.refresh.Invoke()

> Disconnect the host from the session

> Get the next host from the notepad and do the same task again

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

$user = 'root'

$pswd = 'VMware1!'


$cred = New-Object -TypeName pscredential -ArgumentList $user,(ConvertTo-SecureString -String $pswd -AsPlainText -Force)


Get-Content -Path .\names.txt -PipelineVariable esxFQDN |

ForEach-Object -Process {

    $sshStatus = Get-VMHost -Name $esxFQDN | Get-VMHostService | where{$_.Label -eq 'SSH'}

    if(-not $sshStatus.Running){

        Start-VMHostService -HostService $sshStatus -Confirm:$false

    }

    try{

        Set-SCPFile -ComputerName $esxFQDN -Credential $cred -RemotePath '/etc/vmware/firewall/service.xml' -LocalFile 'D:\File\CompanyFirewall.xml' -AcceptKey -ErrorAction Stop

        Write-Output "FW xml file copied to $esxFQDN"

    }

    catch{

        Write-Output "FW xml file not copied to $esxFQDN"

    }


    try{

        $session = New-SSHSession -ComputerName $esxFQDN -Credential $cred –AcceptKey -ErrorAction Stop

        Invoke-SSHCommand -SSHSession $session -Command ' esxcli network firewall refresh'

        Remove-SSHSession -SSHSession $session | Out-Null

    }

    catch{

        Write-Output "SSH session to $esxFQDN failed"

    }


    if(-not $sshStatus.Running){

        Stop-VMHostService -HostService $sshStatus -Confirm:$false

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

46 Replies
LucD
Leadership
Leadership
Jump to solution

Read the .txt file with Get-Content, then loop through all names.

Open the SSH session with the New-SSHSession cmdlet from the Posh-SSH module.

You can copy the xml file with the Set-ScpFile cmdlet from the Posh-SSH module.

You can send the esxcli command through the Get-EsxCli cmdlet or directly through the SSH session.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

@LucD, Appreciate if you can share the script, since I dont have experience in scripting.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do something like this

$user = 'root'

$pswd = 'VMware1!'


$cred = New-Object -TypeName pscredential -ArgumentList $user,(ConvertTo-SecureString -String $pswd -AsPlainText -Force)


Get-Content -Path .\names.txt -PipelineVariable esxFQDN |

ForEach-Object -Process {

    Set-SCPFile -ComputerName $esxFQDN -Credential $cred -RemotePath '/etc/vmware/firewall/service.xml' -LocalFile 'D:\File\CompanyFirewall.xml' -AcceptKey


    $session = New-SSHSession -ComputerName $esxFQDN -Credential $cred –AcceptKey

    Invoke-SSHCommand -SSHSession $session -Command ' esxcli network firewall refresh'

    Remove-SSHSession -SSHSession $session | Out-Null

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

I am getting error. In that script where can I mention the esx host esx host txt file?

And what method it is using to copy the local drive xml file to esx hosts directory ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The name of the .txt file is the value on the Path parameter on the Get-Content cmdlet.

It is using SCP to copy the file.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you install the Posh-SSH module I linked to in my first reply?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Replace -AcceptKey with -AcceptKey $true


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Do you have empty lines in your .txt file?

What is the layout of that file?

One ESXi FQDN per line?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

For testing purpose, I have copied only one esx host information in that txt file. There is no empty space/line after that esx host entry.

Upload and share screenshots and images - print screen online | Snipboard.io

While running that script it is fetching that ESX host information from the txt file. That you have seen in previous picture.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You forgot the pipeline symbol at the end of the Get-Content line.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The SSH service is apparently not running on that ESXi node or the FW rule forbids a connection.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

And the AcceptKey does not need a value on the New-SshSession cmdlet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can you please stop making updates in place?

That makes the thread hard to follow.

There are 2 issues

  • Your ESXi node refuses the SSH connection
  • The AcceptKey on the New-SshSession cmdlet does not need a $true value


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Why do you keep updating your same reply over and over again?

This is highly unfriendly to others who read this thread.

I can't solve your issue with the ESXi node refusing the SSH connection.

Start the service or change the FW rule.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Vimal348
Enthusiast
Enthusiast
Jump to solution

Hello LucD, I am really sorry. Now only I realized that your new comments are on my 2nd page. I was on 1st page and since I didnt see the 2nd page I was trying to communicate with you. Please forgive me. Let me go through your suggestions.

Reply
0 Kudos