Change the admin password using SCCM.
- You just need to create a program, use the command line:
%systemroot%\system32\cscript “your_script_name.vbs” new_password true - Create the collection.
If you are comfortable with your test, you could populate the collection base on a query. - Create the advertisement.
Let me explain what we have.
In fact nothing special except in this script we don’t care about if the admin account was renamed or not, to identify the admin account we check the SID.
If the SID starts by
S-1-5 and if he ends with
-500 we are sure this is the right one.
- We unlock the account if it’s locked
- We enable the account if it’s disabled
- We set the password never expire
- We set the new password
- In the mean time we add one domain group in the local administrators group (optional)
- We create a backup account (optional)
- We create a random password for this backup account.
- We add this account into the local administrators group.
- A mail is sent (optional)
- An event is created in the event log
- We grant admin right to the user if the computer is a laptop. (Optional)
in that case we use the user define in the computer object in in AD “manage by”.
It’s up to you to modify this code. - The first argument is the new password
- The second argument should be true of false if you want to grant admin right to the user define in AD.
* If you plane to add the domain group into the local admin group, change the value of
admin_member_group_name.
* If you plane to send a mail each time a password was change then modify the value of :
MAIL_TO,
SMTP_Servername and se the
MAIL to true
* IF you plane to grant admin right to the user define in the manage by ( we set that for the laptop users only) you have to change the value of
AD_ROOT if you have some trouble with this script let me know. copy and past the code after this line
'==========================================================================
'
' VBScript Source File -- Created with SAPIEN Technologies PrimalScript 4.0
'
' NAME:
'
' AUTHOR: Laurent Trachsel
trachsel@gmail.com ' DATE : 19/10/2010
'
' COMMENT: none
'
'==========================================================================
' Option Explicit
Function Get_AdminName
Dim objwmi
Dim qry
Dim Admin
Set objwmi = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & strComputer)
qry = "SELECT * FROM Win32_Account where Domain = '" & cstr(strComputer) & "'" 'set query, making sure to only look at local computer
For Each Admin in objwmi.ExecQuery(qry)
if (left(admin.sid, 6) = "S-1-5-" And right(admin.sid,4) = "-500") then 'look for admin sid
Get_AdminName = admin.name
end if
Next
end Function
Function unlock_user(cur_UserName)
Dim UserObj
Set UserObj = GetObject("WinNT://"& strComputer &"/"& cur_UserName &"")
If UserObj.IsAccountLocked = -1 then UserObj.IsAccountLocked = 0
UserObj.SetInfo
If err.number = 0 Then
unlock_user = false
Else
unlock_user = True
End if
End Function
Function Change_PWD(cur_UserName, newpwd)
WScript.Echo "... newpwd: " & newpwd
Dim new_objUser
Set new_objUser = GetObject("WinNT://" & strComputer & "/" & cur_UserName & ", user")
new_objUser.SetPassword newpwd
new_objUser.SetInfo
End Function
Function PWD_never_expire(req_UserName)
Dim objUser
Set objUser = GetObject("WinNT://" & strComputer & "/"& req_UserName )
objUserFlags = objUser.Get("UserFlags")
objPasswordExpirationFlag = objUserFlags OR ADS_UF_DONT_EXPIRE_PASSWD
objUser.Put "userFlags", objPasswordExpirationFlag
objUser.SetInfo
End Function
Function enable_User(req_UserName)
Set objUser = GetObject("WinNT://" & strComputer & "/" & req_UserName)
objUser.AccountDisabled = False
objUser.SetInfo
End Function
Sub write_Event(strMessage)
' Constants for type of event log entry
const EVENTLOG_SUCCESS = 0
const EVENTLOG_ERROR = 1
const EVENTLOG_WARNING = 2
const EVENTLOG_INFORMATION = 4
const EVENTLOG_AUDIT_SUCCESS = 8
const EVENTLOG_AUDIT_FAILURE = 16
'strMessage = "My event log message..."
objShell.LogEvent EVENTLOG_INFORMATION, strMessage
End Sub
Sub update_admingroups(globalGRoup)
Dim objLocalGroup
Dim objADGroup
If globalGRoup <> vbNullString Then
Set objLocalGroup = GetObject("WinNT://./Administrators")
Set objADGroup = GetObject("WinNT://corp/" & globalGRoup)
if not objLocalGroup.ismember(objADGroup.adspath) Then
objLocalGroup.Add(objADGroup.ADsPath)
End if
Set objLocalGroup = Nothing
Set objADGroup = Nothing
End if
End Sub
Sub create_local_UserAccount(req_UserName)
Dim colAccounts
Dim objUser
If req_UserName <> vbNullString Then
Set colAccounts = GetObject("WinNT://" & strComputer & "")
Set objUser = colAccounts.Create("user", req_UserName)
cur_backupadmin_pwd = generatePassword(8)
objUser.SetPassword cur_backupadmin_pwd
objUser.SetInfo
End if
End Sub
Sub Grant_admin_right(req_UserName)
On Error Resume Next
Dim objGroup
Dim objUser
If req_UserName <> vbNullString Then
Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators,group")
Set objUser = GetObject("WinNT://" & strComputer & "/"& req_UserName &",user")
objGroup.Add(objUser.ADsPath)
End If
On Error GoTo 0
End Sub
Sub Grant_corpusr_admin_right(req_UserName)
On Error Resume Next
Dim objGroup
Dim objUser
If req_UserName <> vbNullString Then
Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators,group")
Set objUser = GetObject("WinNT://corp/"& req_UserName &",user")
objGroup.Add(objUser.ADsPath)
End If
On Error GoTo 0
End Sub
Function UserExist()
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
Set colAccounts = GetObject("WinNT://" & strComputer & "")
colAccounts.Filter = Array("user")
For Each objUser In colAccounts
If objUser.Name = backup_admin_login Then
UserExist = True
Exit function
End if
Next
UserExist = False
End Function
function Get_ManageBY(SearchComputername)
Const ADS_SCOPE_ONELEVEL = 1
const ADS_SCOPE_SUBTREE = 2
Dim objConnection
Dim objCommand
Dim objRecordSet
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.CommandText = "SELECT name, cn,distinguishedName, managedBy FROM 'LDAP://"& AD_ROOT &"' WHERE objectCategory='computer' AND cn='"& trim(SearchComputername) &"'"
Set objRecordSet = objCommand.Execute
On Error Resume Next
objRecordSet.MoveFirst
If Err.Number <> 0 Then
'WScript.Echo "... device not found"
WriteLineToFile SearchUserGlobalID &";;;"
On Error GoTo 0
Exit Function
End If
Do Until objRecordSet.EOF
'Wscript.Echo "... ManagedBy:"& objRecordSet.Fields("managedBy").Value
If objRecordSet.Fields("managedBy").Value <> vbNullString then
Get_ManageBY = objRecordSet.Fields("managedBy").Value
cur_computer_adspath = objRecordSet.Fields("distinguishedName").Value
On Error GoTo 0
Exit function
End if
objRecordSet.MoveNext
Loop
End Function
Function Get_samAccountName(search_distinguishedName)
Const ADS_SCOPE_ONELEVEL = 1
const ADS_SCOPE_SUBTREE = 2
Dim objConnection
Dim objCommand
Dim objRecordSet
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.CommandText = "SELECT name, cn, samAccountName FROM 'LDAP://"& AD_ROOT &"' WHERE objectCategory='user' AND distinguishedName='"& trim(search_distinguishedName) &"'"
Set objRecordSet = objCommand.Execute
On Error Resume Next
objRecordSet.MoveFirst
If Err.Number <> 0 Then
'WScript.Echo "... User not found"
On Error GoTo 0
Exit Function
End If
Do Until objRecordSet.EOF
If objRecordSet.Fields("samAccountName").Value <> vbNullString Then
Get_samAccountName = objRecordSet.Fields("samAccountName").Value
On Error GoTo 0
Exit function
End if
objRecordSet.MoveNext
Loop
End Function
Function generatePassword(PASSWORD_LENGTH)
Dim NUMLOWER, NUMUPPER, LOWERBOUND, UPPERBOUND, LOWERBOUND1, UPPERBOUND1, SYMLOWER, SYMUPPER
Dim newPassword, count, pwd
Dim pCheckComplex, pCheckComplexUp, pCheckComplexLow, pCheckComplexNum, pCheckComplexSym, pCheckAnswer
NUMLOWER = 48 ' 48 = 0
NUMUPPER = 57 ' 57 = 9
LOWERBOUND = 65 ' 65 = A
UPPERBOUND = 90 ' 90 = Z
LOWERBOUND1 = 97 ' 97 = a
UPPERBOUND1 = 122 ' 122 = z
SYMLOWER = 33 ' 33 = !
SYMUPPER = 46 ' 46 = .
pCheckComplexUp = 0 ' used later to check number of character types in password
pCheckComplexLow = 0 ' used later to check number of character types in password
pCheckComplexNum = 0 ' used later to check number of character types in password
pCheckComplexSym = 0 ' used later to check number of character types in password
' initialize the random number generator
Randomize()
newPassword = ""
count = 0
DO UNTIL count = PASSWORD_LENGTH
' generate a num between 2 and 10
' if num <= 2 create a symbol
If Int( ( 10 - 2 + 1 ) * Rnd + 2 ) <= 2 Then
pwd = Int( ( SYMUPPER - SYMLOWER + 1 ) * Rnd + SYMLOWER )
' if num is between 3 and 5 create a lowercase
Elseif Int( ( 10 - 2 + 1 ) * Rnd + 2 ) > 2 And Int( ( 10 - 2 + 1 ) * Rnd + 2 ) <= 5 Then
pwd = Int( ( UPPERBOUND1 - LOWERBOUND1 + 1 ) * Rnd + LOWERBOUND1 )
' if num is 6 or 7 generate an uppercase
Elseif Int( ( 10 - 2 + 1 ) * Rnd + 2 ) > 5 And Int( ( 10 - 2 + 1 ) * Rnd + 2 ) <= 7 Then
pwd = Int( ( UPPERBOUND - LOWERBOUND + 1 ) * Rnd + LOWERBOUND )
Else
pwd = Int( ( NUMUPPER - NUMLOWER + 1 ) * Rnd + NUMLOWER )
End If
newPassword = newPassword + Chr( pwd )
count = count + 1
'Check to make sure that a proper mix of characters has been created. If not discard the password.
If count = (PASSWORD_LENGTH) Then
For pCheckComplex = 1 To PASSWORD_LENGTH
'Check for uppercase
If Asc(Mid(newPassword,pCheckComplex,1)) >64 And Asc(Mid(newPassword,pCheckComplex,1))< 90 Then
pCheckComplexUp = 1
'Check for lowercase
ElseIf Asc(Mid(newPassword,pCheckComplex,1)) >96 And Asc(Mid(newPassword,pCheckComplex,1))< 123 Then
pCheckComplexLow = 1
'Check for numbers
ElseIf Asc(Mid(newPassword,pCheckComplex,1)) >47 And Asc(Mid(newPassword,pCheckComplex,1))< 58 Then
pCheckComplexNum = 1
'Check for symbols
ElseIf Asc(Mid(newPassword,pCheckComplex,1)) >32 And Asc(Mid(newPassword,pCheckComplex,1))< 47 Then
pCheckComplexSym = 1
End If
Next
'Add up the number of character sets. We require 3 or 4 for a complex password.
pCheckAnswer = pCheckComplexUp+pCheckComplexLow+pCheckComplexNum+pCheckComplexSym
If pCheckAnswer < 3 Then
newPassword = ""
count = 0
End If
End If
Loop
'The password is good so return it
generatePassword = "!" & newPassword
End Function
Sub sendMAil()
Dim iMsg
Dim iConf
Dim Flds
Dim strHTML
Dim msg
Const cdoSendUsingPort = 2
set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields
msg=""
msg = msg & "<html xmlns="&Chr(34)&"http://www.w3.org/1999/xhtml"&Chr(34)&" ><head> <style type="&Chr(34)&"text/css"&Chr(34)&">.style1{color: #CC3300;font-weight: bold;}.style2{color: #000000;}</style>"
msg = msg & "</head><body><b>Password was change for "& strComputer &"<br /></b><table class="&Chr(34)&"style2"&Chr(34)&"><tr><td style="&Chr(34)&"background-color: #999999"&Chr(34)&" >new password is: </td><td style="&Chr(34)&"color: #FFFFFF; font-weight: 700; background-color: #3399FF"&Chr(34)&" >"& cur_backupadmin_pwd &"</td></tr></table><BR>"
msg = msg & "<span class="&Chr(34)&"style1"&Chr(34)&">Remember:</span><BR>Never send the admin password to the end user.<br />we have created a second local user account name "& backup_admin_login &", this account is administrator of the device <b>"& strComputer &"</b><BR>The BackupAdmin password is unic. <BR>If you send this password to a user, password should be change after few days.<br />thanks,<br>laurent<BR><p> </p></body></html>"
' Set the CDOSYS configuration fields to use port 25 on the SMTP server.
With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = SMTP_Servername
.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 10
.Update
End With
' Apply the settings to the message.
With iMsg
WScript.Echo "... MailTo: " & MAIL_TO
WScript.Echo "... MailFrom: " & strComputer
Set .Configuration = iConf
.To = MAIL_TO
.From = strComputer & "@free.fr"
.Subject = "password was changed on "& strComputer &" at " & now
.HTMLBody = msg
.Send
End With
' Clean up variables.
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing
End Sub
Function is_laptop()
Dim strComputer
Dim objWMIService
Dim colChassis
Dim strChassisType
Dim objChassis
Dim tmp_value
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colChassis = objWMIService.ExecQuery("Select * from Win32_SystemEnclosure")
For Each objChassis in colChassis
For Each strChassisType in objChassis.ChassisTypes
Select Case strChassisType
'Case 1
' Wscript.Echo "Other"
'Case 2
'Wscript.Echo "Unknown"
'Case 3
'Wscript.Echo "Desktop"
'Case 4
'Wscript.Echo "Low Profile Desktop"
'Case 5
'tmp_value = "Pizza Box"
'Case 6
'Wscript.Echo "Mini Tower"
'Case 7
'Wscript.Echo "Tower"
Case 8
'Wscript.Echo "Portable"
tmp_value = True
Case 9
'Wscript.Echo "Laptop"
tmp_value = True
Case 10
'Wscript.Echo "Notebook"
tmp_value = True
Case 11
'Wscript.Echo "Handheld"
tmp_value = True
Case 12
'Wscript.Echo "Docking Station"
tmp_value = True
'Case 13
'Wscript.Echo "All-in-One"
'Case 14
'Wscript.Echo "Sub-Notebook"
'Case 15
'Wscript.Echo "Space Saving"
'Case 16
'Wscript.Echo "Lunch Box"
'Case 17
'Wscript.Echo "Main System Chassis"
'Case 18
'Wscript.Echo "Expansion Chassis"
'Case 19
'Wscript.Echo "Sub-Chassis"
'Case 20
'Wscript.Echo "Bus Expansion Chassis"
'Case 21
'Wscript.Echo "Peripheral Chassis"
'Case 22
'Wscript.Echo "Storage Chassis"
'Case 23
'Wscript.Echo "Rack Mount Chassis"
'Case 24
'tmp_value = "Sealed-Case PC"
Case Else
'tmp_value = "Unknown"
tmp_value = False
End Select
Next
Next
is_laptop = tmp_value
End Function
' **********************************
' **********************************
' **********************************
' **********************************
' start here
Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000
Dim strComputer
Dim objNetwork
Dim cur_admin_profile
Dim objUser
Dim objShell
Dim backupadmin_login
Dim cur_backupadmin_pwd
Dim cur_admin_pwd
Dim computer_manageby
Dim cur_computer_adspath
Dim isalaptop
Dim objArgs
Dim debug
Dim grant_Adminright
Dim SMT_Servername
Dim MAIL_TO
Dim Create_Backup_Account
Dim Update_administrators_group
Dim AD_ROOT
set objShell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("Wscript.Network") 'get the current computer name
Set objArgs = WScript.Arguments
debug = False ' change to true to enable the display
grant_Adminright = False ' set the true if you plane to grant admin right to the user define in your AD.
Create_Backup_Account = True ' set the true if you plane to create a backup account
backup_admin_login = "BackupAdmin" ' set the name for this backup account
Update_administrators_group = False ' set to true is want to add a domain group into the local admin group
admin_member_group_name = "Your_group_here" ' change the group here should be a domain group name
MAIL = True ' set the true if you want to send a mail each time a password was reset using this scirpt
SMTP_Servername = "smtp.contoso.com" ' put here your smtp server name (FQDN)
MAIL_TO = "couldbe_a_share_point_mail_here@contoso.com" ' change the mail to here
AD_ROOT = "DC=corp,DC=contoso,DC=com" ' change the AD root if you plane to grant admin right to the user define in manage by of the computer object in AD
If objArgs.Count > 1 Then
cur_admin_pwd = objArgs(0) ' Argument 0 if the new admin password
grant_Adminright = objArgs(1) ' argument should be true or false - if you want to grant admin right to the user define in the manage by.
If lcase(grant_Adminright) = "true" Then grant_Adminright = True
If lcase(grant_Adminright) = "false" Then grant_Adminright = false
elseIf objArgs.Count > 0 Then
cur_admin_pwd = objArgs(0)
Else
if debug = true then WScript.Echo "... Argument missing" ' argument missing we do nothing.
WScript.Quit (9)
End If
if debug = true then WScript.Echo "... GrantAdminright: " & grant_Adminright
if debug = true then WScript.Echo "... Cur_admin_pwd: "& cur_admin_pwd
strComputer = objNetwork.ComputerName
if debug = true then WScript.Echo "... strComputer: " & strComputer
cur_admin_profile = Get_AdminName
if debug = true then WScript.Echo "... admin_profile: " & cur_admin_profile
Set objUser = GetObject("WinNT://./"& trim(cur_admin_profile) &"")
unlock_user cur_admin_profile
if debug = true then WScript.Echo "... account unlocked"
enable_User cur_admin_profile
if debug = true then WScript.Echo "... account enabled"
PWD_never_expire cur_admin_profile
if debug = true then WScript.Echo "... account never expired"
change_PWD cur_admin_profile , cur_admin_pwd
write_Event "Password for:" & cur_admin_profile & " was reset by a script"
If Update_administrators_group = True Then
update_admingroups admin_member_group_name
if debug = true then WScript.Echo "... Update Administrators group"
End If
' // create a backup account if Create_Backup_Account = True
' // by default Create_Backup_Account = false
' // the password will be a random password
if Create_Backup_Account = True Then
if debug = true then WScript.Echo "... Create backup admin"
If UserExist = False Then
create_local_UserAccount backup_admin_login
if debug = true then WScript.Echo "... create "& backup_admin_login
Else
cur_backupadmin_pwd = generatePassword(8)
change_PWD backup_admin_login , cur_backupadmin_pwd
if debug = true then WScript.Echo "... set a new password for "& backup_admin_login
End If
'//
unlock_user backup_admin_login
if debug = true then WScript.Echo "... Unlock "& backup_admin_login &" account"
PWD_never_expire backup_admin_login
if debug = true then WScript.Echo "... Set account never expire for "& backup_admin_login
enable_User backup_admin_login
if debug = true then WScript.Echo "... enable "& backup_admin_login &" account"
Grant_admin_right backup_admin_login
if debug = true then WScript.Echo "... grant "& backup_admin_login & " admin right"
'//
End If
'// send the mail is mail is set the true (defaul is false)
if mail = true Then
sendMAil
If debug = true then WScript.Echo "... send the new password to sharepoint"
End If
' // Grant admin right to the use defind in AD in the mange by of the computer object
' // to enable this function set grant_Adminright to true (default is false)
If grant_Adminright = True Then
computer_manageby = Get_ManageBY (strComputer)
if debug = true then WScript.Echo "... manageby: "& computer_manageby
If computer_manageby <> "" Then user_Login = Get_samAccountName(computer_manageby)
If cur_computer_adspath <> "" Then
If is_laptop() = true Then
if debug = true then WScript.Echo "... this is a laptop"
Grant_corpusr_admin_right user_Login
Else
if debug = true then WScript.Echo "... this is not a laptop"
End If
End If
If debug = True Then WScript.Echo "... user_Login: "& user_Login
End If
if debug = true then WScript.Echo "... Script ended"