Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1524
  • Last Modified:

VBScript needed to be run from Non domain PC

Hi There,

I have a script written by Wayne Tilton a while back. This script uses the IP address of the local machine to determine which Site OU it should belong to. This works great when running from domain PC with an appropriate user executing.
However, I would like to run this VBscript within WinPE to determine the OU and then make changes to the sysprep.inf. The machine would then be autmatically named according to our naming convention (which has the Site OU in it) as well as moved to the 'Computers' OU within that Site. I have managed to get the script working to modify the relevant sysprep.inf settings on a domain PC with the relevant user logged on.

I have already tried binding to the various objects using various methods but am having no success. Also, have performed several searches within experts exchange to no avail!
Could someone help me modify this code to run in the WinPE environment? I have no problems in embedding credentials as we have an account specific for this purpose which is locked down.
Alternatively, a way of running the script in VB equivalent of runas with the credentials on that script? I am desperate guys!! I have included Waynes' script below. If there is anything else you need to ask, please do! look forward to your help!
'------------------------------------------------------------------------------'
' Displays the AD Site name for the supplied dotted decimal IP address.
'
'------------------------------------------------------------------------------'
' IP2Site.vbs witten April 4, 2003 by Wayne Tilton
'------------------------------------------------------------------------------'
Option Explicit

Dim Site

WScript.Echo SiteName(WScript.Arguments.Item(0))
Site = SiteName(WScript.Arguments.Item(0))
WScript.Echo Site


Function SiteName(IPAddr)

Dim ConfigNameContext
Dim DecIPAddr, MaskBits, NumAddrs, LoIPAddr, HiIPAddr, SiteAddrs
Dim SubnetContainer, LDAPQry, Subnet
Dim AdConn, AdComm, AdRS

SiteName = "Default-First-Site-Name" ' Default site name if no matches
DecIPAddr = Dot2Dec(IPAddr) ' Convert supplied address to decimal

ConfigNameContext = GetObject("LDAP://RootDSE").Get("configurationNamingContext")

SubnetContainer = "CN=Subnets,CN=Sites," & ConfigNameContext
LDAPQry = "<LDAP://" & SubnetContainer & ">;(objectCategory=subnet);cn,siteObject"

Set AdConn = CreateObject("ADODB.Connection") ' Get an ADO connection object

AdConn.Provider = "ADsDSOObject" ' Set provider name
AdConn.Open "Active Directory Provider" ' open connection

Set AdComm = CreateObject("ADODB.Command") ' Get an ADO command object
Set AdComm.ActiveConnection = AdConn ' Tell command object about connection
AdComm.Properties("SearchScope") = 2 ' we want to search everything
AdComm.Properties("Page Size") = 500 ' and we want our records in lots of 500

AdComm.CommandText = LDAPQry ' Set the ADO CommandText
Set AdRS = AdComm.Execute ' and run the query.

SiteAddrs = (2^31)-1 ' Really big range
AdRS.MoveFirst ' Go to 1st record in the set
While Not AdRS.EOF ' Read 'em until they're gone
Subnet = AdRs.Fields("cn") ' Get subnet name
MaskBits = Split(Subnet,"/") ' Split IP addr from subnet mask
NumAddrs = (2 ^ (32 - MaskBits(1))) - 1 ' Calc # addresses based on subnet mask
LoIPAddr = Dot2Dec(MaskBits(0)) ' Get low end of IP range in decimal
HiIPAddr = LoIPAddr + NumAddrs ' Calc high end of range by adding # add
' Check to see if IP is within this subnet range and if so that it's smallest subnet with that addr
If DecIPAddr => LoIPAddr And DecIPAddr <= HiIPAddr And NumAddrs <= SiteAddrs then
SiteName = AdRs.Fields("siteObject")
SiteName = GetObject("LDAP://" & AdRs.Fields("siteObject")).Get("name")
SiteAddrs = NumAddrs ' Remember # addrs in this subnet
End If
AdRS.MoveNext ' Go to next record or EOF
Wend

Set AdRs = Nothing
Set AdComm = Nothing
Set AdConn = Nothing
End Function

' Returns the decimal value of a dotted decimal IP address
Function Dot2Dec(IPAddress)
Dim Octets
Octets = Split(IPAddress,".")
Dot2Dec = (Octets(0)*(2^24)) + (Octets(1)*(2^16)) + (Octets(2)*(2^8)) + Octets(3)
End Function

Open in new window

0
crazymystic
Asked:
crazymystic
  • 5
  • 4
  • 2
1 Solution
 
dax_badCommented:
Hey mate,

Add the below lines, that should do it. Change account name to an account in the domain with the add computers to a domain permissions and edit the below password.

I hope that does the trick

Cheers
DAniel

Additional code:
'Add these 2 lines after line 22
Const ADS_SECURE_AUTHENTICATION = &H1
Const ADS_SERVER_BIND = &H200

'Add these 2 lines to after line 25
strUser = "TestUser@MyDomain.com"
strPassword = "Abc1234"

'Add these for lines after line 40
adoConnection.Properties("User ID") = strUser
adoConnection.Properties("Password") = strPassword
adoConnection.Properties("Encrypt Password") = True
adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND _
     Or ADS_SECURE_AUTHENTICATION
0
 
dax_badCommented:
You can use the below formats for the user account:

strUser = "cn=TestUser,ou=Sales,dc=MyDomain,dc=com"
strUser = "TestUser@MyDomain.com"
strUser = "MyDomain\TestUser"

Optionally you can add the below two variables to line 21 to dim them
strPassword
strUser
0
 
crazymysticAuthor Commented:
Hi there Daniel,

Sorry about the delay in getting back to you. mate, I have tried what you have asked me to do above and no joy. Could you check below to make sure I have followed your instructions correctly?

Now, I have also tried this with the adoConnection changed to 'ADConn' and 'ADComm' with no success.

I think the key to getting this right is with this code within the function:
SiteAddrs = (2^31)-1 ' Really big range
AdRS.MoveFirst ' Go to 1st record in the set
While Not AdRS.EOF ' Read 'em until they're gone
Subnet = AdRs.Fields("cn") ' Get subnet name
MaskBits = Split(Subnet,"/") ' Split IP addr from subnet mask
NumAddrs = (2 ^ (32 - MaskBits(1))) - 1 ' Calc # addresses based on subnet mask
LoIPAddr = Dot2Dec(MaskBits(0)) ' Get low end of IP range in decimal
HiIPAddr = LoIPAddr + NumAddrs ' Calc high end of range by adding # add
' Check to see if IP is within this subnet range and if so that it's smallest subnet with that addr
If DecIPAddr => LoIPAddr And DecIPAddr <= HiIPAddr And NumAddrs <= SiteAddrs then
SiteName = AdRs.Fields("siteObject")
SiteName = GetObject("LDAP://" & AdRs.Fields("siteObject")).Get("name")
SiteAddrs = NumAddrs ' Remember # addrs in this subnet
End If
AdRS.MoveNext ' Go to next record or EOF
Wend

I think it is the LDAP query here that does not return the relevant values. although, I am stumped as to why! especially if it is using the stated connection.


Function SiteName(IPAddr)

Dim ConfigNameContext
Dim DecIPAddr, MaskBits, NumAddrs, LoIPAddr, HiIPAddr, SiteAddrs
Dim SubnetContainer, LDAPQry, Subnet
Dim AdConn, AdComm, AdRS

Const ADS_SECURE_AUTHENTICATION = &H1
Const ADS_SERVER_BIND = &H200

SiteName = "Default-First-Site-Name" ' Default site name if no matches
DecIPAddr = Dot2Dec(IPAddr) ' Convert supplied address to decimal

strUser = "TestUser@MyDomain.com"
strPassword = "Abc1234"


ConfigNameContext = GetObject("LDAP://RootDSE").Get("configurationNamingContext")

SubnetContainer = "CN=Subnets,CN=Sites," & ConfigNameContext
LDAPQry = "<LDAP://" & SubnetContainer & ">;(objectCategory=subnet);cn,siteObject"

Set AdConn = CreateObject("ADODB.Connection") ' Get an ADO connection object

AdConn.Provider = "ADsDSOObject" ' Set provider name
AdConn.Open "Active Directory Provider" ' open connection

Set AdComm = CreateObject("ADODB.Command") ' Get an ADO command object
Set AdComm.ActiveConnection = AdConn ' Tell command object about connection
AdComm.Properties("SearchScope") = 2 ' we want to search everything
AdComm.Properties("Page Size") = 500 ' and we want our records in lots of 500
adoConnection.Properties("User ID") = strUser
adoConnection.Properties("Password") = strPassword
adoConnection.Properties("Encrypt Password") = True
adoConnection.Properties("ADSI Flag") = ADS_SECURE_AUTHENTICATION

AdComm.CommandText = LDAPQry ' Set the ADO CommandText
Set AdRS = AdComm.Execute ' and run the query.

SiteAddrs = (2^31)-1 ' Really big range
AdRS.MoveFirst ' Go to 1st record in the set
While Not AdRS.EOF ' Read 'em until they're gone
Subnet = AdRs.Fields("cn") ' Get subnet name
MaskBits = Split(Subnet,"/") ' Split IP addr from subnet mask
NumAddrs = (2 ^ (32 - MaskBits(1))) - 1 ' Calc # addresses based on subnet mask
LoIPAddr = Dot2Dec(MaskBits(0)) ' Get low end of IP range in decimal
HiIPAddr = LoIPAddr + NumAddrs ' Calc high end of range by adding # add
' Check to see if IP is within this subnet range and if so that it's smallest subnet with that addr
If DecIPAddr => LoIPAddr And DecIPAddr <= HiIPAddr And NumAddrs <= SiteAddrs then
SiteName = AdRs.Fields("siteObject")
SiteName = GetObject("LDAP://" & AdRs.Fields("siteObject")).Get("name")
SiteAddrs = NumAddrs ' Remember # addrs in this subnet
End If
AdRS.MoveNext ' Go to next record or EOF
Wend

Set AdRs = Nothing
Set AdComm = Nothing
Set AdConn = Nothing
End Function

' Returns the decimal value of a dotted decimal IP address
Function Dot2Dec(IPAddress)
Dim Octets
Octets = Split(IPAddress,".")
Dot2Dec = (Octets(0)*(2^24)) + (Octets(1)*(2^16)) + (Octets(2)*(2^8)) + Octets(3)
End Function
 

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
zivkoCommented:
Hello,

If I remember well, even in that case the computer must be joined to the domain to be able to use the code below (query AD with a non-domain user account from a domain-joined computer).

If you want to use the code on a non-domain joined computer, you have to specify a server binding to a domain controller.

A more detailed explanation can be found here as well as a sample script to perform the operation you want: http://www.rlmueller.net/ADOAltCredentials.htm

Hope this will help.
Regards
0
 
dax_badCommented:
As Zivko mentioned above, which i completely missed out on :-)

Yes, you need to query the PDC of your domain when querying from a non joined pc.

try this

add to line 16:
 PDC = "PDCName" 'name of your Primary DC

Replace line 21 with this
LDAPQry = "<LDAP://" & PDC & "/" & SubnetContainer & ">;(objectCategory=subnet);cn,siteObject"
0
 
crazymysticAuthor Commented:
Hi Lads,

Thanks for your input. Daniel i have now manged to get this to work. script below attached. it seems that a combination of all our three observations needed it to work. I just couldn't get the code right!

not only do we need to pass it a DC but it needs to be added to two seperate parts within the function. Especially to the part of the function I have stated above. I got my local programmer to sort the code out for me to get it to work
Function SiteName(IPAddr)

Dim ConfigNameContext
Dim DecIPAddr, MaskBits, NumAddrs, LoIPAddr, HiIPAddr, SiteAddrs
Dim SubnetContainer, LDAPQry, Subnet
Dim AdConn, AdComm, AdRS

Dim dso, subnets

Dim strUserId, strDomain, strPassword
 
strUserId = "Username"
strDomain = "Domain"
strPassword = "password"

SiteName = "Default-First-Site-Name" ' Default site name if no matches
DecIPAddr = Dot2Dec(IPAddr) ' Convert supplied address to decimal

set dso = GetObject("LDAP:")

set subnets = dso.OpenDSObject("LDAP://DC.domain.com/cn=subnets,cn=sites,cn=configuration,dc=worleyparsons,dc=com", strUserId, strPassword, 1)

SiteAddrs = (2^31)-1 ' Really big range

For Each obj In subnets
	Subnet = obj.cn
	MaskBits = Split(Subnet,"/") ' Split IP addr from subnet mask
	NumAddrs = (2 ^ (32 - MaskBits(1))) - 1 ' Calc # addresses based on subnet mask
	LoIPAddr = Dot2Dec(MaskBits(0)) ' Get low end of IP range in decimal
	HiIPAddr = LoIPAddr + NumAddrs ' Calc high end of range by adding # add
	' Check to see if IP is within this subnet range and if so that it's smallest subnet with that addr
	If DecIPAddr => LoIPAddr And DecIPAddr <= HiIPAddr And NumAddrs <= SiteAddrs then
		set SiteName = dso.OpenDSObject("LDAP://DC.domain.com/" & obj.siteobject, strUserId, strPassword, 1)
		SiteName = SiteName.name
		SiteAddrs = NumAddrs ' Remember # addrs in this subnet
	End If
Next

Set AdRs = Nothing
Set AdComm = Nothing
Set AdConn = Nothing
End Function

' Returns the decimal value of a dotted decimal IP address
Function Dot2Dec(IPAddress)
Dim Octets
Octets = Split(IPAddress,".")
Dot2Dec = (Octets(0)*(2^24)) + (Octets(1)*(2^16)) + (Octets(2)*(2^8)) + Octets(3)
End Function

Open in new window

0
 
crazymysticAuthor Commented:
Hi Guys,

As you can see from the post above that the final code incorporates bits from both experts. I am a bit confused as to how to award the points.

would you mind sharing 250 each?
0
 
dax_badCommented:
It's up to you mate :-)

No problem here
0
 
zivkoCommented:
No problem here too...
0
 
crazymysticAuthor Commented:
Happy to close this.
0
 
dax_badCommented:
Think you need to add our comments as assisted solutions to awards us any points mate (not really sure how that all works)
0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 5
  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now