已編寫指令碼的規則
在這個部分中:
關於已編寫指令碼的規則
已編寫指令碼規則可讓您使用 Windows PowerShell 或 VB 指令碼建立自訂規則。指令碼的成功或失敗可決定屬於規則一部分的安全性層級、「允許的項目」和「拒絕的項目」是否適用於使用者。
已編寫指令碼規則會利用可透過 PowerShell 或 VBScript 存取的任何介面,例如 COM (元件物件模型),在以下情況中會評估每個指令碼:
- 當電腦部署新組態時。
- 當使用者登入時。
您可以在「已編寫指令碼規則」對話方塊中建立及編輯指令碼,存取方式如下:
- 在「規則」功能區中,選取新增規則。
-
在下拉式功能表中,選取已編寫指令碼規則。
「已編寫指令碼規則」工作區域隨即顯示。
您可以定義何時可使用下列「已編寫指令碼規則」選項執行指令瑪:
- 每次以使用者身分登入工作階段時執行一次指令碼 - 每次使用者登入時執行指令碼。僅在使用者工作階段期間套用的設定。請注意,如果桌面已經解除鎖定,指令碼也將會執行。
- 每次系統使用者登入工作階段時執行一次指令碼 - 每次使用者登入時以系統帳戶權限執行指令碼。僅對於使用者工作階段的持續時間套用設定。
-
每次系統使用者啟動電腦時執行一次指令碼 - 每次電腦啟動時以系統帳戶權限執行指令碼。設定會套用至所有使用者工作階段直到電腦重新啟動為止,應用程式控制 代理程式會重新啟動或發生組態變更。
警告: 以系統使用者身分執行指令碼,可能會造成您的電腦受到嚴重損害,因此應僅由有經驗的指令碼作者啟用。
-
在使用者登入完成之前不執行指令碼 - 選取此選項以避免使用者在登入完成之前執行指令碼。
-
指令碼逾時前等候 <n> 秒 - 可讓您指定指令碼逾時前可繼續執行的秒數。設定為零 (0) 秒可避免指令碼逾時。若發生逾時則表示結果失敗且無法套用設定。
VBScripts
每個指令碼都是在託管指令碼引擎中執行,能更有效地控制整個指令碼執行,同時提供更高等級的輸入和輸出控制。
- 未使用 VBS 檔案。
- 不會衍生個別的處理序。
指令碼必須以函數寫入,並可包含許多函數,但必須指定主要開始函數。開始函數會由 應用程式控制 代理程式執行並可用來呼叫其他函數。
AMScriptRule COM 物件會內建於指令碼引擎並提供以下方式的存取權限:
strUsername = AMScriptRule.UserName
strUserdomain = AMScriptRule.UserDomain
strSessionid = AMScriptRule.SessionID
-
strStationname = AMScriptRule.WinStation
此實例中的 Microsoft 標準表示 WinStation 會傳回「終端服務工作階段」的名稱值,這是由工作階段類型 (通常為 ’Console’ 或 ’RDP-Tcp#34’ 值) 而非「視窗工作站」名稱 (通常為 WinSta0) 所決定。
AMScriptRule COM 物件還包括下列方法:
-
strLog = AMScriptRule.Log "My Log Statement"
可讓您將記錄字串輸出至代理程式記錄檔案,以搭配偵錯已編寫指令碼規則使用。
-
strEnvironmentvar = AMScriptRule.ExpandEnvironment ("%MyEnvironmentVariables%")
展開執行指令碼的使用者環境變數。
使用 WScript. shell 來展開環境變數以僅傳回 SYSTEM 變數。
Windows PowerShell 指令碼
如果指令碼傳回 (離開) 的值為 0,指令碼將會通過並套用規則。若傳回任何非零值,指令碼將會失敗且不套用規則。
每個 PowerShell 指令碼都會在 PowerShell.exe 的實例中執行,且 應用程式控制 不會強制或新增任何特定語法 – 所有格式正確的 PowerShell 皆正常運作。
PowerShell 會安裝在任何將使用指令碼的端點上。
新增已編寫指令碼的規則
-
按一下「規則」功能區上的新增規則下拉式箭頭,並選取已編寫指令碼規則。
隨即會將新規則新增至「所有已編寫指令碼規則」工作區域。已編寫指令碼的規則對話方塊隨即顯示。
- 若要輸入指令碼,請執行以下其中一項動作:
- 在「目前指令碼」區域內輸入指令碼。
- 在指令碼編輯器內開啟現有指令碼並複製/剪下內容,然後貼上。
- 選取按一下這裡可編輯指令碼。按一下匯入以匯入現有指令碼。
編輯已編寫指令碼規則
- 使用「已編寫指令碼規則」對話方塊,可依據使用者登入時執行的自訂 VB 和 PowerShell 指令碼來建立和維護規則。
- 若要為特定規則開啟「已編寫指令碼規則」對話方塊,您可以:
- 導覽至導覽窗格內的已編寫指令碼規則並選擇它。
在導覽樹狀目錄中選取規則節點。在「所有規則」對話方塊中,按兩下您想編輯的規則。
「已編寫指令碼的規則」對話方塊隨即顯示。
-
按一下按一下這裡可編輯指令碼。
「設定此已編寫指令碼規則」對話方塊隨即顯示。
- 在「指令碼」索引標籤中,新增或修改當使用者登入時所使用的指令碼。
- 在「選項」索引標籤中,於「定義執行設定」區段的可用選項清單中選取指令碼執行設定。
- 若要指定指令碼時間設定,請在「定義指令碼時間設定」區段中選取適當的選項。
- 按一下確定。
範例指令碼
以下 VBscript 將示範如何控制使用者可存取的應用程式。
Function ScriptedRule()
’預定要傳回的篩選器掃描名稱
ExpectedFilter = "FWALL"
’取得伺服器名稱
Set objNTinfo = CreateObject ("WinNTSystemInfo")
ServerName = lcase (objNTInfo.ComputerName)
’設定初始傳回值
ScriptedRule = False
’建立 MetaFrame 工作階段物件
Set MFSession = Createobject ("MetaFrameCOM.MetaFrameSession")
’初始化此工作階段的工作階段篩選器
對於 MFSession.SmartAccessFilters 中的每個 x
’若找到了我們的篩選器,則傳回 true
If x = ExpectedFilter Then
ScriptedRule=True
AMScriptRule.Log "SmartAccessFilter match found."
End If
下一步
結束功能
以下 VBscript 可用來判斷電腦是否位於「電腦組織單位」:
Function ScriptedRule()
ScriptedRule = vbFalse
strCompName = AMScriptRule.StationName
Set oRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = oRootDSE.Get("DefaultNamingContext")
Set oOU = GetObject("LDAP://OU=TheOUyouAreSearching,OU=Parent,OU=Parent," & strDNSDomain)
oOU.GetInfo
對於 oOU 中的每個成員
If UCase(strCompName) = UCase(member.CN) Then
ScriptedRule = vbTrue
退出
End If
下一步
結束功能
以下範例 VBScript 會顯示指令碼的主要元件,並示範如何存取與系統登入使用者之使用者名稱有關的資訊,同時比對特定網域與組織單位:
Function MyScript()
'取得使用者登入的使用者名稱 (亦適用於以 SYSTEM 身分執行)
strUserName = AMScriptRule.UserName
'取得使用者登入的網域 (亦適用於以 SYSTEM 身分執行)
strUserDomain = AMScriptRule.UserDomain
'查詢使用者環境變數 (以 SYSTEM 身分執行時,只能使用 SYSTEM 變數)
strClientName = AMScriptRule.ExpandEnvironment ("%ClientName%")
'記錄輸出
AMScriptRule.Log strUserName & " logged in on " & strClientName
'檢查使用者是否為網域的成員
If strUserdomain = "MyDomain" Then
'若是,查看該使用者是否存在於 MyOU OU 中
Set objOU = GetObject ("LDAP://ou=MyOU,dc=MyDomain,dc=com")
objOU.Filter = Array("user")
對於 objOU 中的每個 objUser
'檢查是否符合登入中的使用者
If objUser.sAMAccountName = strUserName Then
'如果有,則將函數設定為 True
MyScript = True
End If
下一步
End If
'除非有符合的使用者名稱,否則函數預設為 False
結束功能
以下範例 Windows PowerShell 指令碼會顯示指令碼的主要元件,並示範如何存取與系統登入使用者之使用者名稱有關的資訊,同時比對特定網域與組織單位:
#Script 檢查目前使用者是否為指定的 OU 成員
# Return 0 if TRUE
# 1 otherwise
$logonuser = $env:username
$bindpt = [adsi] "LDAP://OU=TS_Users,OU=Users,OU=MyUser,OU=MyOU,DC=MyDomain,DC=com"
$users = New-Object System.DirectoryServices.DirectorySearcher $bindpt
$users.Filter = "(&(objectClass=User)(sAMAccountName=$logonuser))"
$obj = $users.FindOne()
if($obj -eq $null)
{
#" Not a Member"
exit 1
}