Find PDC Emulator role holder - vbscript

Is there a way locate the server with the PDCE role using VBScript? I know I can use an NSLOOKUP and capture its output
nslookup -type=all _ldap._tcp.pdc._msdcs.mydomain.com
I want to use VBScript wihout calling external programs and it must run on a Windows 7 workstation (32 and 64bit) without additional software!
Thanks.

you can use NETDOM.EXE tool on server
netdom query /domain:DOM fsmo
Where DOM is my Netbios domain name
You can use DSQUERY.EXE tool
dsquery server -hasfsmo schema
(the five roles are: schema, rid, name, infr and pdc)
Determining FSMO Role Holders seems to be a good source
(Edited)
Here is an example of VBScript doing that using ADSI.

To determine the PDC Master you must query the fSMORoleOwner attribute on the partition corresponding to your domain.
Here is a sample VBS (visit http://adcoding.com/ for more information):
Set objDomDn = GetObject("LDAP://dc=concorp,dc=contoso,dc=com")
strfsmoRoleOwner = objDomDn.Get("fsmoRoleOwner")
Set objPDCfsmo = GetObject("LDAP://" & strfsmoRoleOwner)
Set objPDCfsmoParent = GetObject(objPDCfsmo.Parent)
Wscript.Echo objPDCfsmoParent.Get("dnsHostName")

Related

Discrepancy in timezone between timestamps for lastlogon using WMI commands

I'm trying to get the user's last logon in some Windows machines using WMI, but for some reason, this information is different for different commands when I think they should be the same.
The first command that I'm using is : PATH Win32_NetworkLoginProfile WHERE "Name='DOMAIN\\fakeuser'" GET LastLogon. The result for it is like below:
LastLogon
20181206093540.000000-480
The second command is: PATH Win32_NTLogEvent WHERE "(EventIdentifier =4648 OR EventIdentifier = 4647 OR EventIdentifier = 4634)" GET CategoryString, TimeGenerated, InsertionStrings
The result is like below (after some processing to find the last entry of category "Logon" linked to the "fakeuser", since the command returns a lot of information):
CategoryString
Logon
InsertionStrings
{"S-1-5-21-3457937927-2839227994-823803824-1104","DOMAIN$","DOMAIN","0x3e6","{00000000-0000-0000-0000-000000000000}","fakeuser","DOMAIN","{00000000-0000-0000-0000-000000000000}","localhost","localhost","0x64c","C:\Windows\System32\svchost.exe","999.999.99.999","0"}
TimeGenerated
20181206173540.580545-000
For what I understand for these two commands, the LastLogon in the first result should be the same of TimeGenerated in the second one. Am I misunderstood something?
In my preliminary research, I found a possible bug in the WMI Timestamps, but I don't know if it is the same problem.
Some additional information:
These commands are executed using a script that make a remote connection using WinRM connection (ports 5985 and 5986) and then executes the commands to get the info, but I also tried to connect in the machine using RDP and execute it in Powershell with wmic PATH.... The result is the same.
I tested it in Windows 10 and also in Windows Server 2012, but the scripted will be used in some other Windows versions.
To get the Event numbers for the log class, I used this link
After first comment, I noticed that the problem is in time zones. Are there any way to set timezone direct in these commands or convert timezones between them?

VBScript GetObject WINNT properties

I recently created a script for checking running services using the GetObject("WinNT://" & computer) method. It uses a .filter method to only get "Service" items. I have used similar scripts for querying other items from a computer. However, I can't seem to find a list of everything that I should be able to query from a computer using this connection (prior to the filter)
Would someone be able to point me in the correct direction for finding out all of the possible properties I can access when using this type of connection?
Check out the following section in MSDN:
ADSI Objects of WinNT
It describes the available objects and their methods and properties.

API for Detecting Windows Active Directory name/IP

I have a requirement to detect all users from local and Active Directory(if present) in Windows.
I have found that C API: NetQueryDisplayInformation() has also the option to retrieve the information from a "serverName", which is presumably an Active Directory which can be queried.
But how do I find out if ActiveDirectory is available/ and it's name ?
Thanks.
This information is available in WMI. In the Win32_ComputerSystem class (there will be a single instance per computer) has a Domain property containing the domain's name.
Another way of finding out domain name (if present) is to use WIN API ::DsGetDcName()
This one returns information about Active Dir server name in DOMAIN_CONTROLLER_INFO struct.
You get there all the domain information you need. Much sympler than using WMI :-)

How to Check if an user account exists or not (on local machine) in windows?

I am trying to verify whether a particular user exists on the local computer. The one solution that I can do is parsing the output of command Net user . But is there any better solution than this?
You can possibly use WMI with a query such as "select * from Win32_UserAccount where LocalAccount = True" or similar. If you are just looking for a specific account you can be able to restrict the WMI query more. See Win32_UserAccount. You may also just be able to use GetObject (which may be more efficient), but I don't know how to formulate that.
You can follow the template/code at http://snippets.dzone.com/posts/show/6967 (which is not relating to user accounts :-) to setup/create the WMI ActiveX object, execute the query, and enumerate the results.
Happy coding!

VBScript: Using WScript.Shell to Execute a Command Line Program That Accesses Active Directory

I'm attempting to execute a .NET (3.5) command line program from within a VBScript file which does two main things:
Connects to an Active Directory that is on the same domain as the server the script is hosted to retrieve an attribute value. I search AD using the first command line argument which is a username.
Creates a DTO using said attribute value and the second command line argument which is then used in a WCF service call.
When I run the application explicitly, everything works. Active Directory is accessed, the attribute is retrieved and the WCF service is called with the correct result (as verified by looking at the database).
(Edit: I apologize, I forgot to put what the actual issue was.)
When I run the script, it seems as though I can't access Active Directory in my .NET code (the MyProgram app).
The VBScript code:
Dim objResult
Set objShell = WScript.CreateObject("WScript.Shell")
objResult = objShell.Run("MyProgram " & strUsername & " 0", 1, True)
Does the WScript.Shell object need special permissions on the file? I've checked them and the Execute permission is there. Typically, the second argument I am passing to the .Run() method would be 6, I wanted it to be 1 for debugging.
Is there another way for me to execute a program in VBScript?
This is not a reply (I cant post comments), just few random ideas might be helpful. Unfortunately I've never dealt with citrix, only with regular windows servers.
_0. Ensure you're not a victim of Windows Firewall, or any other personal firewall that selectively blocks processes.
Add 10 minutes Sleep() to the first line of your .NET app, then run both VBScript file and your stand-alone application, run sysinternals process explorer, and compare 2 processes.
_1. Same tab, "command line" and "current directory". Make sure they are the same.
_2. "Environment" tab. Make sure they are the same. Normally child processes inherit the environment, but this behaviour can be easily altered.
The following check is required if by "run my script" you mean anything else then double-clicking the .VBS file:
_3. Image tab, "User". If they differ - it may mean user has no access to the network (like localsystem), or user token restricted to delegation and thus can only access local resources (like in the case of IIS NTLM auth), or user has no access to some local files it wants.
The issue turned out to be certificate-related. The WCF service called by the console app uses an X509 cert for authentication, which is installed on the servers that this script is hosted and run from.
On other servers, where the same services are consumed, the certificates were configured as follows:
winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s "certificate-name" -a "NETWORK SERVICE"
As they ran within the context of IIS. However, when the script was being run as it would in production, it's under the context of the user themselves. So, the script needed to be modified to the following:
winhttpcertcfg.exe -g -c LOCAL_MACHINE\My -s "certificate-name" -a "USERS"
Once that change was made, all was well. Thanks to everyone who offered assistance.
When you run WScript.Shell it runs under the local system account, this account has full rights on the machine, but no rights in Active Directory.
http://support.microsoft.com/kb/278319
Taking Shiraz's idea and running with it...
In your application, are you explicitly defining a domain User Account and Password to access AD?
When you are executing the application explicitly it may be inherently using your credentials (your currently logged in domain account) to interrogate AD. However, when calling the application from the script, I'm not sure if the application is in the System context.
A VBScript example would be as follows:
Dim objConnection As ADODB.Connection
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Properties("User ID") = "MyDomain\MyAccount"
objConnection.Properties("Password") = "MyPassword"
objConnection.Open "Active Directory Provider"
If this works, of course it would be best practice to create and use a service account specifically for this task, and to deny interactive login to that account.

Resources