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:
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.
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.