WS 2016對WS 2016的PSRemoting的Access is denied錯誤
在導入 Docker for Windows 之後,使用 PowerShell 的比重越來越高,而且在 CD(持續發布)的過程,也相當依賴 PowerShell 來進行作業。平常,可以透過 Docker CLI 來直接對 Docker Host 來下達指令(docker -H host command
)。但今天如果是要直接對 Windows Server 下達 PowerShell 指令,也就是,我在 A 電腦直接透過指令視窗對 B 電腦下 PowerShell 指令,而非使用遠端桌面,那麼可以使用 PSRemoting。
PSRemoting
PowerShell 要讓其他電腦可以連線下達指令的功能稱 PSRemoting,一般而言,在接收指令的主機執行 Enable-PSRemoting
之後,在下指令的電腦就可以用 Enter-PSSession -Computer computerName -Credential $cred
來進行連線。(其他 Firewall、User Group 設定細節,請參考微軟文件。)
WS2016 ⇆ WS2016 PSRemoting 無法連線
在啟用與測試的過程,我們發現一個好玩的現象,Windows 10、Windows Server 2012、Windows Server 2016 互相進行 PSRemoting 連線時,特定的 WS2016 → WS2016 無法互連,方向只有單方,例如,兩台都已經 Enable-PSRemoting
的 WS2016 主機,A → PSRemoting → B 正常,但 B → PSRemoting → A 無法連線。
Get-PSSession : The remote session query failed for hostname with the following error message: Access is denied.
At line:1 char:1
+ Get-PSSession -ComputerName hostname
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Manageme...nConnectionInfo:WSManConnectionInfo) [Get-PSSession], RuntimeException
+ FullyQualifiedErrorId : AccessDenied,RemotePSSessionQueryFailed,Microsoft.PowerShell.Commands.GetPSSessionCommand
微軟官方有一篇 About Remote Troubleshooting 寫的算是詳細(另有一篇 如何執行遠端 PowerShell Script 也寫的不錯),不過,用盡網路上找得到的方式,還是解不了是 B to A 無法連線的問題。由於關係到工作,最後選擇開 Microsoft Support Case 請求幫助。
Microsoft Support
以下記錄一下尋找問題點的步驟與工具:
- 使用 WebEx 連線,查明問題點。
用以連入公司內網,驗證兩台主機的 PSRemoting 的問題。
- 使用 Network Monitor 3.4 取得封包資訊
A to B 當然不會有問題。B to A 看不到正常身份驗證的封包。
- 使用 logman 取得 Trace 資訊
第一次取得:
- ds_security.etl
- net_netio.etl
第二次取得:
- admin_wmi.etl
- 使用 Process Monitor 取得事件日誌
取得 PSRemoting 事件發生當下的資訊。
- TTTracer 取得 PID dump file
用來取得 PowerShell 的 PID 的 dump 資訊。
生也 Proxy、死也 Proxy
最後由 Process Monitor 找到的 B to A 的 PowerShell 在進行 PSRemoting 當下會先進行 Proxy 連線,而 A to B 則沒有。
這是 B 主機虛擬資訊:
PS C:\> netsh winhttp show proxy
Current WinHTTP proxy settings:
Proxy Server(s) : proxy.example.com:80
Bypass List :
A 主機虛擬資訊:
PS C:\> netsh winhttp show proxy
Current WinHTTP proxy settings:
Direct access (no proxy server).
趕快找一台有問題 WS2016 的 C 主機:
PS C:\> netsh winhttp show proxy
Current WinHTTP proxy settings:
Proxy Server(s) : proxy.example.com:80
Bypass List : *.example.com
這台 C 主機的設定與 B 主機有一點點差異,多了 Bypass,如果以短名稱進行 PSRemoting 就會取得 Access is denied 錯誤。如改為**完整網域名稱(FQDN)**進行連線,因為符合 Bypass 名稱就不會跑到 Proxy,就能完成正常的 PSRemoting 連線。
- 在 Proxy 環境,要設定 Bypass List。
- 連線需使用 FQDN。
- 這個情況只有在 WS2016 ⇆ ws2016 會出現。
看似簡單的問題,由於不良的錯誤的訊息及難以得知 PowerShell 底層處理細節(PowerShell Core 有開源,但 PowerShell 沒有),追起來費工費時,還在最後在神器 Process Monitor 幫助下,查了近二個月的案子終於可以結案了。
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。