Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

VBScript needed to be run from Non domain PC

Posted on 2010-08-29
11
Medium Priority
?
1,506 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
11 Comments
 
LVL 6

Expert Comment

by:dax_bad
ID: 33553121
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
ID: 33553151
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
ID: 33579165
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
Independent Software Vendors: 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!

 
LVL 4

Expert Comment

by:zivko
ID: 33625232
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
ID: 33625419
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
 

Accepted Solution

by:
crazymystic earned 0 total points
ID: 33680085
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
ID: 33680181
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
ID: 33684525
It's up to you mate :-)

No problem here
0
 
LVL 4

Expert Comment

by:zivko
ID: 33699900
No problem here too...
0
 

Author Comment

by:crazymystic
ID: 33714220
Happy to close this.
0
 
LVL 6

Expert Comment

by:dax_bad
ID: 33723782
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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
When you see single cell contains number and text, and you have to get any date out of it seems like cracking our heads.
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

609 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