Yet again I was given a task at work. This task was to turn off the Firewalls on hundreds of servers. So instead of logging into each one manually and changing the profiles on all the Firewall Profiles; Domain, Private and Public. I decided let us let PowerShell shine again.Now, they didn’t want the Firewall Services stopped, just the Profile states to be off. So after a little research and some help from some co-workers I put this script together.
Let’s talk about something thing through before I go into the script. The easiest way to turn off these Profile states is to run.
netsh advfirewall set allprofiles state off
This of course needs to be run locally on the machine. So I figured why not just use psexec to run the script. So I made a loop for the servers, looped it on the psexec and away it ran.. It ran VERY slowly. I had hundreds of these to run through. This would not work. So I decided to try and use PowerShell Invoke-Command. This required to have a session started using Enter-PSSession. Which of course gave this error.
Enter-PSSession : Connecting to remote server Server01 failed with the following error message : WinRM cannot process the request
Well that’s not going to work because I need to have the WinRM service installed. I don’t have the much time to get approvals to install the WinRM service on all these machines. So I remembered one of my coworkers had run scripts against a remote machine the other week using PowerShell. So I asked for his secret. The secret was Invoke-WmiMethod. Here is the code simply put.
Invoke-WmiMethod -class Win32_process -name Create -ArgumentList (“CMD.EXE /C netsh advfirewall set allprofiles state off”) –ComputerName Server01
This actually runs the script against the server with no Invoke-Command or other service to be installed. So I set off to write the full script and it is FAST. Sooo much faster than I was hoping for.
$command = "netsh advfirewall set allprofiles state off"
$cmd = "CMD.EXE /C " +$command
ForEach ($server in Get-Content "c:\scripts\computers.txt")
{
$theProc = Invoke-WmiMethod -class Win32_process -name Create -ArgumentList ($cmd) -ComputerName $server
If($theProc.ReturnValue -eq "0"){write-host "$server - Completed successfully"}else{write-host "$server - Completed UNsuccessfully"}
}
Now one of the downfalls of this is, you don’t know if the script worked. Of course you can go see on the server if the script did what it was supposed to do, but that is not what I am talking about. Basically you don’t get the output of the cmd. All you get is ReturnValue of 0 if the command went through correctly. Not that your script ran successfully. Just that your little cmd soldier has been sent into the field with the operations it was told to do successfully.