支援管理 Windows Defender 應用程式控制 (WDAC) 強制執行基礎結構的擴充功能

適用於:Windows Admin Center、Windows Admin Center 預覽版

Windows Admin Center 支援在平台層級管理 Windows Defender 應用程式控制 (WDAC) 強制執行基礎結構。 進一步了解在 Windows Admin Center 中管理 WDAC 強制執行基礎結構

支援在平台層級管理 WDAC 強制執行基礎結構,並不表示針對 Windows Admin Center 建置的擴充功能也預設支援這項管理。 本指南概述擴充功能支援管理 WDAC 強制執行基礎結構的需求。

擴充功能結構需求

為管理 WDAC 強制執行基礎結構,Windows Admin Center 必須以特定方式內嵌並執行 PowerShell 指令碼,以遵循最佳安全作法。 為確保擴充功能的指令碼正確執行,請確定您的擴充功能符合下列需求。

所有 PowerShell 指令碼都必須儲存在檔案中

在過去,WAC 擴充功能的開發人員可能會選擇將自訂 PowerShell 程式碼作為字串包含在擴充功能的 manifest.json 檔案中。 例如,您可以選擇在「script」屬性中提供 PowerShell 指令碼,以定義工具擴充功能可見度的條件。 為使 PowerShell 指令碼與 WDAC 相容,必須予以簽署。 無法對字串進行簽署。

為確保符合此需求,請遵循下列步驟:

  1. 識別 manifest.json 檔案中的所有 PowerShell 指令碼。
  2. 在 manifest.json 檔案中定義任何指令碼內容之後,請移除該指令碼內容,並將其儲存在擴充功能的 resources/scripts 目錄的 .ps1 檔案中。 擴充功能資訊清單中的指令碼現在會遵循與其他 Windows Admin Center PowerShell 相同的規則。
  3. 將擴充功能資訊清單中的條件屬性更新為下列格式:
    "conditions": [
        {
            "powerShell": {
                "command": "Script-File-Name",
                "module": "powerShellModuleName",
                "script": "Your script text goes here."
            }
        }
    ]
    
    PowerShell 模組名稱已存在於擴充功能資訊清單中。 該模組在資訊清單中的值和在 PowerShell 欄位中的值必須相符。
  4. 識別動態建立 PowerShell 指令碼的任何其他位置。 使用字串串連動態建立 PowerShell 指令碼,允許攻擊者插入要執行的任意 PowerShell 指令碼。 這個方法可用來略過對使用限制執行空間的遠端使用者所強制執行的限制。 它還可用來為使用使用者輸入建置 PowerShell 指令碼並予以執行的任何應用程式,達成標準命令插入。

使用字串串連建立的指令碼區塊範例:

param($UserInputVar)
$DynamicScript = "Get-ChildItem $UserInputVar"
$ScriptBlock = [ScriptBlock]::Create($DynamicScript)
Invoke-Command $ScriptBlock

未使用字串串連建構的相同指令碼區塊範例:

param($UserInputVar)
 [ScriptBlock]$ScriptBlock = {
Param($SafeUserInput)
Get-ChildItem $ SafeUserInput
 }
 Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList @($UserInputVar)

# OR, alternatively
param($UserInputVar)
 Invoke-Command -ScriptBlock {
 param(
    [String] $SafeUserInput
 )
Get-ChildItem $SafeUserInput

} -ArgumentList $UserInputVar

指令檔也不應該使用字串串連來建構。 以下是如何不建構指令檔的範例:

$Script=@'
    Get-ChildItem $UserInputVar
'@
$Script = '$ UserInputVar =' + "'$ UserInputVar;"+$Script 
$path = “C:\temp”
$Script | Out-File $path

請改為像以下這樣建構指令檔:

Function test {
    param(
        [String] $userInputVar
     )
    Get-ChildItem $UserInputVar
    }
   
    $path = “C:\temp”
    (Get-Command test).ScriptBlock | Set-Content -path $path

所有 PowerShell 程式碼都必須進行簽署,並儲存在適當的位置

在為支援管理 WDAC 強制執行基礎結構所進行的 Windows Admin Center 變更中,擴充功能的已簽署 PowerShell 指令碼現在會在執行前傳輸到 Windows Admin Center 目前所連線的節點。 此外,如先前需求所述,WDAC 強制執行基礎結構僅執行已簽署的 PowerShell 指令碼。 由於這些需求,所有 PowerShell 程式碼都必須進行簽署。 所有 PowerShell 也必須位於一致的位置,Windows Admin Center 平台才可以如預期找到擴充功能的已簽署模組。

如果擴充功能存放庫未包含具有已簽署 PowerShell 模組的 powershell-module 目錄,Windows Admin Center 平台將無法識別可傳輸的程式碼,且在強制執行 WDAC 的環境中作業將會失敗。

Windows Admin Center gulp build 命令會更新存放庫內的 /dist 資料夾,並在模組資料夾內產生未簽署的 .psd1 和 .psm1 檔案。 這些檔案必須使用符合 WDAC 原則中允許列出的簽署憑證進行簽署。

若要進行這項變更,強烈建議您建立一個包含 PowerShell 簽署的組建管線。

您可以透過下列其中一種方式來驗證 PowerShell 採用正確的格式:

  1. 若已安裝擴充功能,您可以在閘道機器 (Windows Admin Center 執行所在的機器) 上檢視 ProgramData\Server Management Experience\UX\modules 目錄。 您應該會在這裡看到 powershell-module 資料夾和已簽署的 PowerShell 模組
  2. 擷取擴充功能的 .nupkg 成品的內容。 powershell-module 資料夾應該存在,且包含已簽署的 PowerShell 模組。

在這兩種情況下,可以透過對檔案執行 Get-AuthenticodeSignature 命令,或以滑鼠右鍵按一下檔案本身並驗證數位簽章,來驗證 .psd1 和 .psm1 檔案本身已進行簽署。

使用「powerShellScript」屬性的 WorkItem 應該更新為使用「powerShellCommand」屬性

Windows Admin Center 平台必須能夠判斷 PowerShell 命令所屬的模組。 由於這項需求,使用 powerShellScript 屬性指定 PowerShell 命令的 WorkItem 會造成錯誤。

若要減少此錯誤,請使用 powerShellCommand 屬性以及 createCommand 方法,以組成有效的命令物件。

以下是使用舊方法的 WorkItem 範例:

    const workItem : WorkItemSubmitRequest = {
      typeId: "SampleWorkItem",
      title: "Title",
      powerShellScript: PowerShellScripts.[scriptName],
      successMessage: "Success",
      errorMessage: "Error",
      progressMessage: "In progress..."
    }

以下是使用新方法的相同 WorkItem:

    const workItem : WorkItemSubmitRequest = {
      typeId: "SampleWorkItem",
      title: "Title",
      powerShellCommand: PowerShell.createCommand(PowerShellScripts.[scriptName]),
      successMessage: "Success",
      errorMessage: "Error",
      progressMessage: "In progress..."
    }

確保 PowerShell 指令碼以限制語言模式執行

許多 WDAC 原則會強制所有 PowerShell 指令碼以限制語言模式執行。 為在整個 Windows Admin Center 中維護完整功能,您應該確保擴充功能中的所有指令碼都遵循以下最佳作法:

  1. 如果是使用 PowerShell 模組匯出指令檔,則必須按名稱 (不要使用萬用字元) 明確匯出函式。 這項需求是為了防止無意間公開可能不打算公開使用的協助程式函式。
  2. 對指令檔執行點溯源會將來自該指令碼的所有函式、變數、別名帶入目前的範圍。 這項功能可阻止受信任的指令碼被點溯源到不信任的指令碼中,並公開其所有內部函式。 同樣地,該功能可以防止不信任的指令碼被點溯源到受信任的指令碼中,以免侵害受信任的範圍。
  3. 建議您避免使用 Start-Job 命令來執行指令碼區塊,除非該指令碼區塊在限制語言模式中已可順利執行。

對於無法支援 WDAC 強制基礎結構管理的建議錯誤處理

如果您不打算支援在強制執行 WDAC 的機器上執行擴充功能,建議您新增 UI,以說明您的擴充功能中不支援管理 WDAC 強制執行基礎結構案例,以避免使用者混淆。 建議使用類似現有 Azure 混合式服務頁面的版面配置,該版面配置具有以擴充功能 iFrame 為中心的擴充功能圖示和文字。

對於此頁面上的文字內容,我們建議使用以下措辭:

「目前不支援在強制執行 Windows Defender 應用程式控制 (WDAC) 的機器上執行此擴充功能。」

此為建議文字。 如果您不確定想要使用的措辭,請傳送電子郵件給 Windows Admin Center 小組:wacextensionrequests@microsoft.com。

從擴充功能偵測 WDAC 強制執行

若要按照上一節中的指引進行操作,您必須判斷所連接的節點是否已強制執行 WDAC。 Windows Admin Center 公開一種名為 getPsLanguageMode 的方法,該方法定義為 Windows Admin Center 的 WDAC 作業的一部分,用來判斷 WDAC 強制執行。

此方法有兩種輸出:

  • Status – HTTPStatusCode 類型
  • psLanguageMode – PsLanguageMode 類型 (enum)

如果 PowerShell 是以限制語言模式執行 (對應於 psLanguageMode 值 3),則您可以考慮強制執行 WDAC。

下列 TypeScript 範例程式碼提供如何使用此方法的範例:

import { Component, OnInit } from '@angular/core';
import { AppContextService } from '@microsoft/windows-admin-center-sdk/angular';
import { WdacOperations } from '@microsoft/windows-admin-center-sdk/core';
import { PSLanguageMode, PsLanguageModeResult } from '@microsoft/windows-admin-center-sdk/core/data/wdac-operations';

@Component({
  selector: 'default-component',
  templateUrl: './default.component.html',
  styleUrls: ['./default.component.css']
})
export class DefaultComponent implements OnInit {
wdacEnforced: boolean;

  constructor(private appContextService: AppContextService) {
    //
  }

  public ngOnInit(): void {

  }

  public checkWDACEnforced(): void {
    const wdacOperations = new WdacOperations(this.appContextService);
    wdacOperations.getPsLanguageMode(this.appContextService.activeConnection.nodeName).subscribe(
      (response: PsLanguageModeResult) => {
          if (response.psLanguageMode.toString() === PSLanguageMode[PSLanguageMode.ConstrainedLanguage]) {
            this.wdacEnforced = true;
          }
          else {
            this.wdacEnforced = false;
          }
      }
    );
  }
}

在 WDAC 強制執行基礎結構上測試擴充功能

進一步了解 Windows Admin Center 的 Windows Defender 應用程式控制原則需求,以開始在 WDAC 強制執行基礎結構上測試您的擴充功能。