Solved

VBScript needed to be run from Non domain PC

Posted on 2010-08-29
11
1,442 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
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
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

Hello again, all.  For those of you that have been following along, you'll know that this is my third article on this topic (though it is not Part III).  This article is sort of remedial, and probably the topic with which I should have started the s…
Welcome, welcome!  If you are new to the series and haven't been following along, please take a brief moment to review the first three installments: Part 1 (http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/A_266-VBScri…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

821 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