Some Useful AD Scripts

Here are some useful scripts that I came upon as a result of a recent project I worked on. Most of these scripts had already been written and were available for download of the web – some of these we took and changed to fit the requirement.

Always test these or any script in a test environment before running in your production environment– no matter how simple the script looks or seems!

The scripts discussed cover the following:

1. Enumerate Group Membership

2. Move Computers to a specific OU based on a list of PC’s in a text file

3. Link a GPO to an OU and Enforce it

4. Script to report on User logged on and various PC specific information

Before we go into them here is a useful tip for anyone who spends alot of their time doing command line stuff....

Instead of using the arrow keys to re-execute previously used commands hit F7 whilst in the command line and the list will appear in a little window like the one below:

clip_image001

Simply then select the command you require...

1. Enumerate Group Membership

This is a handy little script that we used to export the members of a particular Group to a text file. This particular group had alot of unnecessary members and we needed the list exported quickly.

The command line to execute the script is:

cscript EnumGroupMembers.vbs "Group Name" "Domain Name"

The script itself can be found here:

https://www.databasejournal.com/scripts/article.php/3499156

2. Move Computers into an OU

This script was used to move all of the PC’s listed in a text file to an OU. These PC’s were identified as stale or old workstation accounts and the plan was to search the directory and move these into an OU called Accts not used for 6mths. To identify the workstation accounts that were not logged onto the domain within 6 months we ran a dsquery command against the directory and piped the results to a text file.

Simple copy the script below into notepad and save it as a vbscript (.vbs)

Once you have your text file populated just change the lines highlighted in bold to suit your environment and you should be ready to go.

Option Explicit

Dim strDestOU, strObjToMove, strObjDN, objObjToMove

Dim strInputFile, objInputFile, strInputLine

Dim objFSO

Const ForReading = 1, ForWriting = 2, ForAppending = 8

Set objFSO = CreateObject("Scripting.FileSystemObject")

'WScript.Echo ADRoot

strInputFile = "E:\Apps\Move-Old-Computers-Script\OldComputers.txt"

strDestOU = "OU=Expired Computer Accounts,OU=Accts not used for 6mths,DC=contoso,DC=com"

Set objInputFile = objFSO.OpenTextFile(strInputFile, 1, True)

Do While Not objInputFile.AtEndOfStream

objObjToMove = "" 'Reset variable

strInputLine = objInputFile.ReadLine

strObjToMove = strInputLine & "$" 'Append $ - Needed for computer objects

'WScript.Echo strObjToMove

strObjDN = GetObjDN(strObjToMove, "computer")

'WScript.Echo ":::" & strObjDN

If strObjDN <> "" Then

Set objObjToMove = GetObject("LDAP://" & strObjDN)

'WScript.Echo objObjToMove.Name

Call MoveUserToOU(strObjDN, strDestOU)

Else

WScript.Echo "Cant' find object in AD: " & strObjToMove

End If

Loop

WScript.Quit

'****************************************************************************************

'****************************************************************************************

Function MoveUserToOU(strUserDN, strDestOU)

'Moves a user to a new OU

'Just pass the DNs of the target OU and the user object

Dim objOU

Set objOU = GetObject("LDAP://" & strDestOU)

objOU.MoveHere "LDAP://" & strUserDN, vbNullString

End Function

Function GetObjDN(sObjShortName, sObjType)

'This function queries AD for a user by SAMAccountName and returns the distinguishedName for it

'(DN is used for LDAP binds...)

Dim sDomainADsPath, sProperties, strCmdTxt

Dim sUser, sPassword

Dim oCon, oCmd, oRecordSet

Dim intRecordCount

sDomainADsPath = "LDAP://" & ADRoot

Set oCon = CreateObject("ADODB.Connection")

oCon.Provider = "ADsDSOObject"

oCon.Open "ADProvider", sUser, sPassword

Set oCmd = CreateObject("ADODB.Command")

Set oCmd.ActiveConnection = oCon

'sProperties = "name,ADsPath,description,mail,memberof"

sProperties = "distinguishedname"

strCmdTxt = "<" & sDomainADsPath & ">;(&(objectCategory=" & sObjType & ")(SamAccountName=" & sObjShortName & "));" & sProperties & ";subtree"

'WScript.Echo strCmdTxt

oCmd.CommandText = strCmdTxt

oCmd.Properties("Page Size") = 100

On Error Resume Next

Set oRecordSet = oCmd.Execute

On Error goto 0

intRecordCount = oRecordSet.RecordCount

If intRecordCount = 1 Then

oRecordSet.MoveFirst

While Not oRecordSet.EOF

Dim strObjDN, arrObjDN, strDNPart, intDNPart, intOUDNEntry

'Get the object's distinguishedname

strObjDN = oRecordSet.Fields("distinguishedname")

oRecordSet.MoveNext

Wend

GetObjDN = strObjDN

Else

WScript.Echo "ERROR: Expected exactly 1 record from AD. Records received = " & oRecordSet.RecordCount

'GetObjDN = False

End If

End Function ' End of GetObjDN Function

Function ADRoot()

Dim oRootDSE

On Error Resume Next

Set oRootDSE = GetObject("LDAP://RootDSE")

'If Err.Number <> 0 Then

'ADRoot = "DC=DS,DC=AD,DC=SSMHC,DC=com"

'Else

ADRoot = oRootDSE.Get("defaultNamingContext")

'End If

End Function

3. Link a GPO to an OU

This script is really clever and one I have had to use twice in the last 8 months on different projects. It basically links a GPO to a specific OU.

The script can be found here:

https://support.microsoft.com/kb/248392

If you want to go a step further and enforce the GPO you have just linked – the script to do this can be found here.

https://techtasks.com/code/viewbookcode/1690

4. Script to report on User Specific Information

This vbscript has been around for a while and I have even seen versions of it that actually report on printers installed, drive mappings and other user profile related information. I have seen organisations use this or similar scripts to this in environments where they may not have sophisticated PC management technologies deployed or even for laptop/remote users who call a helpdesk with an issue – it enables the IT personnel to quickly get the information they require by instructing the user to click on the script which may have been deployed to their desktop. There are various methods to deploy this to an organisations pc environment – the easiest is via a login script or by using Group Policy to deploy it via a Computer Startup Script – it really depends where you want to place the script and the permissions required to do so.

The output is a little window that appears with the following information. The code for the script can be seen below.

clip_image003

Set objExplorer = WScript.CreateObject("InternetExplorer.Application")

objExplorer.Navigate "about:blank - IT Department"

objExplorer.ToolBar = 0

objExplorer.StatusBar = 0

objExplorer.Width=570

objExplorer.Height = 500

objExplorer.Left = 80

objExplorer.Top = 20

objExplorer.Document.Body.InnerHTML = headerstring

objExplorer.Visible = 1

Set WSHNetwork = WScript.CreateObject("WScript.Network")

strUserName = WSHNetwork.UserName

domainname = WSHNetwork.userDomain

Do While (objExplorer.Busy)

Wscript.Sleep 500

Loop

'Get the Computer's network name

Set objNet=CreateObject("wscript.Network")

objHost=objNet.ComputerName

'Get a connection to the WMI NetAdapteConfig object

Set NIC1 = GetObject("winmgmts:").InstancesOf("Win32_NetworkAdapterConfiguration")

'For Each of the NICs in the connection

For Each Nic in NIC1

'Get the Adapter Description

StrNIC = Nic.Description

'If IP is enabled on the NIC then let's find out about the NIC

IF Nic.IPEnabled THEN

lngCount=UBound(Nic.IPAddress)

StrIP = Nic.IPAddress(i)

If StrIP <> "" Then

headerstring = headerstring & "<br><font face=verdana color=black><font color=blue size=+1><b><center>" & " PC Details for " & strUsername & "</b></center>" & "<b><br><br><font face=verdana color=black><font color=black size=+1><b><left>" & " Your Computers Name is: " & "<font face=verdana color=black><font color=blue size=+2>" & objHost & "<br><br><font color=black size=-1>Your IP Address is: " & "<font face=verdana color=black><font color=blue size=-1>" & StrIP

exit for

END IF

end if

next

'headerstring= headerstring & "<font face=verdana size=-1 color=blue><b> IT Department - TroubleShooter<br><font color=black><br>"

'msgbox domainname

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br> Your Username is <font color=blue>" & strUserName & "</font> and you are logged on into the <font color=blue>" & domainname & "</font> domain.<br>"

Set UserObj = GetObject("WinNT://" & domainname & "/" & strUserName & ",User")

lastlogintime = UserObj.lastlogin

dtmBootup = UserObj.lastlogin

dtmLastBootupTime = cdate(dtmBootup)

'msgbox dtmBootup & " " & now

dtmLastBootupTimeonly = WMIDateStringTotime(dtmBootup)

dtmSystemUptime = DateDiff("h", dtmLastBootUpTime, Now)

uptime = formatnumber(dtmSystemUptime/24,0)

if uptime > 0 then

'headerstring = headerstring & "<font face=verdana size=-1 color=black>Last logon time : <font color=blue>( " & formatnumber(dtmSystemUptime/24,0) & " days ago) " & lastlogintime & "</font> (estimated).<br>"

elseif uptime = 0 then

'headerstring = headerstring & "<font face=verdana size=-1 color=black>You logged in <font color=blue> today at <font color=blue>" & right(dtmLastBootupTime,8) & "</font> (estimated).<br>"

else

'headerstring = headerstring & "<font face=verdana size=-1 color=black>System error trying to figure out last login time" & "</font> (estimated).<br>"

end if

'Model Number and serial Number

syslocale=false

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=delegate}!\\" & strComputer & "\root\cimv2")

Set colSettings = objWMIService.ExecQuery _

("Select * from Win32_ComputerSystem")

For Each objComputer in colSettings

sysModel= objComputer.Model

next

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=delegate}!\\" & strComputer & "\root\cimv2")

Set colBIOS = objWMIService.ExecQuery _

("Select * from Win32_BIOS")

For each objBIOS in colBIOS

sysSerialNo = objBIOS.SerialNumber

next

if sysModel = "Marlin" or sysSerialNo = "" or isnull(sysSerialNo) then

'can't get the serial number from the bios - try from the network comments (last resort)

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=delegate}!\\" & strComputer & "\root\cimv2")

Set Obj= GetObject("winmgmts:").InstancesOf("Win32_OperatingSystem")

For Each x In Obj

descString = x.Description

commapos = instr(descstring,",")

if commapos <> 0 then

sysmodel = left(descString, commapos-1)

sysSerialNo = right(descString,commapos-1)

else

donotupdate = TRUE

end if

Next

end if

if donotupdate = False then

headerstring = headerstring & "<font face=verdana size=-1 color=black><br>The PC Model type is <font color=blue>" & sysmodel & "</font>, Serial No. is <font color=blue>" & sysSerialNo

end if

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _

("Select * from Win32_OperatingSystem")

For Each objOS in colOperatingSystems

dtmBootup = objOS.LastBootUpTime

dtmLastBootupTime = WMIDateStringToDate(dtmBootup)

dtmLastBootupTimeonly = WMIDateStringTotime(dtmBootup)

dtmSystemUptime = DateDiff("h", dtmLastBootUpTime, Now)

uptime = formatnumber(dtmSystemUptime/24,0)

if uptime > 0 and uptime < 10 then

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>This system has been running for <font color=blue size=+2>" & formatnumber(dtmSystemUptime/24,0) & " </font>days.<br><br>" & " It hasn't been rebooted since <font color=blue>" & dtmLastBootupTime & "<br>"

elseif uptime >= 10 then

headerstring = headerstring & "<font face=verdana size=+1 color=blue><br><br>Please restart this PC it has been up for <font color=blue size=+2>" & formatnumber(dtmSystemUptime/24,0) & " </font>days!<br><br>" & "<font color=black size =-1> It hasn't been rebooted since <font color=blue>" & dtmLastBootupTime

elseif uptime = 0 then

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>This system was powered on today at <font color=blue>" & dtmLastBootupTimeonly

else

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>System error trying to figure out uptime"

end if

Next

syslocale=false

strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colSettings = objWMIService.ExecQuery _

("Select * from Win32_ComputerSystem")

For Each objComputer in colSettings

sysMemory= objComputer.TotalPhysicalMemory

next

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>There is <font color=blue>" & formatnumber(sysMemory/1000000,0) & "MB </font> of RAM installed,"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * from Win32_PerfRawData_PerfOS_Memory",,48)

For Each objItem in colItems

headerstring = headerstring & "<font face=verdana size=-1 color=black> of this there is <font color=blue>" & objItem.AvailableMBytes & "MB </font>not in use <font color=blue>(" & formatnumber(((objItem.AvailableMBytes*1000000/sysMemory)*100),0) & "% free)</font>"

next

Const HARD_DISK = 3

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colDisks = objWMIService.ExecQuery ("Select * from Win32_LogicalDisk Where DriveType = " & HARD_DISK & "")

For Each objDisk in colDisks

DiskSize = objDisk.Size

FreeDiskSpace = objDisk.FreeSpace

Next

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>There is a <font color=blue>" & formatnumber(DiskSize/1000000000,0) & "GB </font>HardDisk installed and there is <font color=blue>" & formatnumber(FreeDiskSpace/1000000000,2) & "GB </font>left on this disk <font color=blue>(" & formatnumber((FreeDiskSpace/DiskSize)*100,0) & "% Freespace)</font>"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor",,48)

For Each objItem in colItems

headerstring = headerstring & "<font face=verdana size=-1 color=black><br><br>The CPU runs at <font color=blue>" & objItem.MaxClockSpeed & "Mhz</font>." 'It is currently at a <font color=blue>" & objItem.LoadPercentage & "%</font> load."

Next

objExplorer.Document.Body.InnerHTML = headerstring

objExplorer.Visible = 1

Function WMIDateStringToDate(dtmBootup)

WMIDateStringToDate = CDate(Mid(dtmBootup, 7, 2) & "/" & _

Mid(dtmBootup, 5, 2) & "/" & Left(dtmBootup, 4) _

& " " & Mid (dtmBootup, 9, 2) & ":" & _

Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup, _

13, 2))

End Function

Function WMIDateStringToTime(dtmBootup)

if mid(right(dtmBootup,4),1,1) = "+" then

WMIDateStringToTime = CDate(Mid (dtmBootup, 9, 2) & ":" & _

Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup, _

13, 2))

else

WMIDateStringToTime = CDate(Mid(dtmBootup, 12, 2) & ":" & _

Mid(dtmBootup, 15, 2) & ":" & Mid(dtmBootup, _

18, 2))

end if

End Function

 

Disclaimer

The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.