VMware Cloud Community
lowrider1064
Contributor
Contributor
Jump to solution

PowerCLI Script for Firewall allowed IP's

I am trying to import a CSV and apply allowed IP's to the services in that CSV.  This is a snippet of what I currently have:

$ip1 = X.X.X.X

$ip2 = X.X.X.X

$services - Import-CSV -Path C:\Scripts\ESXI_Host\firewall\Services.csv

foreach ($Service in $services) {

     $esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.set($true, $false, "$Service")

     $esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.allowedip.add("$ip1","$Service")

     $esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.allowedip.add("$ip2","$Service")

     $esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.refresh()

}

My question is... How do I add the service that is listed in the CSV to $Service.  As it is currently laid out, I am getting errors reading each service.  And maybe it is something simple that I am missing.

Thanks in Advance,

Chris Priester

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Since you are reading the services form a CSV file, there must be a property (or column header).

You should use that to refer to the value.

Something like this

$esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.set($true, $false, $Service.Name)

It assumes that your CSV looks like this

Name

service1

service2

service3


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

View solution in original post

0 Kudos
16 Replies
LucD
Leadership
Leadership
Jump to solution

Since you are reading the services form a CSV file, there must be a property (or column header).

You should use that to refer to the value.

Something like this

$esxcli = (Get-EsxCli -VMHost "ESXI01").network.firewall.ruleset.set($true, $false, $Service.Name)

It assumes that your CSV looks like this

Name

service1

service2

service3


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

0 Kudos
lowrider1064
Contributor
Contributor
Jump to solution

Thanks LucD.  That worked like a charm, I just had to remove the "" around the service name

Respectfully,

Chris Priester

0 Kudos
lowrider1064
Contributor
Contributor
Jump to solution

How would I go about expanding this to include "Get-VMHost".  and apply this to each VMhost in the cluster.

Respectfully,

Chris Priester

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try like this

$ip1 = X.X.X.X

$ip2 = X.X.X.X

$services = Import-CSV -Path C:\Scripts\ESXI_Host\firewall\Services.csv -UseCulture

$clusterName = 'MyCluster'

foreach($esx in (Get-Cluster -Name $clusterName | Get-VMHost)){

    $esxcli = Get-EsxCli -VMHost $esx

    foreach ($Service in $services) {

     $esxcli.network.firewall.ruleset.set($true, $false, "$Service")

     $esxcli.network.firewall.ruleset.allowedip.add("$ip1","$Service")

     $esxcli.network.firewall.ruleset.allowedip.add("$ip2","$Service")

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

}


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

0 Kudos
lowrider1064
Contributor
Contributor
Jump to solution

LucD,

If I am every at any of the conferences and see you I owe you a beer.  Thanks for the help.

Respectfully,

Chris Priester

0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hey all,

I'm just wondering why this wouldn't work, or am i forced to write a line for each IP/subnet ?

$vihostService = "webAccess","CIMHttpServer"

$remoteIP = "10.11.12.0/22","10.13.14.0/22","192.176.1.1"

$esxcli = (get-esxcli –vmhost vesxi03).network.firewall

#$esxcli.ruleset.list()

#$esxcli.ruleset.rule.list("webAccess")

$esxcli.ruleset.set($false,$true,"$vihostService")

$esxcli.ruleset.allowedip.add("$remoteIP","$vihostService")

Nicholas
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Afaik, you'll have to do that per IP address or IP address range


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

0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

I'm glad you responded so quickly, so i kind of just figured it out that because it  needs to run in a loop it has to be done line by line either by IP or service, is that correct ?

Nicholas
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Luc, I just tested this and it works

$Service1 = "webAccess"

$remoteIP = "10.11.12.0/22","10.13.14.0/22","192.176.1.1"

$esxcli = (get-esxcli –vmhost vesxi03*).network.firewall

$esxcli.ruleset.set($false,$true,"$Service")

foreach ($ip in $remoteIP){

$esxcli.ruleset.allowedip.add("$ip","$Service1")

}

But this didn't

$Service1 = "webAccess"

$Service2 = "CIMHttpServer"

$remoteIP = "10.11.12.0/22","10.13.14.0/22","192.176.1.1"

$esxcli = (get-esxcli –vmhost vesxi03*).network.firewall

$esxcli.ruleset.set($false,$true,"$Service")

foreach ($ip in $remoteIP){

$esxcli.ruleset.allowedip.add("$ip","$Service1")

$esxcli.ruleset.allowedip.add("$ip","$Service2")

}

Nicholas
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Silly me, just worked out where i went wrong, ok i fixed it and it works. So I have about 7 ESXi services which  need access restricted to approximately 20 IPs/Subnets over 25 clusters adding up to 200 hosts, do you see a more efficient way to do this. I'm going to do it cluster at a time and loop thru hosts and potentially read hosts and IPs/subnets from a list?

$Service1 = "webAccess"

$Service2 = "CIMHttpServer"

$remoteIP = "10.11.12.0/22","10.13.14.0/22","192.176.1.1"

$esxcli = (get-esxcli –vmhost vesxi03*).network.firewall

$esxcli.ruleset.set($false,$true,"$Service1")

$esxcli.ruleset.set($false,$true,"$Service2")

foreach ($ip in $remoteIP){

$esxcli.ruleset.allowedip.add("$ip","$Service1")

$esxcli.ruleset.allowedip.add("$ip","$Service2")

}

Nicholas
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could make it a series of nested ForEach loops, including the services.

Something like this

$Services = "webAccess","CIMHttpServer"

$remoteIP = "10.11.12.0/22","10.13.14.0/22","192.176.1.1"

foreach($esx in Get-VMHost){

    $esxcli = Get-EsxCli -VMHost $esx

    foreach($service in $services){

        foreach($ip in $remoteIP){

            $esxcli.network.firewall.ruleset.allowedip.add($ip,$service)

        }

    }

}


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

0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc,

I got it working with this script, if for example i run it the first time. However to revert the changes and set it to allow all for example within the webclient you have to re-check the box allowAll IP which in turn removes any ips you had listed there, so i figured if i want to revert that change using a script i would just need the following line $esxcli.network.firewall.ruleset.set($false,$true,$Service)

Which does seem to work, if I check the webclient it set back to ALL on those services. The problem is if I use the first script it works as expected but I get error saying the IP already exists. But if I revert the changes in the webclient just by checking that box and run the first script I get no errors??

[Array]$IPAddresses = '10.10.10.0/22','192.168.3.0/24'

[Array]$Services = 'webAccess','CIMHttpServer'

$esxcli = Get-EsxCli -VMHost vesxi03*

            foreach ($Service in $Services) {

             $esxcli.network.firewall.ruleset.set($false,$true,$Service)

            

                $esxcli.network.firewall.ruleset.allowedip.list($Service)

           

                foreach ($IPAddress in $IPAddresses){

                  $esxcli.network.firewall.ruleset.allowedip.add($IPAddress,$Service)

                    }

                $esxcli.network.firewall.refresh()

               }

PS C:\> [Array]$IPAddresses = '10.10.10.0/22','192.168.3.0/24'

[Array]$Services = 'webAccess','CIMHttpServer'

$esxcli = Get-EsxCli -VMHost vesxi03*

            foreach ($Service in $Services) {

             $esxcli.network.firewall.ruleset.set($false,$true,$Service)

            

                $esxcli.network.firewall.ruleset.allowedip.list($Service)

           

                foreach ($IPAddress in $IPAddresses){

                  $esxcli.network.firewall.ruleset.allowedip.add($IPAddress,$Service)

                    }

                $esxcli.network.firewall.refresh()

               }

true

AllowedIPAddresses              Ruleset     

------------------              -------     

{10.10.10.0/22, 192.168.3.0/24} webAccess   

Message: Ip address already exist.;

InnerText: Ip address already exist.EsxCLI.CLIFault.summary

At line:13 char:19

+ ...             $esxcli.network.firewall.ruleset.allowedip.add($IPAddress ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : OperationStopped: (:) [], ViError

    + FullyQualifiedErrorId : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViError

Message: Ip address already exist.;

InnerText: Ip address already exist.EsxCLI.CLIFault.summary

At line:13 char:19

+ ...             $esxcli.network.firewall.ruleset.allowedip.add($IPAddress ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : OperationStopped: (:) [], ViError

    + FullyQualifiedErrorId : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViError

true

true

{10.10.10.0/22, 192.168.3.0/24} CIMHttpServer

Message: Ip address already exist.;

InnerText: Ip address already exist.EsxCLI.CLIFault.summary

At line:13 char:19

+ ...             $esxcli.network.firewall.ruleset.allowedip.add($IPAddress ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : OperationStopped: (:) [], ViError

    + FullyQualifiedErrorId : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViError

Message: Ip address already exist.;

InnerText: Ip address already exist.EsxCLI.CLIFault.summary

At line:13 char:19

+ ...             $esxcli.network.firewall.ruleset.allowedip.add($IPAddress ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : OperationStopped: (:) [], ViError

    + FullyQualifiedErrorId : VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.ViError

true

Nicholas
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The list of allowed IP addresses stays, even if you switch to All.

You have 2 options:

  1. Clear the allowedIP list
  2. Check with $esxcli.network.firewall.ruleset.allowedip.list() if a specific IP is already in the list


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

0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Thanks Luc, I've written another script which lists allowed IP then removes them but I'm wondering when you say "Clear the AllowedIP list" is there a simple way that you know that could just clear all?

Nicholas
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Hi Luc, I think I have the scripts working well but the issue i was having was when i started restricting services the hosts become isolated and disconnected when it got to the "vSphereClient" rulesetid, this basically opens tcp 443 and 902. When restricting this particular ruleset via PowerCLI Get-Esxcli its a catch 22 becasue before applying the allowedip list yu have the set it to not allowall as soon as you run $esxcli.network.firewall.ruleset.set($false,$true,'vSphereClient') it immediately closes 443 and 902 and and not able to apply the allowedip list. This of course works fine if done in the GUI... Any ideas?

The only workaround I can think of is to create a temp custom rule allowing 443 and 902, then restrict 'vSphereClient' but surly there has to be an easier way.

Do you know if PowerCLI can modify VMHost Firewall i see there are some VMHostFirewallDefaultPolicy cmdlets available?

Nicholas
0 Kudos
nicholas1982
Hot Shot
Hot Shot
Jump to solution

Never mind I'm so silly, just figured out i can i can disable the whole firewall first then enable it.

$esxcli.network.firewall.set($true,$false)

$esxcli.network.firewall.set($false,$true)

Nicholas
0 Kudos