The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

移動服務所需的檔案時應連帶複製完整的 NTFS ACLs 資訊

在幾年前曾經有一次因為擅自移動了 Hyper-V 裡所有的 VM 設定檔與 VHD 虛擬硬碟到另一顆硬碟,結果導致 Hyper-V 無法正常開啟該虛擬機,後來發現原來是檔案的 NTFS 相關資訊沒有複製過去的關係而導致 Hyper-V 的權限不足以致於無法正確開啟 VM 執行。前幾天又遇到了類似的情況,我為了將 SQL Server 完整的系統檔案、紀錄、系統資料庫與使用者資料庫都完整的移至另一台硬碟,這次就知道要小心複製這些檔案,以免又因為權限不足而導致 SQL Server 無法開啟。

重要觀念參考注意 Windows 對於檔案複製與搬移的 NTFS 權限變化 [重要]

這次我選擇用 Windows Server 2008 內建的 robocopy 工具來複製該硬碟內所有的檔案到另一台,由於 robocopy 在複製目錄的時候可以設定「複製選項」,如下圖示,你可以設定除了複製 資料 (D) 、屬性 (A) 與 時間戳記 (T) 之外,還能額外的複製 NTFS ACL 安全性 (S)、擁有者資訊 (O) 與 稽核資訊 (U),透過完整的選項設定,你將能夠複製最完整的檔案到另一台硬碟。

預設的情況下,複製目錄時並不會保留「目錄時間戳記」,所以複製完後所有目錄的時間都會被改成複製當時的時間,如果你連目錄的更新時間都要保留的話,建議也加上 /DCOPY:T  選項。

假設我們想從 D:\ 複製到 E:\ 的話,那麼你可以使用以下指令進行複製:

robocopy D:\ E:\ /E /COPY:DATSOU /DCOPY:T /XD "System Volume Information"

以上語法也可以將 /COPY:DATSOU 簡寫成 /COPYALL

robocopy D:\ E:\ /E /COPYALL /DCOPY:T /XD "System Volume Information"

從上述指令你可以發現,為了複製完整的磁碟檔案與目錄,我加上了 /E 參數,如此一來便能複製所有的子目錄,而且還包括空的子目錄。

另一個選項則是排除一個無法複製的 System Volume Information 系統目錄,這個目錄為系統隱藏目錄,但是 robocopy 看的見,因此最好設定為排除目錄,以免複製檔案目錄的過程中發生錯誤。

不過,這樣複製檔案與目錄會遇到一個問題,那就是第一層的目錄並不會複製其 NTFS 安全性過去,因此必須要想辦法同步兩個磁碟根目錄的安全性設定,這樣才能做到完全一樣的磁碟,這時我透過 icals 指令的幫助,省去手動設定時可能會發生手誤的機會。

利用 icals 指令來複製安全性,主要有 2 個步驟,分別為:

  1. 先儲存來源目錄的 ACL 資訊
  2. 再還原 ACL 資訊到目的目錄

我先以複製特定目錄的例子來說明,假設我有一個目錄為 c:\tmp\111,這時我可以輸入以下指令儲存該目錄的 ACL 資訊,並儲存成 AclFile.txt 檔:

icacls c:\tmp\111 /save AclFile.txt

這時的 AclFile.txt 檔案為如下的格式,第一行為「目錄名稱」

這時我們直接還原這個目錄的 ACL 資訊到目的目錄,假設為 D:\tmp\111 這個目錄,其指令如下:

icacls d:\tmp /restore AclFile.txt

請注意:我們這裡輸入的路徑為 d:\tmp 而已,因為 111 這個目錄名稱已經記錄在檔案中,套用時會串接套用指定的目錄與 AclFile.txt 中的目錄名稱:

這樣即可將目錄的 ACL 安全性資訊給設定完成!

不過,這樣的套用技巧並不適用於磁碟機根目錄 ( 例如: D:\ ) 的權限套用!

如果要透過 icacls 指令來套用,會由兩個步驟增加到三個步驟,以下為詳細圖文解說:

1. 儲存來源目錄的 ACL 資訊 ( 假設我們儲存 C:\ 根目錄的 ACL 安全性資訊 )

icacls c:\ /save AclFile.txt

2. 開啟 AclFile.txt 修正第一行的結果

由於透過 icacls 指令儲存「磁碟機根目錄」的時候,第一行並不會有路徑名稱,這個問題會導致在第三步還原時發生處理失敗的情況。

以下是直接執行還原時發生錯誤的情況:

因此,我們必須手動修改該檔案,在第一行的地方加上路徑,也就是一個反斜線 ( \ ) 符號:

3. 還原 ACL 資訊到目的磁碟

有了第二個步驟的修正,就可以正常還原 ACL 權限到磁碟根目錄了:

相關連結