最近在製作上傳到Azure的VHD的時候就遇到,需要開一些特定的port。
作爲coder,懶是一種美德,因此當然想要透過使用powershell的方式把整個動作自動化。
Azure官方文件有些範例script可以參考,但是實際使用起來卻有個但書,就是只能在英文版的OS才有作用(畢竟是外國人寫的script),其他語系就gg了。
因爲這個原因,所以去找了一些資料,才發現原來要支援多語系的Windows沒有那麽直覺,因此這邊記錄一下以供未來參考。
攥寫建議做法 TL;DR
- 盡量使用Windows防火墻的規則來開啓port,而不要自己寫
舉例來説,今天要開啓遠端桌面(Remote Desktop)的port (預設是3389),那麽不要自己建立一個規則,而是直接開啓微軟防火墻内建的遠端桌面群組即可。
- 攥寫的時候,請使用内部的"magic string"做設定而不是呈現名稱
可以透過
Get-NetFirewallRule
來查找特定規則的magic string。例如:
可以把所有防火墻的群組顯示名稱及對應的magic string show出來Get-NetFirewallRule | sort -unique Group | sort DisplayGroup | ft DisplayGroup,Group
接下來會對以上建議原因做個説明。
Windows防火墻規則的組成
當把防火墻設定打開的時候(可以透過快速鍵 Windows + R 然後輸入 wf.msc
),可以看到每一條規則是歸屬到某一個群組下面。
因此,當我們要設定的時候,最好是先找到有沒有内建的規則,然後依照名稱去設定啓用或者停用。
用規則名稱或者群組名稱設定有什麽問題?
瞭解到了要使用内建的規則或群組之後,那麽應該怎麽設定呢?
還是以遠端桌面爲例,最常見的規則的script會是:
netsh advfirewall firewall set rule group="Remote Desktop" new enable=yes
這個是一個cmd的指令,可以看到,他把所有在Remote Desktop這個群組的規則全部做一個啓用。
如果今天這個是在一臺英文版本的OS,這個不會有任何問題,但是如果是在非英文語系,例如簡體中文的OS裏面,那麽會出現找不到的錯誤。
爲什麽找不到呢?,看一下非英文版的設定畫面就可以看的出來:
要用内部的id做設定而不是顯示名稱
上面問題很明顯,是因爲用了顯示名稱做定位導致的問題,但是有沒有什麽全語系都通用的值代表同樣群組呢?找了一下,發現了有一組magic string能夠代表。
如何找到要修改的規則名稱或群組的内部ID?
這個時候就要使用到powershell了。
有一個指令,Get-NetFirewallRule
可以用來查找某個規則的裏面id。
還是一樣的例子,這邊要找出Remote Desktop
這個群組的内部ID值,那麽可以使用:
Get-NetFirewallRule -DisplayGroup "Remote Desktop"
這個時候會列出3筆規則(因爲這個群組有3筆),裏面可以看到Group
及Name
這兩個參數,這個就是每個語系都一樣的内部值。
如何使用内部的id值來改設定
其實有了那個内部的值之後,只要把本來群組的Group改成那個值就可以了,以剛剛cmd的範例來説就是變成:
netsh advfirewall firewall set rule group="@FirewallAPI.dll,-28752" new enable=yes
可以注意到,本來的Remote Desktop改成了@FirewallAPI.dll,-28752。
同樣道理可以用在改規則名稱上面。
不過既然已經用了powershell,那麽建議也是使用powershell來修改防火墻,以上面的例子在powershell來説就會是:
Set-NetFirewallRule -Group "@FirewallAPI.dll,-28752" -Enabled true
結語
在這篇介紹了如何在不同語系的Widnows上面用同樣的script來改Windows防火墻的設定。
這其實也告訴我要寫一個哪裏都能夠跑的script其實沒有那麽容易,特別是當從網路上面參考的語法的時候,需要多費點心思考一下或者測試一下,不然很有可能因爲修改不成功導致上傳到Azure的VHD沒有辦法remote desktop進去 造成了很多時間的浪費。