Const ADS_UF_PASSWD_CANT_CHANGE = &H0040
Set objUser = GetObject("WinNT://atl-ws-01/kenmyer")
If Not objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then
objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE
objUser.Put "userFlags", objPasswordNoChangeFlag
objUser.SetInfo
End If
我們一開始先定義一個常數 (用了一個容易記的名稱 ADS_UF_PASSWD_CANT_CHANGE),我們要用它來識別 userFlags 屬性 (Attribute) 中的適當「開關」。這個 userFlags 屬性 (Attribute) 是一種位元遮罩屬性 (Attribute),是一種含有多項屬性 (Property) 和屬性值 (Property Value) 的單一屬性 (Attribute)。您可以將位元遮罩想像成一排開關,每一個開關代表一種不同的屬性 (Property)。如果代表「使用者不可變更密碼」的開關是開啟狀態,那麼使用者就不能變更他們的密碼;如果這個開關是關閉的,使用者就「可以」變更他們的密碼。這一部份應該是一看就懂了;比較麻煩的是,位元遮罩的「開關」並沒有像「使用者不可變更密碼」這樣的名稱。實際上它們是個十六進位的值,像是 &H0040。為了執行我們的工作,我們需要切換這個 &H0040 開關。這就是我們為什麼要定義這個常數的原因。
接下來,我們連線到電腦 atl-ws-01 上的 kenmyer 帳戶。這時候,我們要檢查看看這個開關是不是已經開啟了。在處理位元遮罩的時候,我們通常會看到類似下面的程式碼:
If objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then
用一般的話來講,這行程式碼就是說「如果 userFlags 屬性 (Attribute) 存在而且 ADS_UF_PASSWD_CANT_CHANGE 開關已經開啟了,表示這個陳述式為真,所以我們應該做某些事情」。在我們的例子中,我們對已經開啟的開關沒什麼興趣;因為如果「不可變更密碼」的旗標已經設定了,表示我們的工作已經完成。我們真正在乎的,是「關閉」的開關。因此,我們用了下面這行程式碼,它只會在開關「沒有」開啟的情況下採取動作:
If Not objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then
接下來,您可能更弄不清楚。仔細看看這行程式碼:
objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE
實際上,如果不看外表,它其實是非常簡單的程式碼。我們在這裡做的,只不過是切換「使用者不可變更密碼」這個開關的數值。也就是 XOR 命令所執行的動作。如果這個開關是開啟的,XOR 會將它切換成關閉;如果它是關閉的,XOR 會將它開啟。我們要利用 userFlags 屬性目前的值,然後切換這個「使用者不可變更密碼」開關。由於我們知道這個開關是關閉狀態 (還記得我們剛才用的是 If Not 陳述式嗎?),所以 XOR 命令一定會將這個開關切換成開啟狀態。因此,變數 objPasswordNoChangeFlag 所包含的數值將會和目前 userFlags 屬性中的值完全相同,只有一個地方不一樣:「使用者不可變更密碼」這個開關現在是開啟狀態,而不是關閉。
聽得懂嗎?指令碼的其他部份都相當簡單。下面這行程式碼會將變數 objPasswordNoChangeFlag 的值寫入 userFlags 屬性:
objUser.Put "userFlags", objPasswordNoChangeFlag
接下來,我們用 SetInfo 命令將這些變更寫入使用者帳戶。一切搞定,本機使用者 Ken Myer 將不再擁有在電腦 atl-ws-01 上變更密碼的權限。
那麼,假如要「允許」Ken Myer 變更密碼又該怎麼做呢?喔...非常簡單。我們只要檢查「使用者不可變更密碼」這個開關是否為「開啟」狀態,然後用 XOR 將它關閉就可以了:
Const ADS_UF_PASSWD_CANT_CHANGE = &H0040
Set objUser = GetObject("WinNT://atl-ws-01/kenmyer")
If objUser.UserFlags AND ADS_UF_PASSWD_CANT_CHANGE Then
objPasswordNoChangeFlag = objUser.UserFlags XOR ADS_UF_PASSWD_CANT_CHANGE
objUser.Put "userFlags", objPasswordNoChangeFlag
objUser.SetInfo
End If
唯一的差異是我們從 If-Then 陳述式中拿掉了 Not 這個字。因為我們現在要找出開關已經開啟的情況,目的是要將它關閉。
的確,這些位元遮罩屬性確實不太容易搞懂。如果您還需要更詳細的資訊 (再加幾張圖片),您不妨試試《Microsoft Windows 2000 指令碼指南》(Microsoft Windows 2000 Scripting Guide) 中的這個部份 (英文)。前面說過,我們以下還要介紹一些可以用 userFlags 屬性 (Attribute) 管理的本機使用者帳戶屬性 (Property)。
屬性 (Property) |
常數 |
數值 |
登入指令碼將會執行 |
ADS_UF_SCRIPT |
&H0001 |
帳戶已停用 |
ADS_UF_ACCOUNTDISABLE |
&H0002 |
帳戶需要主目錄 |
ADS_UF_HOMEDIR_REQUIRED |
&H0008 |
帳戶已鎖定 |
ADS_UF_LOCKOUT |
&H0010 |
帳戶不需要密碼 |
ADS_UF_PASSWD_NOTREQD |
&H0020 |
使用者不可變更密碼 |
ADS_UF_PASSWD_CANT_CHANGE |
&H0040 |
允許加密的文字密碼 |
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |
&H0080 |
密碼永久有效 |
ADS_UF_DONT_EXPIRE_PASSWD |
&H10000 |
登入時需要智慧卡 |
ADS_UF_SMARTCARD_REQUIRED |
&H40000 |
密碼已過期 |
ADS_UF_PASSWORD_EXPIRED |
&H800000 |
在您覺得無聊的時候,不妨將這些數值代入這個「使用者不可變更密碼」指令碼,看看會發生什麼狀況 (當然,就像以前一樣,建議您在實驗這類指令碼的時候,最好能使用測試電腦,最低限度也要用測試帳戶)。
|