├── .github
├── FUNDING.yml
└── README.md
├── .gitignore
└── BlockFolderWindowsFirewall.ps1
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [asheroto]
2 | ko_fi: asheroto
3 |
--------------------------------------------------------------------------------
/.github/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.powershellgallery.com/packages/BlockFolderWindowsFirewall)
2 | [](https://github.com/asheroto/BlockFolderWindowsFirewall/releases)
3 | [](https://github.com/asheroto/BlockFolderWindowsFirewall/releases)
4 | [](https://github.com/asheroto/BlockFolderWindowsFirewall/releases)
5 |
6 | [](https://github.com/sponsors/asheroto?frequency=one-time&sponsor=asheroto)
7 |
8 |
9 |
10 | # Block Entire Folder in Windows Firewall
11 |
12 | This script provides functionalities to manage (block/unblock) executables (EXEs) in specified directories via Windows Firewall. The operation can be targeted at individual directories or recursively applied to subdirectories as well.
13 |
14 | By default, both Inbound and Outbound connections will be affected, but the scope can be controlled via the -Inbound or -Outbound switches.
15 |
16 | Special care should be taken when using this script due to its potentially broad impact. Blocking EXEs indiscriminately may disrupt applications depending on these executables.
17 |
18 | # Installing
19 |
20 | You can either download the PS1 script from here, or install using...
21 |
22 | ```powershell
23 | Install-Script BlockFolderWindowsFirewall -Force
24 | ```
25 |
26 | Answer **Yes** to any prompts. `-Force` is optional, but it will force the script to update if it is outdated.
27 |
28 | This script is published on [PowerShell Gallery](https://www.powershellgallery.com/packages/BlockFolderWindowsFirewall).
29 |
30 | # Usage
31 |
32 | ```powershell
33 | BlockFolderWindowsFirewall [-Path ] [-Outbound] [-Inbound] [-Recurse] [-UnblockInstead] [-Version] [-Help] [-CheckForUpdate]
34 | ```
35 |
36 | # Parameters
37 |
38 | | Parameter | Required | Description |
39 | | ----------------- | -------- | ---------------------------------------------------------------------- |
40 | | `-Path` | Yes | The folder of EXEs to block/unblock. |
41 | | `-Recurse` | No | Scans the folder and subfolders for EXEs. |
42 | | `-UnblockInstead` | No | Unblocks the EXEs in a folder or subfolder. |
43 | | `-Inbound` | No | Blocks all inbound connections for the EXEs in a folder or subfolder. |
44 | | `-Outbound` | No | Blocks all outbound connections for the EXEs in a folder or subfolder. |
45 | | `-CheckForUpdate` | No | Checks if there is an update available for the script. |
46 | | `-UpdateSelf` | No | Updates the script to the latest version. |
47 | | `-Help` | No | Displays the help message. |
48 | | `-Version` | No | Shows the current version of the script. |
49 |
50 | # Examples
51 |
52 | | Description | Command |
53 | | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
54 | | Block all EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder"` |
55 | | Block all EXEs in a specified folder and its subfolders | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Recurse` |
56 | | Block only the inbound connections for EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Inbound` |
57 | | Block only the outbound connections for EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Outbound` |
58 | | Unblock all EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -UnblockInstead` |
59 | | Unblock all EXEs in a specified folder and its subfolders | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Recurse -UnblockInstead` |
60 | | Unblock only the inbound connections for EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -UnblockInstead -Inbound` |
61 | | Unblock only the outbound connections for EXEs in a specified folder | `BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -UnblockInstead -Outbound` |
62 | | Display help for the script | `BlockFolderWindowsFirewall -Help` |
63 | | Check the current version of the script | `BlockFolderWindowsFirewall -Version` |
64 | | Check if there is an update available for the script | `BlockFolderWindowsFirewall -CheckForUpdate` |
65 |
66 | # Screenshot
67 |
68 | 
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | UPDATE-NOTES
2 | dist/
--------------------------------------------------------------------------------
/BlockFolderWindowsFirewall.ps1:
--------------------------------------------------------------------------------
1 | <#PSScriptInfo
2 |
3 | .VERSION 1.0.2
4 |
5 | .GUID c7a7f36d-3d4f-4e2e-9bec-336ec8a0eb16
6 |
7 | .AUTHOR asherto
8 |
9 | .COMPANYNAME asheroto
10 |
11 | .TAGS PowerShell Windows exe block firewall folder directory recursive
12 |
13 | .PROJECTURI https://github.com/asheroto/BlockFolderWindowsFirewall
14 |
15 | .RELEASENOTES
16 | [Version 0.0.1] - Initial Release.
17 | [Version 0.0.2] - Added recurse option.
18 | [Version 0.0.3] - Updated code signing certificate.
19 | [Version 1.0.0] - Major improvements. Added -Version, -Help, -CheckForUpdate. Added inbound/outbound option (will do both if not specified).
20 | [Version 1.0.1] - Added additional line breaks, changed first line to warning, and added PowerShell gallery info to -CheckForUpdate
21 | [Version 1.0.2] - Added UpdateSelf function, fixed CheckForUpdate function.
22 |
23 | #>
24 |
25 | <#
26 | .SYNOPSIS
27 | Block all EXEs in a specified folder in Windows Firewall.
28 | .DESCRIPTION
29 | This script provides functionalities to manage (block/unblock) executables (EXEs) in specified directories via Windows Firewall. The operation can be targeted at individual directories or recursively applied to subdirectories as well.
30 |
31 | By default, both Inbound and Outbound connections will be affected, but the scope can be controlled via the -Inbound or -Outbound switches.
32 |
33 | Here are key switches to guide the script's behavior:
34 | -Path to specify the target directory.
35 | -Recurse switch will include all subdirectories in the operation.
36 | -UnblockInstead switch changes the operation mode from blocking to unblocking.
37 | -Inbound switch will only affect Inbound connections.
38 | -Outbound switch will only affect Outbound connections.
39 |
40 | Additional utilities include:
41 | -Version switch displays the current version of the script.
42 | -Help switch brings up the help information for the script usage.
43 | -CheckForUpdate switch verifies if the current script version is up-to-date.
44 |
45 | Special care should be taken when using this script due to its potentially broad impact. Blocking EXEs indiscriminately may disrupt applications depending on these executables.
46 |
47 | For detailed examples of usage, refer to the .EXAMPLE section.
48 | .EXAMPLE
49 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder"
50 | This command will block both inbound and outbound traffic for all EXEs in the specified folder.
51 | .EXAMPLE
52 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Recurse
53 | This command will block both inbound and outbound traffic for all EXEs in the specified folder and all its subfolders.
54 | .EXAMPLE
55 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Inbound
56 | This command will block only inbound traffic for all EXEs in the specified folder.
57 | .EXAMPLE
58 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -UnblockInstead
59 | This command will unblock both inbound and outbound traffic for all EXEs in the specified folder.
60 | .EXAMPLE
61 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Recurse -UnblockInstead
62 | This command will unblock both inbound and outbound traffic for all EXEs in the specified folder and all its subfolders.
63 | .EXAMPLE
64 | BlockFolderWindowsFirewall -Path "C:\Folder\Subfolder" -Outbound -UnblockInstead
65 | This command will unblock only outbound traffic for all EXEs in the specified folder.
66 | .PARAMETER Path
67 | The directory path to target for the operation.
68 | .PARAMETER Recurse
69 | Include all subdirectories in the operation.
70 | .PARAMETER UnblockInstead
71 | Change the operation mode from blocking to unblocking.
72 | .PARAMETER Inbound
73 | Only affect Inbound connections.
74 | .PARAMETER Outbound
75 | Only affect Outbound connections.
76 | .PARAMETER CheckForUpdate
77 | Verify if the current script version is up-to-date.
78 | .PARAMETER UpdateSelf
79 | Updates the script to the latest version on PSGallery.
80 | .PARAMETER Version
81 | Display the current version of the script.
82 | .PARAMETER Help
83 | Bring up the help information for the script usage.
84 | .NOTES
85 | Version : 1.0.2
86 | Created by : asheroto
87 | .LINK
88 | Project Site: https://github.com/asheroto/BlockFolderWindowsFirewall
89 | #>
90 |
91 | #Requires -RunAsAdministrator
92 |
93 | [CmdletBinding()]
94 | param (
95 | [String]$Path,
96 | [Switch]$Outbound,
97 | [Switch]$Inbound,
98 | [Switch]$Recurse,
99 | [Switch]$UnblockInstead,
100 | [switch]$CheckForUpdate,
101 | [switch]$UpdateSelf,
102 | [switch]$Version,
103 | [switch]$Help
104 | )
105 |
106 | # Version
107 | $CurrentVersion = '1.0.2'
108 | $RepoOwner = 'asheroto'
109 | $RepoName = 'BlockFolderWindowsFirewall'
110 | $PowerShellGalleryName = 'BlockFolderWindowsFirewall'
111 |
112 | # Display version if -Version is specified
113 | if ($Version.IsPresent) {
114 | $CurrentVersion
115 | exit 0
116 | }
117 |
118 | # Help
119 | if ($Help) {
120 | Get-Help -Name $MyInvocation.MyCommand.Source -Full
121 | exit 0
122 | }
123 |
124 | function Get-GitHubRelease {
125 | <#
126 | .SYNOPSIS
127 | Fetches the latest release information of a GitHub repository.
128 |
129 | .DESCRIPTION
130 | This function uses the GitHub API to get information about the latest release of a specified repository, including its version and the date it was published.
131 |
132 | .PARAMETER Owner
133 | The GitHub username of the repository owner.
134 |
135 | .PARAMETER Repo
136 | The name of the repository.
137 |
138 | .EXAMPLE
139 | Get-GitHubRelease -Owner "asheroto" -Repo "winget-install"
140 | This command retrieves the latest release version and published datetime of the winget-install repository owned by asheroto.
141 | #>
142 | [CmdletBinding()]
143 | param (
144 | [string]$Owner,
145 | [string]$Repo
146 | )
147 | try {
148 | $url = "https://api.github.com/repos/$Owner/$Repo/releases/latest"
149 | $response = Invoke-RestMethod -Uri $url -ErrorAction Stop
150 |
151 | $latestVersion = $response.tag_name
152 | $publishedAt = $response.published_at
153 |
154 | # Convert UTC time string to local time
155 | $UtcDateTime = [DateTime]::Parse($publishedAt, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind)
156 | $PublishedLocalDateTime = $UtcDateTime.ToLocalTime()
157 |
158 | [PSCustomObject]@{
159 | LatestVersion = $latestVersion
160 | PublishedDateTime = $PublishedLocalDateTime
161 | }
162 | } catch {
163 | Write-Error "Unable to check for updates.`nError: $_"
164 | exit 1
165 | }
166 | }
167 |
168 | function CheckForUpdate {
169 | param (
170 | [string]$RepoOwner,
171 | [string]$RepoName,
172 | [version]$CurrentVersion,
173 | [string]$PowerShellGalleryName
174 | )
175 |
176 | $Data = Get-GitHubRelease -Owner $RepoOwner -Repo $RepoName
177 |
178 | Write-Output ""
179 | Write-Output ("Repository: {0,-40}" -f "https://github.com/$RepoOwner/$RepoName")
180 | Write-Output ("Current Version: {0,-40}" -f $CurrentVersion)
181 | Write-Output ("Latest Version: {0,-40}" -f $Data.LatestVersion)
182 | Write-Output ("Published at: {0,-40}" -f $Data.PublishedDateTime)
183 |
184 | if ($Data.LatestVersion -gt $CurrentVersion) {
185 | Write-Output ("Status: {0,-40}" -f "A new version is available.")
186 | Write-Output "`nOptions to update:"
187 | Write-Output "- Download latest release: https://github.com/$RepoOwner/$RepoName/releases"
188 | if ($PowerShellGalleryName) {
189 | Write-Output "- Run: $RepoName -UpdateSelf"
190 | Write-Output "- Run: Install-Script $PowerShellGalleryName -Force"
191 | }
192 | } else {
193 | Write-Output ("Status: {0,-40}" -f "Up to date.")
194 | }
195 | exit 0
196 | }
197 |
198 | function UpdateSelf {
199 | try {
200 | # Get PSGallery version of script
201 | $psGalleryScriptVersion = (Find-Script -Name $PowerShellGalleryName).Version
202 |
203 | # If the current version is less than the PSGallery version, update the script
204 | if ($CurrentVersion -lt $psGalleryScriptVersion) {
205 | Write-Output "Updating script to version $psGalleryScriptVersion..."
206 |
207 | # Install NuGet PackageProvider if not already installed
208 | if (-not (Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) {
209 | Install-PackageProvider -Name "NuGet" -Force
210 | }
211 |
212 | # Trust the PSGallery if not already trusted
213 | $psRepoInstallationPolicy = (Get-PSRepository -Name 'PSGallery').InstallationPolicy
214 | if ($psRepoInstallationPolicy -ne 'Trusted') {
215 | Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted | Out-Null
216 | }
217 |
218 | # Update the script
219 | Install-Script $PowerShellGalleryName -Force
220 |
221 | # If PSGallery was not trusted, reset it to its original state
222 | if ($psRepoInstallationPolicy -ne 'Trusted') {
223 | Set-PSRepository -Name 'PSGallery' -InstallationPolicy $psRepoInstallationPolicy | Out-Null
224 | }
225 |
226 | Write-Output "Script updated to version $psGalleryScriptVersion."
227 | exit 0
228 | } else {
229 | Write-Output "Script is already up to date."
230 | exit 0
231 | }
232 | } catch {
233 | Write-Output "An error occurred: $_"
234 | exit 1
235 | }
236 | }
237 |
238 | function Block-Exe {
239 | param(
240 | [String]$FileName,
241 | [String]$FilePath,
242 | [Switch]$Inbound,
243 | [Switch]$Outbound
244 | )
245 |
246 | If ($Inbound.IsPresent -eq $false -and $Outbound.IsPresent -eq $false) {
247 | Write-Output "Blocking Inbound and Outbound $FilePath..."
248 | New-NetFirewallRule -DisplayName "$FileName" -Direction Inbound -Program $FilePath -Action Block | Out-Null
249 | New-NetFirewallRule -DisplayName "$FileName" -Direction Outbound -Program $FilePath -Action Block | Out-Null
250 | } elseif ($Inbound.IsPresent) {
251 | Write-Output "Blocking Inbound $FilePath..."
252 | New-NetFirewallRule -DisplayName "$FileName" -Direction Inbound -Program $FilePath -Action Block | Out-Null
253 | } elseif ($Outbound.IsPresent) {
254 | Write-Output "Blocking Outbound $FilePath..."
255 | New-NetFirewallRule -DisplayName "$FileName" -Direction Outbound -Program $FilePath -Action Block | Out-Null
256 | }
257 | }
258 |
259 | function Unblock-Exe {
260 | param(
261 | [String]$FilePath,
262 | [Switch]$Inbound,
263 | [Switch]$Outbound
264 | )
265 |
266 | if ($Inbound.IsPresent -eq $false -and $Outbound.IsPresent -eq $false) {
267 | Write-Output "Unblocking Inbound and Outbound $FilePath..."
268 | $matchingRules = Get-NetFirewallApplicationFilter | ? { $_.AppPath -eq "$FilePath" } | % { Get-NetFirewallRule $_.InstanceID }
269 | if ($matchingRules) {
270 | $matchingRules | Remove-NetFirewallRule
271 | } else {
272 | Write-Warning "No matching Inbound and Outbound rules found for $FilePath"
273 | }
274 | } elseif ($Inbound.IsPresent) {
275 | Write-Output "Unblocking Inbound $FilePath..."
276 | $matchingRules = Get-NetFirewallApplicationFilter | ? { $_.AppPath -eq "$FilePath" } | % { Get-NetFirewallRule $_.InstanceID | ? { $_.Direction -eq "Inbound" } }
277 | if ($matchingRules) {
278 | $matchingRules | Remove-NetFirewallRule
279 | } else {
280 | Write-Warning "No matching Inbound rules found for $FilePath"
281 | }
282 | } elseif ($Outbound.IsPresent) {
283 | Write-Output "Unblocking Outbound $FilePath..."
284 | $matchingRules = Get-NetFirewallApplicationFilter | ? { $_.AppPath -eq "$FilePath" } | % { Get-NetFirewallRule $_.InstanceID | ? { $_.Direction -eq "Outbound" } }
285 | if ($matchingRules) {
286 | $matchingRules | Remove-NetFirewallRule
287 | } else {
288 | Write-Warning "No matching Outbound rules found for $FilePath"
289 | }
290 | }
291 | }
292 |
293 | # Update the script if -UpdateSelf is specified
294 | if ($UpdateSelf) { UpdateSelf }
295 |
296 | # Check for updates if -CheckForUpdate is specified
297 | if ($CheckForUpdate) { CheckForUpdate -RepoOwner $RepoOwner -RepoName $RepoName -CurrentVersion $CurrentVersion -PowerShellGalleryName $PowerShellGalleryName }
298 |
299 | # If Path is not set, check if -Version, -Help, or -CheckForUpdate is specified
300 | if ("" -eq $Path) {
301 | if ($Version.IsPresent -or $Help.IsPresent -or $CheckForUpdate.IsPresent) {
302 | # Do nothing
303 | } else {
304 | Write-Error "-Path is required"
305 | exit 1
306 | }
307 | }
308 |
309 | # If -Recurse or -UnblockInstead is specified, -Path is required
310 | if ($Recurse.IsPresent -or $UnblockInstead.IsPresent -or $Outbound.IsPresent -or $Inbound.IsPresent) {
311 | if ("" -eq $Path) {
312 | Write-Error "-Path is required"
313 | exit 1
314 | }
315 | }
316 |
317 | # Confirm folder path exists
318 | if (Test-Path -Path $Path -PathType Container) {
319 | # Update note
320 | Write-Output "`n$RepoName $CurrentVersion"
321 | Write-Output "To check for updates, run $RepoName -CheckForUpdate`n"
322 |
323 | # Folder path exists
324 | Write-Output "Folder exists, continuing...`n"
325 |
326 | # Pause for 10 seconds if the folder is C:\
327 | If ($Path -eq "C:\") {
328 | Write-Output "WARNING: You specified C:\ as the path, this will block all EXEs on the C drive. Press CTRL+C to cancel, or wait 10 seconds to continue..."
329 | Start-Sleep -Seconds 10
330 | }
331 |
332 | # Determine if we're blocking or unblocking
333 | if ($UnblockInstead) {
334 | # Unblocking
335 | if ($Recurse) {
336 | # Recursively unblocking
337 | Write-Output "Recursively unblocking EXEs in $Path..."
338 | Get-ChildItem -Path $Path -Filter "*.exe" -Recurse | ForEach-Object {
339 | $FilePath = $_.FullName
340 | $FileName = Split-Path $FilePath -Leaf
341 | Unblock-Exe -FilePath $FilePath -FileName $FileName -Inbound:$Inbound.IsPresent -Outbound:$Outbound.IsPresent
342 | }
343 | } else {
344 | # Not recursively unblocking
345 | Write-Output "Unblocking EXEs in $Path..."
346 | Get-ChildItem -Path $Path -Filter "*.exe" | ForEach-Object {
347 | $FilePath = $_.FullName
348 | $FileName = Split-Path $FilePath -Leaf
349 | Unblock-Exe -FilePath $FilePath -FileName $FileName -Inbound:$Inbound.IsPresent -Outbound:$Outbound.IsPresent
350 | }
351 | }
352 | } else {
353 | # Blocking
354 | if ($Recurse) {
355 | # Recursively blocking
356 | Write-Output "Recursively blocking EXEs in $Path..."
357 | Get-ChildItem -Path $Path -Filter "*.exe" -Recurse | ForEach-Object {
358 | $FilePath = $_.FullName
359 | $FileName = Split-Path $FilePath -Leaf
360 | Block-Exe -FilePath $FilePath -FileName $FileName -Inbound:$Inbound.IsPresent -Outbound:$Outbound.IsPresent
361 | }
362 | } else {
363 | # Not recursively blocking
364 | Write-Output "Blocking EXEs in $Path..."
365 | Get-ChildItem -Path $Path -Filter "*.exe" | ForEach-Object {
366 | $FilePath = $_.FullName
367 | $FileName = Split-Path $FilePath -Leaf
368 | Block-Exe -FilePath $FilePath -FileName $FileName -Inbound:$Inbound.IsPresent -Outbound:$Outbound.IsPresent
369 | }
370 | }
371 | }
372 |
373 | Write-Output "Done!"
374 | } else {
375 | # Folder path does not exist
376 | Write-Output "Folder does NOT exist, please run script again with a valid path"
377 | }
378 |
379 | Write-Output ""
--------------------------------------------------------------------------------