Solved

VBScript needed to be run from Non domain PC

Posted on 2010-08-29
11
1,427 Views
Last Modified: 2012-05-10
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
Comment
Question by:crazymystic
  • 5
  • 4
  • 2
11 Comments
 
LVL 6

Expert Comment

by:dax_bad
Comment Utility
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
 
LVL 6

Expert Comment

by:dax_bad
Comment Utility
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
 

Author Comment

by:crazymystic
Comment Utility
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
 
LVL 4

Expert Comment

by:zivko
Comment Utility
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
 
LVL 6

Expert Comment

by:dax_bad
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Accepted Solution

by:
crazymystic earned 0 total points
Comment Utility
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
 

Author Comment

by:crazymystic
Comment Utility
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
 
LVL 6

Expert Comment

by:dax_bad
Comment Utility
It's up to you mate :-)

No problem here
0
 
LVL 4

Expert Comment

by:zivko
Comment Utility
No problem here too...
0
 

Author Comment

by:crazymystic
Comment Utility
Happy to close this.
0
 
LVL 6

Expert Comment

by:dax_bad
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Recently I finished a vbscript that I thought I'd share.  It uses a text file with a list of server names to loop through and get various status reports, then writes them all into an Excel file.  Originally it was put together for our Altiris server…
When it comes to writing scripts for a Client/Server computing environment it is essential to consider some way of enabling the authentication functionality within a script. This sort of consideration mainly comes into the picture when we are dealin…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video discusses moving either the default database or any database to a new volume.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now