userspace:active_directory_-_join_leave_relocate_ou
This is an old revision of the document!
Table of Contents
Active Directory client management, join/leave/relocate ou
- created by LarsG lars.gruenheid@civitec.de 2015/09/30
- tested under windows 7
- tested under win2012 active directory environment
- tested under winst 4.11.5.14
With this package, you can join or leave a domain, or change the ou-path for the client within a domain (still experimental, details below). These three functions are conveniently assigned to the action requests setup (join), uninstall (leave), update (relocate).
Setup
[Actions]
SetLogLevel = 9
ExitOnError = false
ScriptErrorMessages = on
TraceMode = off
StayOnTop = false
requiredWinstVersion >= "4.11.5.14"
ScriptErrorMessages = false
noUpdateScript
defVar $DomainRaw$
defVar $Domain$
defVar $DomainCurrent$
defVar $OUPath$
defVar $OUPathCurrent$
defVar $Username$
defVar $Password$
defVar $ExitCode$
defVar $JoinMode$
defVar $UnJoinMode$
defVar $JOIN_DOMAIN$
defVar $ACCT_CREATE$
defVar $ACCT_DELETE$
defVar $WIN9X_UPGRADE$
defVar $DOMAIN_JOIN_IF_JOINED$
defVar $JOIN_UNSECURE$
defVar $MACHINE_PASSWORD_PASSED$
defVar $DEFERRED_SPN_SET$
defVar $INSTALL_INVOCATION$
;defVar $ACCT_NO_OPTIONS$
;defVar $ACCT_DEACTIVATE$
;calculate joinmode from possible constants
set $JOIN_DOMAIN$ = "1"
set $ACCT_CREATE$ = "2"
set $ACCT_DELETE$ = "4"
set $WIN9X_UPGRADE$ = "16"
set $DOMAIN_JOIN_IF_JOINED$ = "32"
set $JOIN_UNSECURE$ = "64"
set $MACHINE_PASSWORD_PASSED$ = "128"
set $DEFERRED_SPN_SET$ = "256"
set $INSTALL_INVOCATION$ = "262144"
set $JoinMode$ = calculate($JOIN_DOMAIN$+"+"+$ACCT_CREATE$)
;calculate unjoinmode from possible constants
;set $ACCT_NO_OPTIONS$ = "0"
;set $ACCT_DEACTIVATE$ = "2"
;set $UnJoinMode$ = calculate($ACCT_DEACTIVATE$)
;product property domain_ou has the following syntax: [domain.tld][/ou_1/ou_2] - both segments are optional.
;domain must be the fqdn for the domain to join
;ou-path must consist of the hierarchical list of ou's the client should be put in, every ou must have a leading slash.
set $DomainRaw$ = getProductProperty("domain_ou","")
;get domain from product property - if domain is not set, get domain from host identifier.
set $Domain$ = takeString(0, splitString($DomainRaw$,"/"))
if ($Domain$ = "")
set $Domain$ = composeString(getSubList(1 : ,splitString("%HostId%",".")),".")
set $DomainRaw$ = $Domain$ + $DomainRaw$
endif
;get ou-path from product property - if ou-path is not set, join client to standard client-ou-path for the domain.
;ou-path will be transformed into ldap-friendly syntax.
set $OUPath$ = ""
for %OU% in getSubList(1 : ,splitString($DomainRaw$,"/")) do set $OUPath$ = "OU=%OU%,"+$OUPath$
if not ($OUPath$ = "")
for %DC% in splitString($Domain$,".") do set $OUPath$ = $OUPath$+"DC=%DC%,"
set $OUPath$ = strPart($OUPath$,"1",calculate(strLength($OUPath$)+"-1"))
endif
;get username + password from, product properties, hide password value in log
set $Username$ = getProductProperty("username","")
setConfidential getProductProperty("password","")
set $Password$ = getProductProperty("password","")
;check if client is in domain
if ( takeString(0, getOutStreamFromSection('execwith_vbs_check_domain cscript //nologo //e:vbs')) = "0" )
showBitmap "%ScriptPath%\domain.png" "Active Directory"
message "Join domain " + $DomainRaw$
execwith_vbs_domain_join cscript //nologo //e:vbs
sub_check_domain_join
dosinanicon_gpupdate /WaitOnClose
comment "Setting default logon domain, clear previous login user"
registry_default_domain /sysnative
exitwindows /Reboot
else
set $DomainCurrent$ = takeString(0, getOutStreamFromSection('execwith_vbs_get_domain cscript //nologo //e:vbs'))
;check if client is already in domain requested
if not ( $DomainCurrent$ = $Domain$ )
showBitmap "%ScriptPath%\domain.png" "Active Directory"
message "Leave domain " + $DomainCurrent$
execwith_vbs_domain_unjoin cscript //nologo //e:vbs
sub_check_domain_unjoin
;TODO remove client from ad
;TODO check exitcode adsi
exitwindows /ImmediateReboot
else
comment "Client is already in requested domain"
endif
endif
;reset username + password entries in product properties
opsiservicecall_unset_username
opsiservicecall_unset_password
[execwith_vbs_check_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.PartOfDomain
[execwith_vbs_get_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.Domain
[execwith_vbs_domain_join]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
res = obj.JoinDomainOrWorkGroup("$Domain$", "$Password$", "$Username$", "$OUPath$", $JoinMode$)
Wscript.Quit res
[execwith_vbs_domain_unjoin]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
res = obj.UnjoinDomainOrWorkgroup("$Password$", "$Username$")
;res = obj.UnjoinDomainOrWorkgroup("$Password$", "$Username$", $UnJoinMode$)
Wscript.Quit res
[dosinanicon_gpupdate]
gpupdate /force
exit %ERRORLEVEL%
[registry_default_domain]
openkey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
set "DefaultDomainName" = REG_SZ:"$Domain$"
set "AltDefaultDomainName" = REG_SZ:"$Domain$"
set "CachePrimaryDomain" = REG_SZ:"$Domain$"
openKey [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI]
set "LastLoggedOnSAMUser" = REG_SZ:""
set "LastLoggedOnUser" = REG_SZ:""
[opsiservicecall_unset_username]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"username",
"",
"%hostid%"
]
[opsiservicecall_unset_password]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"password",
"",
"%hostid%"
]
[sub_check_domain_unjoin]
set $ExitCode$ = getLastExitCode
if $ExitCode$ = "0"
comment "Success"
else
logError "UNKNOWN ERROR " & ReturnValue
isFatalError
endif
[sub_check_domain_join]
set $ExitCode$ = getLastExitCode
if $ExitCode$ = "0"
comment "Success"
else
if $ExitCode$ = "2"
logError "Missing OU"
isFatalError
else
if $ExitCode$ = "5"
logError "Access denied"
isFatalError
else
if $ExitCode$ = "53"
logError "Network path not found"
isFatalError
else
if $ExitCode$ = "87"
logError "Parameter incorrect"
isFatalError
else
if $ExitCode$ = "1326"
logError "Logon failure, user or pass"
isFatalError
else
if $ExitCode$ = "1355"
logError "Domain can not be contacted"
isFatalError
else
if $ExitCode$ = "1909"
logError "User account locked out"
isFatalError
else
if $ExitCode$ = "2224"
logError "Computer Account allready exists"
isFatalError
else
if $ExitCode$ = "2691"
logError "Allready joined"
isFatalError
else
logError "Unknown error " & ReturnValue
isFatalError
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
Uninstall
[Actions]
SetLogLevel = 9
ExitOnError = false
ScriptErrorMessages = on
TraceMode = off
StayOnTop = false
requiredWinstVersion >= "4.11.5.14"
ScriptErrorMessages = false
defVar $DomainCurrent$
defVar $Username$
defVar $Password$
defVar $ExitCode$
defVar $UnJoinMode$
;defVar $ACCT_NO_OPTION$
;defVar $ACCT_DEACTIVATE$
;calculate unjoinmode from possible constants
;set $ACCT_NO_OPTION$ = "0"
;set $ACCT_DEACTIVATE$ = "2"
;set $UnJoinMode$ = calculate($ACCT_DEACTIVATE$)
;get username + password from, product properties, hide password value in log
set $Username$ = getProductProperty("username","")
setConfidential getProductProperty("password","")
set $Password$ = getProductProperty("password","")
;reset username + password entries in product properties
;opsiservicecall_unset_username
;opsiservicecall_unset_password
;check if client is in domain
if not ( takeString(0, getOutStreamFromSection('execwith_vbs_check_domain cscript //nologo //e:vbs')) = "0" )
set $DomainCurrent$ = takeString(0, getOutStreamFromSection('execwith_vbs_get_domain cscript //nologo //e:vbs'))
showBitmap "%ScriptPath%\domain.png" "Active Directory"
message "Leave domain " + $DomainCurrent$
;leave domain
execwith_vbs_domain_unjoin cscript //nologo //e:vbs
sub_check_domain_unjoin
;TODO remove client from ad
;TODO check exitcode adsi
;restart client, script will be re-executed upon next opsi request
exitwindows /Reboot
else
comment "Computer is currently not part of a domain"
endif
;reset username + password entries in product properties
opsiservicecall_unset_username
opsiservicecall_unset_password
[execwith_vbs_check_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.PartOfDomain
[execwith_vbs_get_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.Domain
[execwith_vbs_domain_unjoin]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
res = obj.UnjoinDomainOrWorkgroup("$Password$", "$Username$")
;res = obj.UnjoinDomainOrWorkgroup("$Password$", "$Username$", $UnJoinMode$)
Wscript.Quit res
[opsiservicecall_unset_username]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"username",
"",
"%hostid%"
]
[opsiservicecall_unset_password]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"password",
"",
"%hostid%"
]
[sub_check_domain_unjoin]
set $ExitCode$ = getLastExitCode
if $ExitCode$ = "0"
comment "Success"
else
logError "UNKNOWN ERROR " & ReturnValue
isFatalError
endif
Update
[Actions]
SetLogLevel = 9
ExitOnError = false
ScriptErrorMessages = on
TraceMode = off
StayOnTop = false
requiredWinstVersion >= "4.11.5.14"
ScriptErrorMessages = false
defVar $DomainRaw$
defVar $Domain$
defVar $DomainCurrent$
defVar $OUPath$
defVar $OUPathCurrent$
defVar $Username$
defVar $Password$
defVar $ExitCode$
;product property domain_ou has the following syntax: [domain.tld][/ou_1/ou_2] - both segments are optional.
;domain must be the fqdn for the domain to join
;ou-path must consist of the hierarchical list of ou's the client should be put in, every ou must have a leading slash.
set $DomainRaw$ = getProductProperty("domain_ou","")
;get domain from product property - if domain is not set, get domain from host identifier.
set $Domain$ = takeString(0, splitString($DomainRaw$,"/"))
if ($Domain$ = "")
set $Domain$ = composeString(getSubList(1 : ,splitString("%HostId%",".")),".")
set $DomainRaw$ = $Domain$ + $DomainRaw$
endif
;get ou-path from product property - if ou-path is not set, join client to standard client-ou-path for the domain.
;ou-path will be transformed into ldap-friendly syntax.
set $OUPath$ = ""
for %OU% in getSubList(1 : ,splitString($DomainRaw$,"/")) do set $OUPath$ = "OU=%OU%,"+$OUPath$
if not ($OUPath$ = "")
for %DC% in splitString($Domain$,".") do set $OUPath$ = $OUPath$+"DC=%DC%,"
set $OUPath$ = strPart($OUPath$,"1",calculate(strLength($OUPath$)+"-1"))
endif
;get username + password from, product properties, hide password value in log
set $Username$ = getProductProperty("username","")
setConfidential getProductProperty("password","")
set $Password$ = getProductProperty("password","")
if not ( takeString(0, getOutStreamFromSection('execwith_vbs_check_domain cscript //nologo //e:vbs')) = "0" )
set $DomainCurrent$ = takeString(0, getOutStreamFromSection('execwith_vbs_get_domain cscript //nologo //e:vbs'))
;check if client is in domain requested
if ( $DomainCurrent$ = $Domain$ )
set $OUPathCurrent$ = takeString(0, getOutStreamFromSection('execwith_vbs_get_oupath cscript //nologo //e:vbs'))
;check if client is already in ou-path requested
if not ( $OUPathCurrent$ = $OUPath$ )
showBitmap "%ScriptPath%\domain.png" "Active Directory"
message "Relocate to ou-path " + $DomainRaw$
execwith_vbs_move_oupath cscript //nologo //e:vbs
;TODO check exitcode adsi
dosinanicon_gpupdate /WaitOnClose
else
comment "Computer is already in the given ou-path"
endif
else
logError "Computer is not part of the domain requested, moving to another ou-path only works within the same domain"
isFatalError
endif
else
logError "Computer is currently not part of a domain"
isFatalError
endif
[execwith_vbs_check_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.PartOfDomain
[execwith_vbs_get_domain]
Set obj = GetObject("WinMgmts:\\.\root\cimv2:Win32_ComputerSystem.Name='%PCNAME%'")
Wscript.Echo obj.Domain
[execwith_vbs_get_oupath]
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Properties("User ID") = "$Username$"
adoConnection.Properties("Password") = "$Password$"
adoConnection.Properties("Encrypt Password") = True
Set adoCommand = CreateObject("ADODB.Command")
adoConnection.Properties("ADSI Flag") = &H200 Or &H1
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
adoCommand.CommandText = "Select distinguishedName from 'LDAP://$Domain$' where objectClass='computer' and cn='%PCNAME%'"
adoCommand.Properties("Searchscope") = 2
Set adoRecordSet = adoCommand.Execute
adoRecordSet.MoveFirst
OUPathCurrent = adoRecordSet.Fields("distinguishedName").Value
Wscript.Echo Mid(OUPathCurrent,InStr(OUPathCurrent,",")+1)
[execwith_vbs_move_oupath]
Set obj = GetObject("LDAP:")
obj.OpenDSObject "LDAP://w8vrsag08.$Domain$/$OUPath$", "$Username$", "$Password$", 1
res = obj.MoveHere("LDAP://CN=%PCNAME%,$OUPathCurrent$", "CN=%PCNAME%")
Wscript.Quit res
[dosinanicon_gpupdate]
gpupdate /force
exit %ERRORLEVEL%
[opsiservicecall_unset_username]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"username",
"",
"%hostid%"
]
[opsiservicecall_unset_password]
"method": "setProductProperty"
"params": [
"%installingProdName%",
"password",
"",
"%hostid%"
]
userspace/active_directory_-_join_leave_relocate_ou.1443635376.txt.gz · Last modified: (external edit)
