The following script, saved as “User_Provision.hta” (make sure you don’t get a .txt extension after that) will create an HTML Application (HTA)—a GUI tool—that will provision a user.
The script was designed to demonstrate how easy it is to enforce business logic during the creation and modification of objects in Active Directory.
You will need to change values in the CONFIGURATION BLOCK to match your environment. You may also need to change the ‘logic’ for how names are built—for example, the HTA generates a display name in the Last, First format to make searching the global address list (GAL) easier, but the common name remains First Last because having commas in common names is a bad practice.
Details about this script, and many others like it, can be found in the Windows Administration Resource Kit.
* NOTE THIS IS AN UPDATE (bug fix) TO THE SCRIPT IN THE BOOK *
<html>
<head>
<!--
Created with SAPIEN Technologies PrimalScript 2007
NAME: User_Provision.hta
AUTHOR: Dan Holme, Intelliem
DATE : 12/16/2007
Provisions a user account, demonstrating business logic in the
determination of name properties
Neither Microsoft nor Intelliem guarantee the performance
of scripts, scripting examples or tools.
See www.intelliem.com/resourcekit for updates to this script
(c) 2007 Intelliem, Inc
-->
<title>Provision a user</title>
<HTA:APPLICATION
ID="oHTA"/>
<!-- Note this HTA can be called from a command line
HTANAME.hta ObjectName
Where
HTANAME.hta is the filename of this HTA
ObjectName is
the Pre-Windows 2000 Logon Name, DN or ADsPath
of an object -->
<style>
body, tr, td, table, p, input {font-family: arial; font-size: 9pt;}
.trodd {background-color: #cccccc;}
.treven {background-color: #ffffff;}
.tdlabel {width: 30%}
.tdvalue {width: 70%}
.StatusInfo {font-color: black; font-size: 80%; margin: 3 3 3 3;}
.StatusError {font-color: black; font-size: 80%; background-color: #FF9999; margin: 3 3 3 3;}
.Instructions {font-color: black; font-size: 80%; background-color: #EEEEEE;}
</style>
<script language="vbscript">
Option Explicit
Dim sDomainDNS, sDomainNetBIOS, sDomainDN
Dim iPasswordLength, sUPNSuffix
Dim sSAM, sUPN, sCN, sDisplay, sUser
Dim sFirst, sInit, sMiddle, sLast
Dim sDescription, sTargetOU
Dim sProfileNamespace, sProfilePath
' ============================================================================
' CONFIGURATION BLOCK
sDomainDNS = "contoso.com"
sDomainDN = "dc=contoso,dc=com"
sDomainNetBIOS = "CONTOSO"
sUPNSuffix = "contoso.com"
sProfileNamespace = "\\contoso.com\users\%username%\profile"
iPasswordLength = 15
' ============================================================================
Sub MainRoutine()
Dim oUser, oTargetOU
' clear out any existing text in the status area
divStatus.innerText = ""
Call Arguments()
Call BusinessLogic()
If Not Validate() Then Exit Sub
' Connect to OU
Set oTargetOU = GetObject("LDAP://" & sTargetOU)
' Create user and properties
Set oUser = oTargetOU.Create("user","cn=" & sCN)
WriteProperty oUser,"userPrincipalName", sUPN
WriteProperty oUser,"sAMAccountName", sSAM
WriteProperty oUser,"givenName", sFirst
WriteProperty oUser,"initials", sInit
WriteProperty oUser,"middleName", sMiddle
WriteProperty oUser,"sn", sLast
WriteProperty oUser,"description", sDescription
WriteProperty oUser,"displayName", sDisplay
WriteProperty oUser,"profilePath", sProfilePath
oUser.SetInfo
' Generate random password
Dim sTempPassword, iCase, i
' Start with an upper, a lower, and a numeric character
' to ensure complexity requirements are met
sTempPassword = RandomLetter(1)
sTempPassword = RandomLetter(2)
sTempPassword = RandomLetter(3)
' Now fill the remaining length with random characters
For i=1 To iPasswordLength - 3
randomize()
iCase = int(3*rnd())
sTempPassword = sTempPassword & RandomLetter(iCase)
Next
oUser.SetPassword sTempPassword
' Enable account
oUser.AccountDisabled = False
oUser.SetInfo
divStatus.innerText = "User " & sCN & " created."
End Sub
Sub Arguments()
sFirst = txtFirstName.value
sInit = txtInitial.value
sMiddle = txtMiddleName.value
sLast = txtLastName.value
sSAM = txtSAMAccountName.value
sDescription = txtDescription.value
sTargetOU = cboTargetOU.value
End Sub
Sub BusinessLogic()
Call CalculateNames()
sProfilePath = Replace(sProfileNamespace, "%username%", sSAM)
End Sub
Sub CalculateNames()
Dim sName, sNamePart
' COMMON NAME
sName = ""
sNamePart = txtFirstName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
sNamePart = txtMiddleName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
sNamePart = txtLastName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
' Trim off the last space
sName = Trim(sName)
txtCommonName.value = sName
sCN = sName
' DISPLAY NAME
sName = ""
sNamePart = txtLastName.value
If sNamePart > "" Then sName = sName & sNamePart
If txtFirstName.Value > "" Or txtMiddleName.Value > "" Then
sName = sName & ", "
End If
sNamePart = txtFirstName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
sNamePart = txtMiddleName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
' Trim off the last space
sName = Trim(sName)
txtDisplayName.value = sName
sDisplay = sName
' USER PRINCIPAL NAME (email: first.middle.last)
sName = ""
sNamePart = txtFirstName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
sNamePart = txtMiddleName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
sNamePart = txtLastName.value
If sNamePart > "" Then sName = sName & sNamePart & " "
' Trim off the last space
sName = Trim(sName)
' Replace spaces with periods
sName = Replace(sName, " ", ".")
' Add UPN suffix
sName = sName & "@" & sUPNSuffix
txtUPN.value = sName
sUPN = sName
End Sub
Function Validate()
If (sUPN="") Or (sSAM="") Or (sCN="") Or (sDisplay="") Or (sTargetOU="") Then
divStatus.innerText = "Required arguments are missing."
Validate = False
Else
Validate = True
End If
End Function
Sub WriteProperty(oDirectoryEntry, sPropertyName, sPropertyValue)
If sPropertyValue>"" then
oDirectoryEntry.Put sPropertyName,sPropertyValue
End If
End Sub
Function RandomLetter(iCase)
' Returns a random letter or number
' icase = 0 (UPPER), 1 (lower) or 2 (numeric)
Dim iMax, iMin
randomize()
Select Case iCase
Case 0
iMin=65
iMax=26
Case 1
iMin=97
iMax=26
Case 2
iMin=48
iMax=10
End Select
RandomLetter=chr( int( iMax*rnd() + iMin) )
End Function
' ============================================================================
' HTA Functions
Sub Window_Onload
Call CenterMe(500,460)
' Disable the fields that will be driven with business logic
txtDisplayName.disabled = True
txtCommonName.disabled = True
txtUPN.disabled = True
End Sub
Sub txtFirstName_OnChange()
Call CalculateNames()
End Sub
Sub txtLastName_OnChange()
Call CalculateNames()
End Sub
Sub txtMiddleName_OnChange()
Call CalculateNames()
txtInitial.Value = Left(txtMiddleName.value, 1)
End Sub
Sub CenterMe(iSizeH, iSizeV)
' VERSION 070709
' Repositions the window to be centered and sized
' INPUTS: iSizeH: The desired horizontal size of the window
' iSizeV: The desired vertical size of the window
' NOTE: Windows Server 2008 does not expose the
' display resolution, by default, so the routine
' will only size the window in the event that the
' resolution is not available
Dim sComputer, oWMIService, cItems, oItem
Dim iResolutionH, iResolutionV, iPositionH, iPositionV
' Get this computer's display resolution
sComputer = "."
Set oWMIService = GetObject("winmgmts:\\" & sComputer & "\root\cimv2")
Set cItems = oWMIService.ExecQuery("Select * From Win32_DesktopMonitor")
For Each oItem in cItems
iResolutionH = oItem.ScreenWidth
iResolutionV = oItem.ScreenHeight
' Windows Server 2008 does not provide the ScreenHeight & ScreenWidth by default
' so, below, we have to provide for this possibility
Next
' Calcultate the "centered" position
iPositionH = (iResolutionH - iSizeH) / 2
iPositionV = (iResolutionV - iSizeV) / 2
' Resize and reposition the window
window.resizeTo iSizeH, iSizeV
If iResolutionH >0 and iResolutionH > 0 Then
window.moveTo iPositionH, iPositionV
End If
End Sub
</script>
</head>
<body>
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<td colspan="2" style="font-size: 14pt;">
<!--<img src="HTALogo.gif" />-->
<span id="spnTitle">Provision a user</span>
</td>
</tr>
</table>
<hr/>
<table cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="tdlabel">First name</td>
<td class="tdvalue"><INPUT type="text" name="txtFirstName" id="txtFirstName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Middle name</td>
<td class="tdvalue"><INPUT type="text" name="txtMiddleName" id="txtMiddleName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Initial</td>
<td class="tdvalue"><INPUT type="text" name="txtInitial" id="txtInitial" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Last name</td>
<td class="tdvalue"><INPUT type="text" name="txtLastName" id="txtLastName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Pre-Windows 2000 logon name</td>
<td class="tdvalue"><INPUT type="text" name="txtSAMAccountName" id="txtSAMAccountName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Description</td>
<td class="tdvalue"><INPUT type="text" name="txtDescription" id="txtDescription" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Create user in</td>
<td class="tdvalue">
<select name="cboTargetOU" />
<option value="">User type</option>
<option value="ou=Employees,ou=People,dc=contoso,dc=com">Employee</option>
<option value="ou=Contractors,ou=People,dc=contoso,dc=com">Contractor</option>
</select>
</td>
</tr>
<tr>
<td class="tdlabel">Display name</td>
<td class="tdvalue"><INPUT type="text" name="txtDisplayName" id="txtDisplayName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">Common name</td>
<td class="tdvalue"><INPUT type="text" name="txtCommonName" id="txtCommonName" size="30" value=""></td>
</tr>
<tr>
<td class="tdlabel">User principal name</td>
<td class="tdvalue"><INPUT type="text" name="txtUPN" id="txtUPN" size="20" value=""></td>
</tr>
</table>
<hr/>
<table cellpadding="0" cellspacing="0" width="100%">
<tr><td>
<INPUT type="button" name="btnCommand" value="CREATE USER" style="width:100;" onclick="MainRoutine()">
</td></tr>
</table>
<hr/>
<div id="divStatus" name="divStatus" class="StatusInfo"> </div>
<hr/>
<div id="divInstructions" name="divInstructions" class="Instructions">
</div>
</body>
</html>
Posted
Jan 22 2009, 08:45 PM
by
danholme