Archive

Archive for the ‘Scripting’ Category

VBScript: Query multiple servers on any domain from AD or a text file.

March 16, 2011 Leave a comment

I had a requirement to query AD for all servers then gather their network config.  I then found that there were servers in AD that had been shut down but not cleaned up, so the script failed on the first unreachable server, so I had to output a list from AD to a text file then re-work the script to read from that text file.  In this article I’ll show both methods, the worker code and how I output the list of servers.

Enumerate all servers in the domain and query their NIC settings:

Option Explicit

Dim objRootDSE, strDNSDomain, adoConnection, adoCommand, strQuery
Dim adoRecordset, strComputerName, strBase, strFilter, strAttributes

' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for all computers.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"

' Filter on computer objects with server operating system.
strFilter = "(&(objectCategory=computer)(operatingSystem=*server*))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "cn"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute

' Enumerate computer objects with server operating systems.
Do Until adoRecordset.EOF

    ' Worker Code: Enumerate computer objects with server operating systems
    strComputerName = adoRecordset.Fields("cn").Value
    Wscript.Echo "================================="
    Wscript.Echo "Computer Name: " & strComputerName
    Wscript.Echo "================================="
    ' Bind to CIMV2 on each Server
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputerName & "\root\cimv2")
    ' Gather Network Adapter Configuration
    Set colAdapters = objWMIService.ExecQuery _
        ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
    n = 1
    WScript.Echo
    For Each objAdapter in colAdapters
        WScript.Echo
        ' Display NIC Name
        WScript.Echo "Network Adapter " & n
        WScript.Echo "================="
        WScript.Echo "  Description: " & objAdapter.Description
        ' Display MAC address
        WScript.Echo "  Physical (MAC) address: " & objAdapter.MACAddress
        ' Display IP address
        If Not IsNull(objAdapter.IPAddress) Then
            For i = 0 To UBound(objAdapter.IPAddress)
                WScript.Echo "  IP address:             " & objAdapter.IPAddress(i)
            Next
        End If
        ' Display Subnet Mask
        If Not IsNull(objAdapter.IPSubnet) Then
            For i = 0 To UBound(objAdapter.IPSubnet)
                WScript.Echo "  Subnet:                 " & objAdapter.IPSubnet(i)
            Next
        End If
        ' Display Default Gateway
        If Not IsNull(objAdapter.DefaultIPGateway) Then
            For i = 0 To UBound(objAdapter.DefaultIPGateway)
                WScript.Echo "  Default gateway:        " & _
            objAdapter.DefaultIPGateway(i)
        Next
        End If
        ' Display DNS Server Search Order
        WScript.Echo
        WScript.Echo "  DNS"
        WScript.Echo "  ---"
        WScript.Echo "    DNS servers in search order:"
        If Not IsNull(objAdapter.DNSServerSearchOrder) Then
            For i = 0 To UBound(objAdapter.DNSServerSearchOrder)
                WScript.Echo "      " & objAdapter.DNSServerSearchOrder(i)
            Next
        End If
        WScript.Echo "    DNS domain: " & objAdapter.DNSDomain
        ' Display Suffix Search List
        If Not IsNull(objAdapter.DNSDomainSuffixSearchOrder) Then
            For i = 0 To UBound(objAdapter.DNSDomainSuffixSearchOrder)
                WScript.Echo "    DNS suffix search list: " & _
                objAdapter.DNSDomainSuffixSearchOrder(i)
            Next
        End If
        n = n + 1
    Next
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
Function WMIDateStringToDate(utcDate)
WMIDateStringToDate = CDate(Mid(utcDate, 5, 2)  & "/" & _
Mid(utcDate, 7, 2)  & "/" & _
Left(utcDate, 4)    & " " & _
Mid (utcDate, 9, 2) & ":" & _
Mid(utcDate, 11, 2) & ":" & _
Mid(utcDate, 13, 2))
End Function

Query AD for a list of servers by saving the following script as QueryADServers.vbs:

Option Explicit

Dim objRootDSE, strDNSDomain, adoConnection, adoCommand, strQuery
Dim adoRecordset, strComputerName, strBase, strFilter, strAttributes

' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for all computers.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"

' Filter on computer objects with server operating system.
strFilter = "(&(objectCategory=computer)(operatingSystem=*server*))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "cn"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute

' Enumerate computer objects with server operating systems.

Do Until adoRecordset.EOF

    ' Worker Code: Enumerate computer objects with server operating systems & display their names
    strComputerName = adoRecordset.Fields("cn").Value
        Wscript.Echo "Computer Name: " & strComputerName
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
Function WMIDateStringToDate(utcDate)
WMIDateStringToDate = CDate(Mid(utcDate, 5, 2)  & "/" & _
  Mid(utcDate, 7, 2)  & "/" & _
    Left(utcDate, 4)    & " " & _
      Mid (utcDate, 9, 2) & ":" & _
        Mid(utcDate, 11, 2) & ":" & _
          Mid(utcDate, 13, 2))
End Function

Output a list of servers to a text file by running the script thusly:

C:\>cscript //nologo QueryADServers.vbs > ServerList.txt

NB: Once I output the list of servers I fed the list into a batch file that ran an nslookup against them and removed the ones that didn’t have an entry in DNS.  The resulting ServerList.txt file is the one I used for the following script.

Query the ServerList.txt text file by running the following script from the same directory that the ServerList.txt file is in as Administrator:

Option Explicit

Dim objFSO, objFile, strLine, objWMIService, colAdapters, n, objAdapter, i

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("ServerList.txt", 1)

Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine

    ' Worker Code: Enumerate computer objects with server operating systems
    strComputerName = adoRecordset.Fields("cn").Value
    Wscript.Echo "================================="
    Wscript.Echo "Computer Name: " & strLine
    Wscript.Echo "================================="
    ' Bind to CIMV2 on each Server
    Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & strComputerName & "\root\cimv2")
    ' Gather Network Adapter Configuration
    Set colAdapters = objWMIService.ExecQuery _
        ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
    n = 1
    WScript.Echo
    For Each objAdapter in colAdapters
        WScript.Echo
        ' Display NIC Name
        WScript.Echo "Network Adapter " & n
        WScript.Echo "================="
        WScript.Echo "  Description: " & objAdapter.Description
        ' Display MAC address
        WScript.Echo "  Physical (MAC) address: " & objAdapter.MACAddress
        ' Display IP address
        If Not IsNull(objAdapter.IPAddress) Then
            For i = 0 To UBound(objAdapter.IPAddress)
                WScript.Echo "  IP address:             " & objAdapter.IPAddress(i)
            Next
        End If
        ' Display Subnet Mask
        If Not IsNull(objAdapter.IPSubnet) Then
            For i = 0 To UBound(objAdapter.IPSubnet)
                WScript.Echo "  Subnet:                 " & objAdapter.IPSubnet(i)
            Next
        End If
        ' Display Default Gateway
        If Not IsNull(objAdapter.DefaultIPGateway) Then
            For i = 0 To UBound(objAdapter.DefaultIPGateway)
                WScript.Echo "  Default gateway:        " & _
            objAdapter.DefaultIPGateway(i)
        Next
        End If
        ' Display DNS Server Search Order
        WScript.Echo
        WScript.Echo "  DNS"
        WScript.Echo "  ---"
        WScript.Echo "    DNS servers in search order:"
        If Not IsNull(objAdapter.DNSServerSearchOrder) Then
            For i = 0 To UBound(objAdapter.DNSServerSearchOrder)
                WScript.Echo "      " & objAdapter.DNSServerSearchOrder(i)
            Next
        End If
        WScript.Echo "    DNS domain: " & objAdapter.DNSDomain
        ' Display Suffix Search List
        If Not IsNull(objAdapter.DNSDomainSuffixSearchOrder) Then
            For i = 0 To UBound(objAdapter.DNSDomainSuffixSearchOrder)
                WScript.Echo "    DNS suffix search list: " & _
                objAdapter.DNSDomainSuffixSearchOrder(i)
            Next
        End If
        n = n + 1
    Next
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
Function WMIDateStringToDate(utcDate)
WMIDateStringToDate = CDate(Mid(utcDate, 5, 2)  & "/" & _
Mid(utcDate, 7, 2)  & "/" & _
Left(utcDate, 4)    & " " & _
Mid (utcDate, 9, 2) & ":" & _
Mid(utcDate, 11, 2) & ":" & _
Mid(utcDate, 13, 2))
End Function

If you save this script as QueryServersFromTextFile.vbs you can run it as follows to output the servers NIC configs to a text file:

C:\>cscript //nologo QueryServersFromTextFile.vbs > ServerNICs.txt

Sample output:

=================================
Computer Name: DC1.yourdomain.com
=================================

Network Adapter 1
=================
Description: HP Network Team #1
Physical (MAC) address: 00:11:22:33:44:55
IP address:             192.168.77.100
Subnet:                 255.255.255.0
Default gateway:        192.168.77.1

DNS
---
DNS servers in search order:
    192.168.77.10
    192.168.77.11
DNS domain: yourdomain.com
DNS suffix search list: theirdomain.com
DNS suffix search list: our-domain.com

Once again, thanks to Richard Mueller and the writers of WMI Script-O-Matic & EZ AD Script-O-Matic for enabling me to make my job so much easier.

Advertisements

Windows: service management with sc.exe

January 23, 2011 Leave a comment

In a previous post, I listed the net start and net stop commands for managing services.  The main drawback to these is that while they are on every Windows System, they only work on local services.

I’m all for utilities that reduce the amount of time it takes to get work done more efficiently (That’s one of the reasons I’m so fond of the CLI) and to that end, this post is about the Service Control (sc) utility that allows one to query & control services on remote servers, thus avoiding the need to RDP onto multiple servers and manage local services.

If you want to know which services are currently running on a remote server; DC1.your.domain.com for example, running the following command will output a long list of services and their status:

C:\>sc \\DC1.your.domain.com query

If you want more information on a specific service, such as a Windows DNS Server sc makes it easy to gather the required data.  To start with you can get the services display name:

C:\>sc \\DC1.your.domain.com GetDisplayName dns
[SC] GetServiceDisplayName SUCCESS  Name = DNS Server

You can also get the services description like so:

C:\>sc \\DC1.your.domain.com qdescription dns
[SC] GetServiceConfig SUCCESS 
SERVICE_NAME: dns        
    DESCRIPTION              : Enables DNS clients to resolve DNS names by
answering DNS queries and dynamic DNS update requests. If this service is
stopped, DNS updates will not occur. If this service is disabled, any
services that explicitly depend on it will fail to start.

You can quickly list the service configuration too:

C:\>sc \\DC1.your.domain.com qc dns
[SC] GetServiceConfig SUCCESS 
SERVICE_NAME       : dns        
TYPE               : 10  
WIN32_OWN_PROCESS        
START_TYPE         : 2   AUTO_START        
ERROR_CONTROL      : 1   NORMAL        
BINARY_PATH_NAME   : C:\WINDOWS\System32\dns.exe        
LOAD_ORDER_GROUP   :        
TAG                : 0        
DISPLAY_NAME       : DNS Server        
DEPENDENCIES       : Tcpip                          
                   : Afd                          
                   : RpcSs        
SERVICE_START_NAME : LocalSystem

NB: If you want extended information you can use the queryex parameter.

Then you can check the status of the service:

C:\>sc \\DC1.your.domain.com query dns 
SERVICE_NAME: dns        
TYPE               : 10  
WIN32_OWN_PROCESS        
STATE              : 4  RUNNING                                
                        (STOPPABLE,PAUSABLE,ACCEPTS_SHUTDOWN)        
WIN32_EXIT_CODE    : 0  (0x0)        
SERVICE_EXIT_CODE  : 0  (0x0)        
CHECKPOINT         : 0x0        
WAIT_HINT          : 0x0

Finally once you’ve gathered all the information you need, you can stop & start the service if you need to:

C:\>sc \\DC1.your.domain.com stop dns
SERVICE_NAME: dns        
    TYPE               : 10  WIN32_OWN_PROCESS        
    STATE              : 3  STOP_PENDING                                
                            (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)        
    WIN32_EXIT_CODE    : 0  (0x0)        
    SERVICE_EXIT_CODE  : 0  (0x0)        
    CHECKPOINT         : 0x1        
    WAIT_HINT          : 0x5265c00
C:\>sc \\DC1.your.domain.com query dns
SERVICE_NAME: dns        
    TYPE               : 10  WIN32_OWN_PROCESS        
    STATE              : 1  STOPPED        
    WIN32_EXIT_CODE    : 0  (0x0)        
    SERVICE_EXIT_CODE  : 0  (0x0)        
    CHECKPOINT         : 0x0        
    WAIT_HINT          : 0x0
C:\>sc \\DC1.your.domain.com start dns
SERVICE_NAME: dns        
    TYPE               : 10  
    WIN32_OWN_PROCESS        
    STATE              : 2  START_PENDING                                
                            (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)        
    WIN32_EXIT_CODE    : 0  (0x0)        
    SERVICE_EXIT_CODE  : 0  (0x0)        
    CHECKPOINT         : 0x0        
    WAIT_HINT          : 0x7d0        
    PID                : 608        
    FLAGS              :
C:\>sc \\DC1.your.domain.com query dns
SERVICE_NAME: dns        
    TYPE               : 10  
    WIN32_OWN_PROCESS        
    STATE              : 4  RUNNING                                
                            (STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)        
    WIN32_EXIT_CODE    : 0  (0x0)        
    SERVICE_EXIT_CODE  : 0  (0x0)        
    CHECKPOINT         : 0x0        
    WAIT_HINT          : 0x0

A list of sc parameters is as follows:

C:\>sc
DESCRIPTION:        
    SC is a command line program used for communicating with the        
    NT Service Controller and services.
USAGE:        
    sc <server> [command] [service name] <option1> <option2>...         

    The option <server> has the form "\\ServerName"        
    Further help on commands can be obtained by typing: "sc [command]"        
    Commands:          
        query-----------Queries the status for a service, or                          
        enumerates the status for types of services.          
        queryex---------Queries the extended status for a service, or                          
                        enumerates the status for types of services.          
        start-----------Starts a service.          
        pause-----------Sends a PAUSE control request to a service.          
        interrogate-----Sends an INTERROGATE control request to a service.          
        continue--------Sends a CONTINUE control request to a service.          
        stop------------Sends a STOP request to a service.          
        config----------Changes the configuration of a service (persistant).          
        description-----Changes the description of a service.          
        failure---------Changes the actions taken by a service upon failure.          
        sidtype---------Changes the service SID type of a service.          
        qc--------------Queries the configuration information for a service.          
        qdescription----Queries the description for a service.          
        qfailure--------Queries the actions taken by a service upon failure.          
        qsidtype--------Queries the service SID type of a service.          
        delete----------Deletes a service (from the registry).          
        create----------Creates a service. (adds it to the registry).          
        control---------Sends a control to a service.          
        sdshow----------Displays a service's security descriptor.          
        sdset-----------Sets a service's security descriptor.          
        showsid---------Displays the service SID string corresponding to an
                        arbitrary name.          
        GetDisplayName--Gets the DisplayName for a service.          
        GetKeyName------Gets the ServiceKeyName for a service.          
        EnumDepend------Enumerates Service Dependencies.         

    The following commands don't require a service name:        
    sc <server> <command> <option>          
        boot------------(ok | bad) Indicates whether the last boot should                          
        be saved as the last-known-good boot configuration          
        Lock------------Locks the Service Database          
        QueryLock-------Queries the LockStatus for the SCManager Database
EXAMPLE:        
    sc start MyService 
Would you like to see help for the QUERY and QUERYEX commands? [ y | n ]: n

Cross Forest User Lookup LDAP Query Script

January 19, 2011 Leave a comment

I had a requirement to query users over an external trust between two AD forests, so here it is:

Const ADS_SCOPE_SUBTREE = 2
Set rootDSE = GetObject("LDAP://rootDSE")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADSDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.CommandText = "SELECT * FROM 'LDAP://corporate.contoso.com/" _
"dc=corporate,dc=contoso,dc=com' WHERE objectCategory='user'"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Set objType = GetObject(objRecordSet.Fields("ADsPath").Value)
strDistinguishedName = objType.distinguishedName
wscript.echo strDistinguishedName
objRecordSet.MoveNext
Loop

Does exactly what it says on the tin.

Tips: Handy Windows Command Prompt Commands

January 16, 2011 1 comment

This is by no means an exhaustive list, merely ubiquitous commands that I use on a daily basis that will be updated periodically as I can be bothered.

List shares on a file server:

net share

List file locks on a file server:

net file

Close open files from the previous command:

net file <ID> /close

RDP to a specific host:

mstsc.exe /v <FQDN_or-IP-address>

Map network drive:

net use X: \\FQDN\Share$ /persistent:yes

Stop a service:

net stop a <service-name>

Start a service:

net start <service-name>
Categories: Microsoft, Scripting, Tips