Search for and modify a firewall rule in powershell using Get-NetFirewallRule/PortFilter/AddressFilter - powershell

What I am trying to do seems simple but I need help knitting all the pieces together.
What I want to do is search all the firewall rules based on local port and protocol (i.e. 3389 TCP) then, if I find one, ensure that the RemoteAddress is set to x.x.x.x. If I don't find one, then add it.
I can't seem to find out how to knit together Get-NetFirewallPortFilter, Get-NetFirewallAddressFilter, and Get-NetFirewallRule to do what I want.
We have a Remote Desktop Gateway and Multi-Factor Authentication and as part of compliance, all RDP connections must go through the RDGateway so that Two Factor is used. There is a rule in place at the firewall but I want to find some way to enforce this on mass using Powershell (in an SCCM compliance item) at the Windows Firewall level too. Sure I could do a Group Policy Objects but I want to be able to report on compliance which is why I am trying to do this via System Center Configuration Manager.

Ugh. I believe this will work. You can pipe these things both ways. I believe it's pretty self explanatory, but it takes 2 minutes on my computer. At least I got a progress bar. The whatif output is actually incorrect. That's the name, not the displayname.
EDIT: Oh I see. It's much faster without the first command. I guess that's the point. I never understood. It's like the -filter parameter to other commands like get-childitem, that make it faster. Get-NetfirewallPortFilter actually returns the name of the firewall rule if you look at all the properties.
# Get-NetFirewallRule |
Get-NetFirewallPortFilter -Protocol TCP |
Where LocalPort -eq 3389 | Get-NetFirewallRule |
Set-NetFirewallRule -RemoteAddress 192.168.1.1 -WhatIf
Output:
What if: Set-NetFirewallRule DisplayName: RemoteDesktop-UserMode-In-TCP

Piping each command to the next takes the input and filters to the end where your result showing the list of Scopes (RemoteAddress) by expanding the selected property, which you can then use to Edit your Set. Each Command shows a subset of the prior one...
Get-NetFirewallRule -DisplayName "Allow Port 3389 - RDP Access" |Get-NetFirewallAddressFilter |Select -expandproperty RemoteAddress

Related

Test connectivity using specific NIC [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 years ago.
Improve this question
We need to change DNS configuration for several servers, before I do that I need to test DNS ports on those servers.
The problem is that our servers have multiple NICs, so we need to ensure that the DNS ports test go through a specific NIC, in this case would be the NIC that has DNS configured already.
So, we need to retrieve the NICs list, identify which one has DNS configured and then use that specific NIC to perform the port test to the new DNS servers and check if it is Ok/NOTOK.
The second problem is that our network ranges from Windows 2003 to Windows 2019, so the solution must work through different PowerShell versions ranging from 2.0 to the latest.
With more recent PowerShell versions this wouldn't be a problem, but since we have PS 2.0 and up, the scenario changes.
Anyone has or knows any example out there for this task?
Thank you.
The cmdlet,
Test-Connection
does provide a mechanism for this use case.
Test-Connection -Source 'SomeIPA' -Destination 'SomeDest'
Native ping in any OS provides this as well via the source switch.
You can get InterfaceIndex using
Get-Netadapter
cmdlet in recent versions of PowerShell. ---
Get-NetAdapter -Physical | Where Status -eq 'up'
--- below v3, you'd do ---
netsh interface ipv4 show interfaces
--- or ---
Get-WmiObject -Class win32_networkadapter
Any connectivity test will only occur with a nic that has connectivity and is properly routed. There are several articles and Q&A's that talk to your use case. A quick web search will show them to you. 'ping using a specific nic'
Examples:
Ping from specific network adapter on Windows
The adapter chosen is based on the routing tables. You can examine the
routing tables by running 'route print' or 'netstat -r'. Each entry
will have a metric which dictates the weighting of the route - lower
numbers are preferred. You can manipulate the routing table with the
'route' command. route /? for details.
route add (destination subnet) MASK (destination subnet mask)
(gateway) IF (interface)
Probably easier is to use the -S switch, which lets you specify the
source IP address (see ping /? for more infos).
Another thing you can do is change the binding order, which meets your
"option to prefer one adapter over the other". Although it varies from
Windows OS to OS, it is in a similar location as this example: For
Windows 7 you right click on Network, and click properties. Then you
click on ""Change adapter settings". Then click on the menu
Advanced>Advanced Settings and move the connection you want to have
priority to the top.
From Windows 7 (Version 6.1 Build 7601: Service Pack 1) ping /? Usage:
ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name
Ping using specific gateway interface or source IP address
Ping using specific source IP address One can set socket stuff. The
syntax is:
ping -S ip dest
ping -S 192.168.2.24 www.cyberciti.biz
ping -c 4 -S 10.207.0.54 1.1.1.1
Can I try to ping a website through a specific adapter?
OK, missed the Port thing, but, Test-NetConnection is not in legacy PowerShell period, so not an option, and it does not provide a source switch either anyway.
(Get-Command Test-Connection).Parameters.Keys
AsJob
DcomAuthentication
WsmanAuthentication
Protocol
BufferSize
ComputerName
Count
Credential
Source
Impersonation
ThrottleLimit
TimeToLive
Delay
Quiet
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
(Get-Command Test-NetConnection).Parameters.Keys
ComputerName
TraceRoute
Hops
CommonTCPPort
Port
DiagnoseRouting
ConstrainSourceAddress
ConstrainInterface
InformationLevel
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
You could take the route of using the .Net libraries. Which is how it's been documented in legacy PowerShell. Using stuff like ...
--- New-Object Net.Sockets.TcpClient ---
$tcpObj = New-Object Net.Sockets.TcpClient
$tcpObj.Connect($Ipaddress,$Port)
More info on that namespace is here:
https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient?view=netframework-4.8
... combining the results from ping or Test-Connection and piping that to Net.Sockets to deal with the port check.
For example (since this was sort of interesting I threw this together and tested it - so I know it works - well not on W2K3 as I've had none of those in over a decade.):
Clear-Host
$SourceIpa = 'SomeSourceNicIpa'
$TargetDestination = 'Stackoverflow.com'
$TargetResponseCount = 1
$DestinationPort = 443
try
{
$DestinationIpa = (Test-Connection -Source $SourceIpa -ComputerName $TargetDestination -Count $TargetResponseCount).ipv4address.ipaddressToString
$tcpObj = New-Object Net.Sockets.TcpClient($DestinationIpa,$DestinationPort)
if($tcpObj -ne $null)
{
"Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is open."
$tcpObj.close()
}
}
catch
{
Write-Warning -Message "Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is not open."
$tcpObj.close()
}
And a similar approach could have been done with ping and the .Net namespace as well.

Getting interfaces and their DNS servers that are STATIC (not dhcp allocated)

I'm trying to ge the DNS servers of network interfaces via WMI that are static (placed by the user). I have this script that works, except for the static part of course:
Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.DNSServerSearchOrder -ne $null} | Select DnsServerSearchOrder,Index,InterfaceIndex
This leads to an output like so:
DnsServerSearchOrder Index InterfaceIndex
-------------------- ----- --------------
{192.168.122.1} 1 6
{1.1.1.1} 2 10
The interface with 192.168.122.1 has it's DNS setup to DHCP so that value is not good for me. How do I filter out interfaces where dns is not static? Any ideas?
netsh interface ip show config:
Configuration for interface "Ethernet"
DHCP enabled: Yes
IP Address: 192.168.122.130
Subnet Prefix: 192.168.122.0/24 (mask 255.255.255.0)
Default Gateway: 192.168.122.1
Gateway Metric: 0
InterfaceMetric: 35
DNS servers configured through DHCP: 192.168.122.1
Register with which suffix: Primary only
WINS servers configured through DHCP: None
Configuration for interface "Ethernet 2"
DHCP enabled: Yes
IP Address: 10.0.0.17
Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
Default Gateway: 10.0.0.1
Gateway Metric: 0
InterfaceMetric: 35
Statically Configured DNS Servers: 1.1.1.1
Register with which suffix: Primary only
WINS servers configured through DHCP: None
Notice the difference in terms between Statically Configured DNS Servers and DNS servers configured through DHCP. I figured I might parse this output but I'm not sure if I can rely on this text if windows language/locale is changed and I'd rather use the WMI interface if possible.
I thought this might be available in the System.Net.NetworkInformation namespace, but evidently not. I looked through a few lower-level Windows networking APIs thinking certainly it must exist somewhere in there, but no such luck. After running dumpbin on netsh.exe to see what kinds of libraries/functions it's consuming, I did get an idea of one other place to look: the registry.
As it happens, if you look in the registry under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ key you will see a key for each network interface with the name in GUID format. Within an interface's key you will find two values of interest: DhcpNameServer and NameServer. On my client system where the DNS server is set by DHCP, DhcpNameServer contains that DNS server's IP address and NameServer contains an empty [String]. If I manually set a DNS server while keeping the automatically-assigned address for the interface itself, NameServer then contains that manually-set DNS server address while DhcpNameServer still contains the same DNS server specified by DHCP.
Based on these observations, it would seem that...
The DhcpNameServer value always contains the DNS server(s) specified by DHCP.
The NameServer value always contains the DNS server(s) specified manually.
When you query the system for its nameservers (e.g. via the Win32_NetworkAdapterConfiguration.DNSServerSearchOrder property) the result will contain the value of NameServer, if provided, otherwise the value of DhcpNameServer, if provided. In other words, the system tells you which DNS servers are currently being used, but not how their addresses were specified.
To determine if an interface has manually-assigned DNS servers, check if NameServer has a non-empty value.
Thus, given an interface with ID $interfaceID, you can build a path to its registry key like this...
$interfaceKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$interfaceID"
...and then retrieve the dynamically-assigned and manually-assigned nameserver values like this...
Get-ItemProperty -Path $interfaceKeyPath -Name 'DhcpNameServer', 'NameServer'
That just leaves the matter of from where you get the value for $interfaceID, and there are numerous sources although the trick will be excluding undesirable interfaces (for example, on my Windows 10 system I have a packet capture loopback adapter and a hypervisor adapter that I'd want to be excluded from such a query). The most compatible way (dating back to .NET 2.0) would be the Id property of the NetworkInterface class...
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() `
| Select-Object -ExpandProperty 'Id'
...although the only useful properties on which to filter are Name and NetworkInterfaceType.
On Windows Vista and above the Win32_NetworkAdapter class provides a GUID property...
Get-WmiObject -Class 'Win32_NetworkAdapter' -Property 'GUID' -Filter 'PhysicalAdapter = true'
...although even when filtering on PhysicalAdapter it still returns the loopback and hypervisor adapters and I'm not seeing any definitive property or class relation that can be used to select only hardware adapters.
The Win32_NetworkAdapterConfiguration class is much the same...
Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration' -Property 'SettingID'
...with no properties to filter out non-hardware or even non-physical adapters.
On (I think) Windows 8 and above there's the Get-NetConnectionProfile cmdlet...
Get-NetConnectionProfile | Select-Object -ExpandProperty 'InstanceID'
which is documented to get "a connection profile associated with one or more physical network adapters" and, on my system, it does only return my physical adapter.
There is also the Get-NetAdapter cmdlet...
Get-NetAdapter -Physical `
| Where-Object -Property 'EndPointInterface' -NE -Value $true `
| Select-Object -ExpandProperty 'InterfaceGuid'
I found that passing the -Physical parameter excluded the hypervisor adapter but not the loopback adapter, so filtering out where EndPointInterface is $true was necessary to eliminate that. The HardwareInterface and Virtual properties might also be of interest.
Another option would be to invoke the Get-NetAdapterHardwareInfo cmdlet, which seems to know how to distinguish true hardware adapters, and let that determine which adapters are retrieved by Get-NetAdapter...
Get-NetAdapterHardwareInfo `
| Get-NetAdapter `
| Select-Object -ExpandProperty 'InterfaceGuid'
The Get-Net* cmdlets above return CIM instances so, for example, instead of Get-NetAdapter -Physical you could use something like...
Get-WmiObject -Namespace 'Root\StandardCimv2' -Class 'MSFT_NetAdapter' `
-Property 'InterfaceGuid' -Filter 'HardwareInterface = true AND EndPointInterface = false'
to retrieve the MSFT_NetAdapter instances just the same. I'm not really sure what the guidance is on using one versus the other. It would seem like one should prefer the cmdlets, and yet, unlike WMI/CIM, they offer limited/no parameters for efficiently filtering the output or specifying which properties are desired so you have to do that in the pipeline. I think it's noteworthy, though, that I wasn't able to find any current documentation for these MSFT_* class; they all say they're no longer updated, except for the MSFT_NetConnectionProfile class for which I couldn't find any documentation page at all. That says to me Microsoft doesn't want you relying on any definite structure of these classes, and yet if the cmdlets just pass along those class instances...I'm not sure how can you meaningfully and reliably interact with them if nothing is documented.
Also, keep in mind that you'll want to prefer Get-CimInstance and its ilk over Get-WmiObject, where possible. I don't think I've yet encountered an instance where it was any more complicated than changing Get-WmiObject to Get-CimInstance, although there are more differences (not necessarily bad) than the name.
After enough bashing I found a solution but I'm not 100% positive is the right path. On all DHCP DNS servers the DNS values contain a single ip address and that IP address is equal to the Default Gateway value. When those values match we're dealing with a DHCP DNS server and not statically configured.

How do I completely wipe out NIC settings with Powershell?

Have a smidge of a problem. I am trying to completely blank out the IP address, subnet mask, and default gateway of a single NIC on one of my VMs.
I open up IPv4 Properties on that NIC and set it to DHCP (there is no DHCP server available to it and it isn't getting a Windows APIPA address) and then I look in Advanced and make sure there aren't alternate addresses assigned. I close out all of the windows. Then, I open up CMD and type ipconfig and it shows that it has an IP address, subnet mask, and a default gateway. I even tried Disabling and Enabling the NIC and typing Restart-NetAdapter -Name "Ethernet" and there are no changes.
In PS, I type Get-NetAdapterAdvancedProperty -DisplayName "Network Address" and it shows -- under the DisplayValue.
For some reason, and I'm not sure why (I didn't give it the ol' College Try), but when I type Set-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "0.0.0.0" it shows red. I try putting in a valid address to see if maybe the cmdlet won't take all zeros and it does the same thing. I checked the man page and I'm fairly sure that the format is correct (I tried $ip = #("0.0.0.0") and gave it $ip and $ip[0] but it still, no joy).
I just want all of the NIC settings wiped and it seems like it is but ipconfig and Get-NetIPAddress, and Get-NetIPConfiguration keep showing addresses whereas Get-NetAdapterAdvancedProperty -DisplayName "Network Address" show that it's blank.
Why won't it let me wipe the configs (without doing an OOBE SysPrep)? I feel like the answer is probably something simple that I'm just overlooking but I haven't really found anything online--it's mostly just ways to work with your NIC configurations within Powershell.
Could anyone help shine some light on what is actually going on?
Thanks.
If you have several NICs, Get-NetAdapter will list all adapters with their respective index, Get-NetAdapter -ifIndex $ | Get-NetIPAddress | Remove-NetIPAddress (substitute $ with desired adapter index) will wipe IP configuration.
In case of a vm with a single adapter you can omit the index:
Get-NetAdapter | Get-NetIPAddress | Remove-NetIPAddress

Selecting specific IIS website using powershell

I currently have several websites running under IIS. For ease lets call them site1, site2, and site3
My powershell script accepts a parameter from the user of which number site to work with. I am attempting to turn off site3 with simply the parameter 3
I thought it would be something along the lines of
stop-website | where-object {$_.name -like "*3*"}
this line is executed, but brought to a prompt for "name"
The Name property seems to accept wildcards (although help states otherwise) so you should be able to stop it with this:
Stop-Website -Name *3*

Powershell - Refresh SNMP from registry or do a SNMPServiceResetEvent

I've written a powershell script that writes registry entries for network drivers to change DCB settings. Things like turning DCB on and off, defining traffic classes and bandwidth groups. After writing the values to registry sometimes you cannot see the changes with SNMP remotely. Though this is inconsistent.
I've scoured the web to see if there is a way to force SNMP to get its values from registry again. We have a script that sets the values in SNMP which automatically changes the registry. I'm trying to go the opposite way and set the values in the registry and have the MIB updated. I've tried reseting the SNMP service and network device in the script with no luck.
After modifying the registry, do a SetEvent on the global event named
"SNMPServiceResetEvent". (That is, do a CreateEvent to that named event and
then do a SetEvent). That should cause the agent to reintialize using the
current registry values.
Jeff Kelley
Microsoft / Windows CE Networking
The only thing I've found that sounds like what I need is the above quote, though futher research suggests he is talking about C++ or C#. Is there a way to do what he suggests in powershell? I found a New-Event commandlet though I'm unsure of its suitability to the current task. Code I've tried:
$snmpService = New-Event -sourceidentifier dcbScriptSnmpReset -sender SNMPServiceResetEvent -messagedata "Reset SNMP to refresh Registry"
Though there is no Set-Event commandlet and I don't know how to proceed.
Any help or leads would be much appreciated.
Thanks,
Marcus
Apparently I misunderstood how SNMP worked and now I can get it to update values entered into the registry by enabling and disabling the network adapter and stopping and starting the SNMP service:
Stop-Service $snmpService.Name
$adaptor = Get-WmiObject -Class Win32_NetworkAdapter | Where-Object {$_.DeviceID -eq $deviceID }
$adaptor.Disable()
$adaptor.Enable()
Start-Service $snmpService.Name