Use PowerShell to Create New Windows Firewall Rules

Doctor Scripto

Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell to create new Windows Firewall rules on local and remote systems.

Microsoft Scripting Guy, Ed Wilson, is here. Today, we are off to Europe. The Scripting Wife and I are actually on separate flights—it’s the way the airline miles worked out for the flight. Luckily, the Scripting Wife is an excellent traveler. When I was working in Vienna a few years ago, she flew into Frankfurt, hopped a train to Vienna, and navigated the local S-Bahn trains from the Ost-Bahnhoff to the hotel without incident.

Anyway, from Frankfurt, once we are all there, we hop a train to Dortmond, Germany, where we will meet with Klaus Schulte. Klaus, as you may know, was the winner of the Scripting Games, and he has written several guest Hey, Scripting Guy! Blog posts. Neither the Scripting Wife nor myself has been to Dortmond, and we are looking forward to hanging out with Klaus, taking pictures, and of course, talking about Windows PowerShell.

Enable firewall rules with Windows PowerShell

I know why we do it, but dude, I still like to use Ping to see if a computer is up or down. I know I can use Windows PowerShell and do something like Test-WSMan to see if WinRM works, but old habits die hard. By default, on certain profiles, and on certain versions of the operating system, the Ping command is disabled. It really makes life difficult in the early hours of the morning when I tend to forget these sorts of things. So, I like to explicitly ensure that Ping is permitted through Windows Firewall. Once I have done this, and a machine does not respond to Ping, I know I need to do something else.

Unfortunately, while I can use the Get-NetFireWallRule cmdlet to retrieve information about scope and status of a firewall rule, it does not display what the actual rule itself is or does. This means that, for example, I cannot use Get-NetFireWallRule to retrieve a firewall rule and use it as a pattern when it comes to creating a new rule. In addition, it means that I cannot use the GUI tool to create a new firewall rule, use the Get-NetFireWallRule cmdlet to obtain the actual rules themselves, and then use that to create a new rule. Get-NetFireWallRule is useful for auditing but not for system configuration.

Create a new firewall rule

To create a new firewall rule that permits the Ping command, I first import the NetSecurity module. Next, I use the New-NetFirewallRule cmdlet to create the new firewall rule. The problem with this is that I basically have to know what I am doing … specifically. If, for example, I do not know that a Ping is ICMPv4 protocol, and specifically ICMPType 8, then I have no chance of creating a new firewall rule. This is where the GUI tool is a bit more friendly—rather than having to look up the ICMPTypes, they are available through the ICMP type page. This is shown here.

Image of Customize ICMP Settings dialog box

Here again, even the GUI tool does not actually list the ICMP type. So to get this information, I need to either already know it (Hey, I wrote a book on Network Monitoring and Analysis), or I need to look it up by using Ping.

I recommend using the Windows PowerShell cmdlet to create the firewall rule, and then inspecting the rule in the Windows Firewall with Advanced Security tool. Here is the rule I came up with to permit Ping on network interfaces with the ANY profile. (Note that I could use DOMAIN or PRIVATE profiles as well.)

Import-Module NetSecurity

New-NetFirewallRule -Name Allow_Ping -DisplayName “Allow Ping”`

  -Description “Packet Internet Groper ICMPv4” `

  -Protocol ICMPv4 -IcmpType 8 -Enabled True -Profile Any -Action Allow 

Deploy the rule to all my Windows Server 2012 and Windows 8 machines

The first thing I need to do is to find all of my computers running Windows Server 2012 and Windows 8. I created a specific filter for the Get-ADComputer cmdlet that returns only these types of computers. I also specify Admin credentials to the Get-Credential cmdlet. This is shown here.

Import-Module NetSecurity, ActiveDirectory

$cred = Get-Credential -Credential iammred\administrator

$cn = Get-ADComputer -Properties operatingsystem -Filter `

 “Operatingsystem -like ‘windows 8 *’ -OR OperatingSystem -like ‘* 2012 *'”

Now, I create a CIM session to each of these computers. When I do this, I specify the name of the computer and the credentials to use to make the connection. I do not worry if computers are offline when calling the command because it only connects with online machines. It simplifies the code. This appears here.

$CIM = New-CimSession -ComputerName $ -Credential $cred

Next, I use the same New-NetFirewallRule command I used before—only this time I add that I want to use the CIM sessions in the $cim variable. Here is the code.

New-NetFirewallRule -Name Allow_Ping -DisplayName “Allow Ping”`

  -Description “Packet Internet Groper ICMPv4” `

  -Protocol ICMPv4 -IcmpType 8 -Enabled True -Profile Any -Action Allow `

  -CimSession $cim

Verify that the changes took place

Because I already have the CIM sessions in the $CIM variable, I can use that with the Get-NetFirewallRule cmdlet to verify that the remote servers and workstations have received the new firewall rule. This command is shown here.

Get-NetFirewallRule -DisplayName “Allow Ping” -CimSession $cim |

  Select PSComputerName, name, enabled, profile, action |

  Format-Table -AutoSize

 The command and the associated output are shown here.

Image of command output

I also want to verify that the Pings themselves will take place. Now, remember that the Get-ADComputer command returned some computers that were offline. But the $CIM variable contains CIM sessions to each computer that is obviously online. Unfortunately, the Test-Connection cmdlet does not accept a CIM session object, but that does not matter because it does accept an array of computer names. With auto array expansion, I can get the computer names from the variable containing all of the CIM sessions easily. Here is the command to which I arrived.

Test-Connection -ComputerName $cim.computername -BufferSize 15 -Count 1

The command and associated output are shown here.

PS C:\> Test-Connection -ComputerName $cim.computername -BufferSize 15 -Count 1 

Source        Destination     IPV4Address      IPV6Address                         

——        ———–     ———–      ———–                         

EDLT          DC2                                           

EDLT          DC3                                           

EDLT          DC4                                           

EDLT          EDLT      fe80::bd2d:5283:5572:5e77%19        

EDLT          HYPERV2                                         

EDLT          HYPERV3                                         

EDLT          SQL1                                          

EDLT          WDS1                                          

EDLT          WEB1                                           

Sweet, it worked! Join me tomorrow when I will talk about more way-cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy


Discussion is closed.

Feedback usabilla icon