I have been tasked with a requirement to get the current patch level of number of computers within a domain. Currently with the help of code snippets used from many sources I have managed to come-up with the following:
My Approach was to check the July 2017 Patches first and then goto June 2017, then further down up to March 2017. I am quite new to VBScript and need advice :| (Only VBScript can be used due to many restrictions in the Server environments)
' Checks only servers
' Add Respective HotFixID in to respective Array
' Create a new Array if missing in Format "HotFixIDs<YYYY><MM>"
' Add the Array Name as the First in "HotFixIDArray"
'Enter the hotfix number to check for: ONLY the number, no letters here!
ComputerName = "."
Dim status
Dim found
Dim HotFixIDArray()
Set fso = CreateObject("Scripting.FileSystemObject" )
Set file = fso.OpenTextFile("C:\temp\tetran\patchstatus_2017.txt",2,1)
found = 0
HotFixIDArray = Array("HotFixIDs201707","HotFixIDs201706","HotFixIDs201705","HotFixIDs201704","HotFixIDs201703")
For i = 0 To UBound(HotFixIDArray) (
If found = 0 Then
'Check July 2017 Patches
Dim HotFixIDs201707()
HotFixIDs201707 = Array("4032955","4026061","4026059","4025877","4025872","4025674","4025497","4025409","4025398","4025397","4025343","4025341","4025339","4025337","4025336","4025333","4025331","4025240","4022914","4022748","4022746")
For j = 0 To UBound(HotFixIDs201707)
status = CheckParticularHotfix(ComputerName, HotFixIDs201707(j))
If status = True Then
file.writeLine ("The hotfix with number " & HotFixIDs201707(j) & " IS installed.")
found = 1
Exit For
Else
status = False
found = 0
Next
If found = 1 Then
file.writeLine ("2017 July Patch Installed")
Exit For
Else
'Check June 2017 Patches
Dim HotFixIDs201706()
HotFixIDs201706 = Array("3217845","4018106","4019204","4019263","4019264","4021903","4021923","4022008","4022010","4022013","4022715","4022717","4022718","4022719","4022722","4022724","4022726","4022883","4022884","4022887","4024402")
For j = 0 To UBound(HotFixIDs201706)
status = CheckParticularHotfix(ComputerName, HotFixIDs201706(j))
If status = True Then
file.writeLine ("The hotfix with number " & HotFixIDs201706(j) & " IS installed.")
found = 1
Exit For
Else
status = False
found = 0
Next
If found = 1 Then
file.writeLine ("2017 June Patch Installed")
Exit For
Else
'Check May 2017 Patches
Dim HotFixIDs201705()
HotFixIDs201705 = Array("4018196","4018466","4018556","4018821","4018885","4018927","4019149","4019206","4019213","4019214","4019215","4019216","4019472")
For j = 0 To UBound(HotFixIDs201705)
status = CheckParticularHotfix(ComputerName, HotFixIDs201705(j))
If status = True Then
file.writeLine ("The hotfix with number " & HotFixIDs201705(j) & " IS installed.")
found = 1
Exit For
Else
status = False
found = 0
Next
If found = 1 Then
file.writeLine ("2017 May Patch Installed")
Exit For
Else
'Check April 2017 Patches
Dim HotFixIDs201704()
HotFixIDs201704 = Array("3211308","3217841","4014652","4014793","4014794","4015068","4015195","4015217","4015380","4015383","4015546","4015547","4015548","4015549","4015550","4015551","4020535")
For j = 0 To UBound(HotFixIDs201704)
status = CheckParticularHotfix(ComputerName, HotFixIDs201704(j))
If status = True Then
file.writeLine ("The hotfix with number " & HotFixIDs201704(j) & " IS installed.")
found = 1
Exit For
Else
status = False
found = 0
Next
If found = 1 Then
file.writeLine ("2017 April Patch Installed")
Exit For
Else
'Check March 2017 Patches
Dim HotFixIDs201703()
HotFixIDs201703 = Array("3211306","3214051","3217587","3217882","3218362","4011981","4012021","4012212","4012213","4012214","4012215","4012216","4012217","4012373","4012497","4012583","4012584","4012598","4013429","4017018")
For j = 0 To UBound(HotFixIDs201703)
status = CheckParticularHotfix(ComputerName, HotFixIDs201703(j))
If status = True Then
file.writeLine ("The hotfix with number " & HotFixIDs201703(j) & " IS installed.")
found = 1
Exit For
Else
status = False
found = 0
Next
If found = 1 Then
file.writeLine ("2017 March Patch Installed")
Exit For
Else
'Do nothing
'201703 End
'201704 End
'201705 End
'201706 End
'201707 End
If found = 0 Then
'Do nothing
Else
'Do nothing
Else
Exit For
)
Next
File.close
Private Function CheckParticularHotfix(strPuter, strHotfixID)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Version 1.0
' Checks if a particular hotfix is installed or not.
' This function has these 3 return options:
' TRUE, FALSE, <error description>
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strPuter & "\root\cimv2")
If err.number <> 0 Then
CheckParticularHotfix = "WMI could not connect to computer '" & strPuter & "'"
Exit Function 'No reason to continue
End If
strWMIforesp = "Select * from Win32_QuickFixEngineering where HotFixID = 'Q" & strHotfixID &_
"' OR HotFixID = 'KB" & strHotfixID & "'"
Set colQuickFixes = objWMIService.ExecQuery (strWMIforesp)
If err.number <> 0 Then 'if an error occurs
CheckParticularHotfix = "Unable to get WMI hotfix info"
Else 'Error number 0 meaning no error occured
tal = colQuickFixes.count
If tal > 0 Then
CheckParticularHotfix = True 'HF installed
Else
CheckParticularHotfix = False 'HF not installed
End If
End If
Set colQuickFixes = Nothing
Err.Clear
On Error Goto 0
End Function
Finally got around and managed to fix the VBScript :)
'Enter the name of the computer to check: (Replace the dot with a computer name, to connect to a remote computer)
ComputerName = "."
'Creates the FileSystemObject and use it to read the file "patch2017.txt"
Set fso = CreateObject("Scripting.FileSystemObject" )
Set file = fso.OpenTextFile("C:\temp\Patch\patch2017.txt",2,1)
'Variable to identify the installation status
Dim j
j = 0
'July 2017 Patches
'Enter the hotfix number to check for: (ONLY the number, no letters here!)
HotFixID = Array("4032955","4026061","4026059","4025877","4025872","4025674","4025497","4025409","4025398","4025397","4025343","4025341","4025339","4025337","4025336","4025333","4025331","4025240","4022914","4022748","4022746")
For i = 0 To UBound(HotFixID)
status = CheckParticularHotfix(ComputerName, HotFixID(i))
If status = True Then
j = 1
File.WriteLine("July 2017")
Exit For
End If
Next
'June 2017 Patches
HotFixID = Array("3217845","4018106","4019204","4019263","4019264","4021903","4021923","4022008","4022010","4022013","4022715","4022717","4022718","4022719","4022722","4022724","4022726","4022883","4022884","4022887","4024402")
For i = 0 To UBound(HotFixID)
status = CheckParticularHotfix(ComputerName, HotFixID(i))
If status = True Then
j = 1
File.WriteLine("June 2017")
Exit For
End If
Next
'May 2017 Patches
HotFixID = Array("4018196","4018466","4018556","4018821","4018885","4018927","4019149","4019206","4019213","4019214","4019215","4019216","4019472")
For i = 0 To UBound(HotFixID)
status = CheckParticularHotfix(ComputerName, HotFixID(i))
If status = True Then
j = 1
File.WriteLine("May 2017")
Exit For
End If
Next
'April 2017 Patches
HotFixID = Array("3211308","3217841","4014652","4014793","4014794","4015068","4015195","4015217","4015380","4015383","4015546","4015547","4015548","4015549","4015550","4015551","4020535")
For i = 0 To UBound(HotFixID)
status = CheckParticularHotfix(ComputerName, HotFixID(i))
If status = True Then
j = 1
File.WriteLine("April 2017")
Exit For
End If
Next
'March 2017 Patches
HotFixID = Array("3211306","3214051","3217587","3217882","3218362","4011981","4012021","4012212","4012213","4012214","4012215","4012216","4012217","4012373","4012497","4012583","4012584","4012598","4013429","4017018")
For i = 0 To UBound(HotFixID)
status = CheckParticularHotfix(ComputerName, HotFixID(i))
If status = True Then
j = 1
file.WriteLine("March 2017")
Exit For
End If
Next
file.Close
'**************************************
'* Read file and produce and output *
'* Only if the File is not Empty *
'* If File is empty output UNKNOWN *
'**************************************
If (fso.FileExists("C:\temp\Patch\patch2017.txt")) Then
If (fso.GetFile("C:\temp\Patch\patch2017.txt").Size <> 0) Then
Dim firstLine
Set firstLine = fso.OpenTextFile("C:\temp\Patch\patch2017.txt",1)
WScript.Echo firstLine.ReadLine
firstLine.Close
Else
WScript.Echo "UNKNOWN"
End If
End If
'*********************************************************************
'* This Function checks if a particular hotfix is installed or not *
'* This function has these 3 return options: *
'* TRUE, FALSE, <error description> *
'*********************************************************************
Private Function CheckParticularHotfix(strPuter, strHotfixID)
On Error Resume Next
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strPuter & "\root\cimv2")
If err.number <> 0 Then
CheckParticularHotfix = "WMI could not connect to computer '" & strPuter & "'"
Exit Function
End If
strWMIforesp = "Select * from Win32_QuickFixEngineering where HotFixID = 'Q" & strHotfixID &_
"' OR HotFixID = 'KB" & strHotfixID & "'"
Set colQuickFixes = objWMIService.ExecQuery (strWMIforesp)
If err.number <> 0 Then
CheckParticularHotfix = "Unable to get WMI hotfix info"
Else
tal = colQuickFixes.count
If tal > 0 Then
CheckParticularHotfix = True 'HF installed
Else
CheckParticularHotfix = False 'HF not installed
End If
End If
Set colQuickFixes = Nothing
Err.Clear
On Error Goto 0
End Function
I have a script that I put together for my users a few years ago for them to log onto to the company drive shares after they had logged into the VPN. The script has worked well over the years with a few tweaks needed here and there due to IE version upgrades. As of today I can no longer get the script to function properly the Error is:
Line: 93
Char: 5
Error: Permission denied: 'objIE.Document.parentWindow.screen'
Code: 800A0046
Source: Microsoft VBScript runtime error
I'm not sure what has changed but after doing multiple searches on the error codes and other items I figured I'd post it here and see if any of you can help me with this problem.
dim WshNetwork
Dim arrFileLines()
'On Error Resume Next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("Drive Shares.txt", 1)
If Not err.number = 0 then
WScript.Echo "Drive Shares.txt was not found. Please ensure that it is in the same directory as this script file"
WScript.Quit
End If
NumElements = 0
Do Until objFile.AtEndOfStream
Redim Preserve arrFileLines(NumElements)
arrFileLines(NumElements) = objFile.ReadLine
NumElements = NumElements + 1
Loop
objFile.Close
strPw = GetPassword()
If strPw = "" Then
wScript.Quit
End If
SplitPasswd = Split(StrPW,"*",2)
username = "DEFAULT\" & SplitPasswd(0)
password = SplitPasswd(1)
Set WshNetwork = Wscript.CreateObject("WScript.Network")
For Count = 0 to (NumElements - 1)
SplitDriveInfo = Split(arrFileLines(Count)," ",2)
DriveLetter = SplitDriveInfo(0)
Share = SplitDriveInfo(1)
ExitCode = WshNetwork.MapNetworkDrive(DriveLetter, Share, false, username, password)
ErrorHandler(err.number)
Next
Sub ErrorHandler(ErrorNumber)
Select Case ErrorNumber
Case 0
'OK
Exit Sub
Case -2147024811
'Already Mapped Continue
Exit Sub
Case -2147024843
'No Connection
WScript.Echo "No connection found. Confirm you have an internet connection and that you have the VPN connected."
WScript.Quit
Case -2147024829
'Share not available
WScript.Echo "The drive share you are trying to connect to does not exist on this server."
WScript.Quit
Case -2147023570
'Invalid username or password
WScript.Echo "Invalid username or password. Please try again."
WScript.quit
Case Else
WScript.Echo "Unknown error: " & CStr(ErrorNumber)
WScript.Quit
End Select
End Sub
Function GetPassword()
Dim objIE
Set objIE = CreateObject( "InternetExplorer.Application" )
objIE.Navigate "about:blank"
objIE.Document.Title = "Login Credentials"
objIE.ToolBar = False
objIE.Resizable = False
objIE.StatusBar = False
objIE.Width = 320
objIE.Height = 320
With objIE.document.parentWindow.screen
objIE.Left = (.availwidth - objIE.Width ) \ 2
objIE.Top = (.availheight - objIE.Height) \ 2
End With
objIE.Document.Body.InnerHTML = "<DIV align=""center""><P>Please enter your credentials</P>" & vbCrLf _
& "<DIV align=""center""><P>Username</P>" & vbCrLf _
& "<P><INPUT TYPE=""Username"" SIZE=""20"" " _
& "ID=""UserName""></P>" & vbCrLf _
& "<DIV align=""center""><P>Password</P>" & vbCrLf _
& "<P><INPUT TYPE=""password"" SIZE=""20"" " _
& "ID=""Password""></P>" & vbCrLf _
& "<P><INPUT TYPE=""hidden"" ID=""OK"" " _
& "NAME=""OK"" VALUE=""0"">" _
& "<INPUT TYPE=""submit"" VALUE="" OK "" " _
& "OnClick=""VBScript:OK.Value=1""></P></DIV>"
objIE.Visible = True
Do While objIE.Document.All.OK.Value = 0
WScript.Sleep 200
Loop
GetPassword = objIE.Document.All.UserName.Value & "*" & objIE.Document.All.Password.Value
objIE.Quit
Set objIE = Nothing
End Function
Any help with this would be greatly appreciated.
Microsoft released hotfix:[KB3025390] http://support.microsoft.com/kb/3025390
I can confirm uninstalling this update will resolve issue if it worked just prior to December 17th, 2014.
I had a similar problem with an HTA program using IE 11 and the With objIE.Document.ParentWindow.Screen command.
I found adding objIE.left = 910 and objIE.top and removed the With objIE.Document.ParentWindow.Screen section and now the IE Windows opens fine.
Sub AdditionalComputerInfo
'v3.00 - Changed to HTML Output
strComputer = trim(txtComputerName.Value)
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.ToolBar = 0
objIE.StatusBar = 0
objIE.addressbar = 0
objIE.Width = 650
objIE.Height = 900
'added v3.02
objIE.Left = 910
objIE.Top = 20
objIE.Document.Title = " " & uCase(strComputer) & " Information"
'With objIE.Document.ParentWindow.Screen removed in version 3.02
' objIE.Left = 910
' objIE.Top = 20
'End With
Set objDoc = objIE.Document.Body
In the code bellow I get an error on the line reading recset.Close.
Char: 5
Error: Operation is not allowed when the object is closed.
Code: 800A0E78
Source: ADODB.Recordset
If the program reaches the line PQ_ID_number = InputBox("Enter PQ Database ID number, Do not use / ? < > \ : * | !", "PQ ID Number", "Replace Text") it seems to work fine (taking manual input) but when it tries to get the ID from the URL of a browser (automaticaly) it gives the error.
valid_name = 0
Dim objInstances, objIE, counterTab
Do While valid_name = 0 'Flag to exit the loop if the Id number has content in the SQL Database'
'-----------------------------------------------------------------------------------------'
Set objInstances = CreateObject("Shell.Application").windows
If objInstances.Count > 0 Then '/// make sure we have IE instances open.
'Loop through each tab.'
For Each objIE In objInstances
'Split the url of current tab using /'
splitURL = Split(objIE.LocationURL,"/")
'Count how many sub strings are in the URL when split'
counter = UBound(splitURL)
if counter = 7 Then
lastSplit = Split(splitURL(7),".")
lastURL = splitURL(0) & "//" & splitURL(2) & "/" & splitURL(3) & "/" & splitURL(4) & "/" & splitURL(5) & "/" & splitURL(6) & "/" & lastSplit(0)
if lastURL = "URL" Then
Set IE = objIE
counterTab = counterTab + 1
end if
end if
'End if
Next
Else
'If no internet explorer window is open.'
MsgBox "No Internet Explorer window found."
wscript.quit
End if
'Check if no [] is open in internet explorer'
if IsObject(IE) Then
url = Split(IE.LocationURL,"=")
url2 = Split(url(1),"&")
PQ_ID_number = url2(0)
else
MsgBox "No incident found."
wscript.quit
end if
'counterTab counts how many [] are open. If there is more than 1, ask for confirmation of last [] number.'
if counterTab > 1 Then
confirm = msgbox("Please confirm Incident ID: " & incidentID,vbYesNo,"Confirmation")
'If no is pressed, ask for manual entry.'
if confirm = vbNo Then
PQ_ID_number = InputBox("Enter PQ Database ID number, Do not use / ? < > \ : * | !", "PQ ID Number", "Replace Text")
On Error Resume Next
If PQ_ID_number = False Then
wscript.quit
End If
end if
end if
'-----------------------------------------------------------------------------------------'
'Open connection in Database'
dbConnectStr = "connection string"
Set con = CreateObject("ADODB.Connection")
Set recset = CreateObject("ADODB.Recordset")
con.Open dbConnectStr
'Get PQ Database title and status of incident number provided.
SQL_String = "Select title, status_id from incident_TBL where incident_ID = " & PQ_ID_number
recset.Open SQL_String, con
title = recset.Fields(0).Value
incidentStatus = recset.Fields(1).Value
con.Close
recset.Close
If title = False Then 'check if PQ_ID given has content in SQL Database
wscript.echo "Invalid PQ Database ID number, please type correct number"
valid_name = 0
Else
valid_name = 1
End If
Loop
Thanks for the help!
you need close Recordset first and only after that close connection
con.Close
recset.Close
change to:
recset.Close
con.Close
So I've got an XP Pro workstation that is reporting "Windows cannot connect to the domain, either because the domain controller is down or otherwise unavailable, or because your computer account was not found. Please try again later. If this message continues to appear, contact your system administrator for assistance." when logging in with domain credentials. To fix this manually I would simply log in with the local admin account, drop it to a workgroup, and re-add it to the domain. This process however can take a decent amount of time considering this issue crops up at my work rather frequently. What I'm trying to do is programmatically automate the dropping/rejoining process. The following code works, but only if the computer is correctly in a domain or workgroup, not in limbo like it is now.
Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
Const ACCT_DELETE = 4
Const WIN9X_UPGRADE = 16
Const DOMAIN_JOIN_IF_JOINED = 32
Const JOIN_UNSECURE = 64
Const MACHINE_PASSWORD_PASSED = 128
Const DEFERRED_SPN_SET = 256
Const INSTALL_INVOCATION = 262144
Const WbemAuthenticationLevelPktPrivacy = 6
'On Error Resume Next
SystemName = "SystemName"
strNamespace = "root\cimv2"
ComputerBLogin = "LoginB"
ComputerBPass = "PassB"
ComputerALogin = "LoginA"
ComputerAPass = "PassA"
DomainName = "domain.com"
OU = "OU=desiredou,DC=domain,DC=com"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")
If Err.Number <> 0 Then
Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy
Err.Clear
End IF
Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
Return = objComputer.UnJoinDomainOrWorkGroup(NULL, NULL)
Return = objComputer.JoinDomainOrWorkGroup("WORKGROUP", NULL, NULL)
If Err.Number <> 0 Then
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup (SystemName & " could not be dropped to the workgroup!" & vbCr &_
"Error: " & Err.Description,, "Title", 0 + 16)
Else
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup (SystemName & " was successfully dropped to the WORKGROUP!",, "Title", 0 + 64)
End If
Next
For Each objComputer in colComputers
ReturnValue = objComputer.JoinDomainOrWorkGroup(DomainName, ComputerAPass, ComputerALogin, OU, JOIN_DOMAIN + ACCT_CREATE)
If Err.Number <> 0 Then
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup ("Unable to join " & SystemName & " to the domain! Please join manually.",, "Title", 0 + 16)
Else
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup ("Domain joining was successful!",, "Title", 0 + 64)
End If
Next
When the script hits line 24:
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")
it errors with "The remote server machine does not exist or is unavailable: 'GetObject'". This line would normally work if the machine were correctly in the domain. The AD object does exist. If this errors I have it coded to log into the machine with the local admin credentials on line 29:
Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)
That will error out with "SWbemLocator: Access is denied."
So using both methods I'm familiar with there's no way to access WMI when the machine is in this limbo. In my research it seems as though the "Trust relationship between the workstation and the domain has failed" but to me that doesn't explain why I can't log in with the local admin credentials.
I didn't want to have to resort to NETDOM, but I tried anyway. It errors out as well talking about the failed trust relationship.
So my questions are:
A) When this error message is present is there any way to programmatically drop the workstation to a workgroup and re-add it to the domain?
B) Programmatically repair the trust relationship between the workstation and domain (If that is in fact what's wrong with it)?
C) When this error message is present log into the workstation with admin credentials?
Thanks everyone in advance for any potential help and please let me know if any more details are needed.
Ok, I feel a bit foolish not thinking of this sooner but Lizz's mention of mapping the drive got me thinking. I attempted to map the drive but it continually wanted to use either my current credentials or my domain with an alternate domain username. So I tried ".\LoginB" but that just used MY computer's name followed by "LoginB". I ended up having to use "SystemName\LoginB" and was successfully able to map the drive. Using that I was able correct the code above by changing the ComputerBLogin variable to the following which does in fact work:
Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
Const ACCT_DELETE = 4
Const WIN9X_UPGRADE = 16
Const DOMAIN_JOIN_IF_JOINED = 32
Const JOIN_UNSECURE = 64
Const MACHINE_PASSWORD_PASSED = 128
Const DEFERRED_SPN_SET = 256
Const INSTALL_INVOCATION = 262144
Const WbemAuthenticationLevelPktPrivacy = 6
On Error Resume Next
SystemName = "SystemName"
strNamespace = "root\cimv2"
ComputerBLogin = SystemName & "\LoginB"
ComputerBPass = "PassB"
ComputerALogin = "LoginA"
ComputerAPass = "PassA"
DomainName = "domain.com"
OU = "OU=desiredou,DC=domain,DC=com"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")
If Err.Number <> 0 Then
Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy
Err.Clear
End IF
Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
Return = objComputer.UnJoinDomainOrWorkGroup(NULL, NULL)
Return = objComputer.JoinDomainOrWorkGroup("WORKGROUP", NULL, NULL)
If Err.Number <> 0 Then
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup (SystemName & " could not be dropped to the workgroup!" & vbCr &_
"Error: " & Err.Description,, "Title", 0 + 16)
Else
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup (SystemName & " was successfully dropped to the WORKGROUP!",, "Title", 0 + 64)
End If
Next
For Each objComputer in colComputers
ReturnValue = objComputer.JoinDomainOrWorkGroup(DomainName, ComputerAPass, ComputerALogin, OU, JOIN_DOMAIN + ACCT_CREATE)
If Err.Number <> 0 Then
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup ("Unable to join " & SystemName & " to the domain! Please join manually.",, "Title", 0 + 16)
Else
Set WshShell = CreateObject("WScript.Shell")
message = WshShell.Popup ("Domain joining was successful!",, "Title", 0 + 64)
End If
Next
Thanks for the lightbulb-moment Lizz!
To my knowledge, the relationship with a host and its domain cannot be repaired when it's in this state; we have never been able to do that progmatically. To do so also requires your local admin and Active Directory account credentials be hard coded in the script, which is quite a risky process.
Instead, you must delete the host from AD using your domain credentials, then reboot the host. Perhaps after its removal from AD you'll be able to log into it with local admin credentials. One way to replicate this condition for testing purposes is to delete a test PC's domain object then reboot and see if you can authenticate.
In the end, this may be something that can only be done interactively. And I wouldn't use WMI, since WMI has more security checks and limitations than do other methods, like starting a psexec session using RPC to copy and run a script on the damaged host.
The script in the link above prompts you for AD credentials. This link assumes you're running the script with those creds, as follows.
strComputer = "atl-pro-040"
set objComputer = GetObject("LDAP://CN=" & strComputer & _
",CN=Computers,DC=fabrikam,DC=com")
objComputer.DeleteObject (0)
I am using a VBScript to do an authentication between my application with OID(Oracle Identity Directory) using an LDAP script. I am successfull in doing authentication. The next step involved is fetching all the groups that user is belonging to and map with the groups in my application. For some reasons I am not able to fetch the group information from the LDAP server. I know the attribute I should query is "groupmembership". But I am not able to get any values from this attribute. Any help on this is required. Here is a code snippet of what I have -
'ldapauth.vbs
'Version: 1.0
'Use: c:\cscript ldapauth.vbs <userName> [<password>]
'Ex - Anonymous: c:\>cscript ldapauth.vbs svc_testconsona
'Ex - Authenticated: c:\>cscript ldapauth.vbs svc_testconsona wipro#123
Dim oUser 'LDAP object holding user info
Dim oDSP 'Directory Service Provider
Dim oArgs 'Command line arguments
Dim sCN 'search parameter - LDAP attribute: CN
Dim sPWD 'CN's password parameter
Dim sRoot 'Holds the root of the LDAP object
Dim sDN 'Distinguished Name of authenticating account
Dim sLDAPsrv 'LDAP server
Dim sLDAPsb 'LDAP search base
Dim bAuthQuery 'Query Type - True=Authenticated, False=Anonymous
CONST ADS_SECURE_AUTHENTICATION = &H0001
CONST ADS_USE_ENCRYPTION = &H0002
CONST ADS_USE_SSL = &H0002
CONST ADS_READONLY_SERVER = &H0004
CONST ADS_NO_AUTHENTICATION = &H0010
CONST ADS_FAST_BIND = &H0020
CONST ADS_USE_SIGNING = &H0040
CONST ADS_USE_SEALING = &H0080
CONST ADS_USE_DELEGATION = &H0100
CONST ADS_SERVER_BIND = &H0200
Const ADS_PROPERTY_NOT_FOUND = &h8000500D
sLDAPsrv = "myserver.domain.com:389"
sLDAPsb = "ou=Active,o=CMI"
'Get the command line args
set oArgs=WScript.Arguments
'Check command line args
On Error Resume Next
sCN = oArgs.item(0) 'username
If Err.Number <> 0 Then
Echo ""
Echo "**** ERROR: No username supplied."
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <userName> [<password>]"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
sRoot = "LDAP://" & sLDAPsrv & "/cn=" & sCN & "," & sLDAPsb
sDN = "cn=" & sCN & "," & sLDAPsb
wscript.echo "the query is:"
wscript.echo sRoot
On Error Resume Next
sPWD = oArgs.item(1) 'password
If Err.Number <> 0 Then 'This will be a non-authenticated query
bAuthQuery = False
Echo ""
Echo "Performing anonymous LDAP query..."
Echo ""
Else 'This will be an authenticated query
bAuthQuery = True
Echo ""
Echo "Performing authenticated LDAP query..."
Echo ""
End If
'Done checking command line args
'Set directory service provider
Set oDSP = GetObject("LDAP:")
'Perform requested type of query - anonymous or authenticated
If bAuthQuery Then 'authenticated query requested
'Set the LDAP object query
On Error Resume Next
Set oUser = oDSP.OpenDSObject(sRoot,sDN,sPWD,ADS_SERVER_BIND)
If Err.Number <> 0 Then
If Err.Number = "-2147023570" Then
Echo "**** ERROR: Authentication failed. Check username, password and search base."
ElseIf Err.Number = "-2147016646" Then
Echo "**** ERROR: LDAP server not found."
Else
Echo "**** ERROR: Unable to bind to LDAP server. " & Err.Number
End If
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <username> <password>"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
Else 'anonymous query requested
'Set the LDAP object query
On Error Resume Next
Set oUser = oDSP.OpenDSObject(sRoot,vbNullString,vbNullString,ADS_SERVER_BIND AND ADS_NO_AUTHENTICATION)
If Err.Number <> 0 Then
If Err.Number = "-2147016656" Then
Echo "**** ERROR: Username not found."
ElseIf Err.Number = "-2147016646" Then
Echo "**** ERROR: LDAP server not found."
Else
Echo "**** ERROR: Unable to bind to LDAP server. " & Err.Number
End If
Echo ""
Echo "Use: c:\>cscript ldapauth.vbs <username [<password>]"
Echo ""
Echo "Aborting..."
Echo ""
WScript.Quit
End If
End If
'Populate the user property cache
oUser.GetInfo
'Iterate through available user attributes
For count = 0 to (oUser.PropertyCount-1)
sAttribName = oUser.Item(CInt(count)).Name
-'This line fetches the attribute name poroperly. But values from groupmembership is not getting it.
if sAttribName = "groupmembership" then
sAttribVal = oUser.GetInfoEx(sAttribName)
else
sAttribVal = oUser.Get(sAttribName)
end if
If IsArray(sAttribVal) Then
For Each sMultiVal in oUser.GetEx(sAttribName)
sAttribList = sAttribList & sAttribName & Space(16-Len(sAttribName)) & ":: " & sMultiVal & vbCRLF
Next
Else
sAttribList = sAttribList & sAttribName & Space(16-Len(sAttribName)) & ": " & sAttribVal & vbCRLF
End If
sAttribName = ""
sAttribVal = ""
if err.number <> 0 then
err.Clear
end if
Next
Echo sAttribList
'Clean up
set oDSP=Nothing
set oUser=Nothing
wscript.Quit
Sub Echo(byref message)
WScript.Echo message
End Sub
OID doesn't normally have an attribute on a user called groupmembership (unless you added one yourself).
If you are trying to find the groups that a user is a member of, you have to do a second ldap search for the groups.
Groups in OID have either groupOfNames or groupOfUniqueNames as their object class. Each of these object classes has a multivalued attribute for storing the names of group members. When a user is assigned to a group, their DN is added to the respective multivalued attribute. In the groupOfNames object class, this multivalued attribute is member, and, in the groupOfUniqueNames object class, it is uniqueMember.