How to add quotes around part of a string in VBScript that edits the registry services to include quotes around files paths - service

Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_EXPAND_SZ = 2
strComputer = "." ' Use . for current machine
hDefKey = HKEY_LOCAL_MACHINE
strKeyPath = "SYSTEM\CurrentControlSet\Services"
On Error Resume Next
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
oReg.EnumKey hDefKey, strKeyPath, arrSubKeys
For Each strSubkey In arrSubKeys
strSubKeyPath = strKeyPath & "\" & strSubkey
oReg.EnumValues hDefKey, strSubKeyPath, arrValueNames, arrTypes
For i = LBound(arrValueNames) To UBound(arrValueNames)
strValueName = arrValueNames(i)
Select Case arrTypes(i)
Case REG_EXPAND_SZ
oReg.GetStringValue hDefKey, strSubKeyPath, strValueName, strValue
If InStr(1, strValue, Chr(34), 1) = 0 Then
strValueTemp = Chr(34) & strValue
wscript.echo " " & strValueName & " (REG_EXPAND_SZ) = " & strValueTemp
End IF
End Select
Next
Next
This code outputs these strings:
ImagePath (REG_EXPAND_SZ) = "C:\Windows\system32\svchost.exe -k
netsvcs -p
ImagePath (REG_EXPAND_SZ) = "C:\Windows\system32\svchost.exe -k
netsvcs -p
ImagePath (REG_EXPAND_SZ) = "\SystemRoot\System32\drivers\xboxgip.sys
How could I add another quote to each string at the point where the string has .exe or .sys providing this output.
ImagePath (REG_EXPAND_SZ) = "C:\Windows\system32\svchost.exe" -k
netsvcs -p
ImagePath (REG_EXPAND_SZ) = "C:\Windows\system32\svchost.exe" -k
netsvcs -p
ImagePath (REG_EXPAND_SZ) = "\SystemRoot\System32\drivers\xboxgip.sys"
This code is to apply fix to a Windows Security flaw.

If you are just trying to add another quote after the file extension, try this:
strValueTemp = replace(strValueTemp,".exe ",".exe" & Chr(34) & " ")
strValueTemp = replace(strValueTemp,".sys ",".sys" & Chr(34) & " ")
Note that Chr(34) corresponds to a double quote. It is also important to keep the text to be replaced as ".exe " with the space, as the space means that the quote is already missing in the string.

Related

Removing ~\r\n characters in a File [duplicate]

This question already has an answer here:
CScript and VBS to Remove Line Breaks from Text File
(1 answer)
Closed 1 year ago.
I have the following file, where each new line is created with the characters ~\r\n<CR><LF>.
Sample test file
I want to remove all occurrences of ~\r\n<CR><LF> and replace with "" (empty string) so that all the file data appears on a single line. To do this, I wrote a script in VBScript (replace.vbs) and I run it in the commandline with cscript replace.vbs "~\r\n<CR><LF>" "" - the first parameter is the original characters I want replace and the second parameter is the new text to write into the file.
My script can successfully replace regular text - for example, if I pass only <CR><LF> as the string to replace, it will work as expected. But my issue is when I pass the full ~\r\n<CR><LF>, it does not modify the file at all. I think it has something to do with the ~\r\n characters being incorrectly passed into the command.
The following is my script:
Const ForReading = 1
Const ForWriting = 2
strOldText = Wscript.Arguments(0)
strNewText = Wscript.Arguments(1)
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "D:\FTP\Private\EDI\KleinschmidtTemp\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
if instr(objFile.Name,"BRO") <> 0 and instr(objFile.Name,".edi") <> 0 then
Set objFileToRead = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForReading)
strText = objFileToRead.ReadAll
objFileToRead.Close
strNewText = Replace(strText, strOldText, strNewText)
Set objFileToEdit = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForWriting)
objFileToEdit.WriteLine strNewText
objFileToEdit.Close
objFSO.MoveFile objStartFolder + objFile.Name, "D:\FTP\Private\EDI\Kleinschmidt\Outgoing\" + objFile.Name
end if
Next
EDIT: So I found out that for our production files, <CR><LF> will not be plaintext - they are actually non printable ASCII control characters. So I made the following change to my script, I used the Chr() function to get these characters and properly replace them.
Const ForReading = 1
Const ForWriting = 2
'strOldText = Wscript.Arguments(0)
'strNewText = Wscript.Arguments(1)
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "D:\FTP\Private\EDI\KleinschmidtTemp\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
if instr(objFile.Name,"BRO") <> 0 and instr(objFile.Name,".edi") <> 0 then
Set objFileToRead = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForReading)
strText = objFileToRead.ReadAll
objFileToRead.Close
'strNewText = Replace(strText, strOldText, strNewText)
strNewText = Replace(strText, Chr(10), "") ' 10 is ASCII code for LF, line feed
strNewText = Replace(strNewText, Chr(13), "") ' 13 is ASCII code for CR, carriage return
Set objFileToEdit = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForWriting)
objFileToEdit.WriteLine strNewText
objFileToEdit.Close
'objFSO.MoveFile objStartFolder + objFile.Name, "D:\FTP\Private\EDI\Kleinschmidt\Outgoing\" + objFile.Name
end if
Next
I still have one issue though... When I open the resulting file, everything is on a single line which is what I want. But my script does not remove the <CR><LF> at the very end of the file, so there is an extra blank line. How can I fix this?
New resulting file
This is far easier to do from the command line or in a batch file. But since you are using VBScript, here's what you need to do.
First, do away with the script arguments. Passing control characters to a script argument would be a nightmare to get working correctly. Instead, we'll hardcode the search into the script. If you absolutely need to do this using arguments, comment and I'll update the script to do that but it gets a lot more confusing.
Const ForReading = 1
Const ForWriting = 2
' strOldText = Wscript.Arguments(0)
strOldText = "~" & vbCrLf & "<CR><LF>"
' strNewText = Wscript.Arguments(1)
strNewText = ""
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = "D:\FTP\Private\EDI\KleinschmidtTemp\"
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
if instr(objFile.Name,"BRO") <> 0 and instr(objFile.Name,".edi") <> 0 then
Set objFileToRead = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForReading)
strText = objFileToRead.ReadAll
objFileToRead.Close
strNewText = Replace(strText, strOldText, strNewText)
Set objFileToEdit = objFSO.OpenTextFile(objStartFolder + objFile.Name, ForWriting)
objFileToEdit.WriteLine strNewText
objFileToEdit.Close
objFSO.MoveFile objStartFolder + objFile.Name, "D:\FTP\Private\EDI\Kleinschmidt\Outgoing\" + objFile.Name
end if
Next
EDIT
In response to the edit, you are adding the extra line to the file when you write it back. You're using:
objFileToEdit.WriteLine
The WriteLine method appends a new line character to the end of your string. Just use Write instead.
objFileToEdit.Write strNewText
I would try "~" & vbCrLF & "" as the search. vbCrLf is the constant for the new line carriage return combo.
You can do this in Notepad++, by turning on the 'Extended' Search Mode on in the find in replace dialog box. replace \r\n with \n.
It also appears you are doing this from a Window's machine, and if you have Cygwin, or git bash on your system you can also use sed, for example:
sed -i sed 's/\r$//' input
If you don't want to edit the file in place, and test the results exclude the -i flag.

VBS Script that shows the files created on a specific date

I want to create a script that shows the files created on a specific date in a specific location.
As for now I created this:
Set objWMIService = GetObject("winmgmts:" & "!\\" & "." & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery ("Select * from CIM_DataFile where Drive='C:' AND Path='\\' AND CreationDate Like '20071107%' ")
For Each objFile in colFiles
Buffer = Buffer & objFile.FileName & " - " & objFile.CreationDate & vbNewLine
Next
Wscript.echo Buffer
But I am getting error in this line: " AND CreationDate Like '20071107%' "
So it does not work in such a way as I thought it will be - in C:\ I have a lot eula.txt files created on 2007 11 07.
I do not ask about finished code, but only for a clue. Thanks!
WHERE clause of a WQL query defends or inhibits from using wildcards in CIM_DATETIME values. Use SWbemDateTime object as follows:
option explicit
On Error GoTo 0
Dim strResult: strResult = Wscript.ScriptName
Dim objWMIService, colFiles, objFile, dTargetDate, dMinDate, dMaxDate, dateTime
Set dateTime = CreateObject("WbemScripting.SWbemDateTime")
dTargetDate = #2007-11-07# ' date literal in yyyy-mm-dd format
dateTime.SetVarDate( dTargetDate) ' convert to CIM_DATETIME
dMinDate = datetime
dateTime.SetVarDate( DateAdd( "d", 1, dTargetDate))
dMaxDate = datetime
strResult = strResult & vbNewLine & dMaxDate
Set objWMIService = GetObject("winmgmts:" & "!\\" & "." & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery ( _
"Select * from CIM_DataFile where Drive='c:' AND Path='\\'" _
& " AND CreationDate >= '" & dMinDate & "'" _
& " AND CreationDate < '" & dMaxDate & "'" _
)
If colFiles.Count = 0 Then
strResult = strResult & vbNewLine & "no files found"
Else
For Each objFile in colFiles
strResult = strResult & vbNewLine & objFile.FileName & " " & objFile.Extension _
& " - " & objFile.CreationDate
Next
End If
Wscript.Echo strResult
Wscript.Quit

VBA Access Compile Error - Data Member Not Found - How to ignore?

I have the code below in a button in my forms in MS Access. The problem is that sometimes not all "strCTRL"s exist. In some forms they do, in some they don't. The whole code is 900+ lines long so I won't post all of it. It's a SQL query which references controls and extracts their value.
The problem comes when not all controls are present, then I get the error: Compile error: Method or data Member not found.
Is there a way to bypass the compile error or tell VBA to compile it only if it exists? I tried If...Nothing and On Error Resume Next, but they don't seem to work. There's also other objects that will not exist on each page, not just the ones below. So...any ideas? =/
Dim strCTRL1 As String
Dim strCTRL2 As String
Dim strCTRL3 As String
Dim strCTRL4 As String
Dim strCTRL5 As String
Dim strCTRL6 As String
Dim strCTRL7 As String
Dim strCTRL8 As String
Dim strCTRL9 As String
Dim strCTRL10 As String
DoCmd.SetWarnings False
On Error Resume Next
strCTRL1 = "[Control Number] = " & Me.Text684.DefaultValue & " "
strCTRL2 = "[Control Number] = " & Me.Label2210.DefaultValue & " "
strCTRL3 = "[Control Number] = " & Me.Label2295.DefaultValue & " "
strCTRL4 = "[Control Number] = " & Me.Label73.DefaultValue & " "
strCTRL5 = "[Control Number] = " & Me.Label160.DefaultValue & " "
strCTRL6 = "[Control Number] = " & Me.Label246.DefaultValue & " "
strCTRL7 = "[Control Number] = " & Me.Label332.DefaultValue & " "
strCTRL8 = "[Control Number] = " & Me.Label417.DefaultValue & " "
strCTRL9 = "[Control Number] = " & Me.Label506.DefaultValue & " "
strCTRL10 = "[Control Number] = " & Me.Text2285.DefaultValue & " "
You can create an array or list of the label names, then:
Dim LabelName As String
Dim LabelNames As Variant
LabelNames = Array("Text684", "Label2210", ...etc.)
' ...
LabelName = LabelNames(1)
strCTRL1 = "[Control Number] = " & Me(LabelName).DefaultValue & " "
That will compile, though - of course - fail at runtime for non-existing labels.
OK, thanks to #Gustav, you got your code to compile, and his suggestions, combined with On Error Resume Next will get your code to run without errors under any circumstance.
But there is no way to tell if your code is correct, because now, the compiler won't tell you which controls are misnamed or missing.
So instead, I would suggest an array-based approach like this:
Dim Ctl As Access.Control
Dim CtlValues() As String
Dim i as Long
i = 0
ReDim CtlValues 1 To Me.Controls.Count
For Each Ctl In Me.Controls
If Ctl.ControlType = acTextBox Then
i = i + 1
CtlValues(i) = "[Control Number] = " & CStr(Nz(Ctl.DefaultValue, "Null"))
End If
Next
ReDim Preserve CtlValues 1 To i
These 12 lines of code perform the same task that the 900 lines do (going by your example). This code will work in any form, regardless of how many controls there are, and what they are named. This code is way easier to understand and work with.
See if maybe an approach like this will work here.

Query all objects in active directory using LDAP, vbScript or PowerShell

I'm hoping someone has already developed a script to do this.
I'm need to query all objects in AD (users, computers, containers (OU's), everything exceot for the forest root) and show which objects in AD do not have the "Include inheritable permissions from this object's parent" attribute checked.
Thanks much
If you show some initiative, I can help in VBS. I wrote a VBS a while ago to query everything in AD for below attributes via LDAP, and putting results in Excel and plain text file.
"objectCategory"
"objectClass"
"objectGUID"
"objectSid"
"sIDHistory"
"sAMAccountName"
"description"
"sAMAccountType"
"userAccountControl"
"whenCreated"
"whenChanged"
"givenName"
"sn"
"displayName"
"title"
"mail"
"physicalDeliveryOfficeName"
"memberOf"
"telephoneNumber"
"mobile"
"pager"
"company"
"lastLogon"
"badPwdCount"
"badPasswordTime"
"streetAddress"
"l"
"postalCode"
"st"
"co"
I will show you my first 50/360 lines of code:
Const ADS_SCOPE_SUBTREE = 2
Const PageSize = 2000
Const GAP = "——————————————————————————————————————————————————"
'=== Public Variables ===
Dim aADProp, sRootLDAP, oRecordSet, oFSO, oLogFile, oExcel, oWB, oWS
Dim lObjects, lComputersEnabled, lUsersEnabled, lComputersDisabled, lUsersDisabled, lOtherDisabled, lExcelRow
Dim aUAC ' AD's UserAccountControl flags array
Dim aSAT ' AD's sAMAccountType flags array
'==================================================
Main
'==================================================
Sub Main
Init
ConnectAD
If Err.Number = 0 Then ProcessRecords
CleanUp
End Sub
'--------------------------------------------------
Sub Init
Dim dNow
dNow = Now
Wscript.echo dNow & vbTab & "Init"
DefineADProp
DefineUACArray
DefineSATArray
Set oFSO = CreateObject("scripting.filesystemobject")
Set oLogFile = oFSO.CreateTextFile(WScript.ScriptFullName & "_" & Join(Array(Year(dNow),Month(dNow),Day(dNow)),".") & ".log")
sRootLDAP = "'LDAP://" & GetObject("LDAP://RootDSE").Get("defaultNamingContext") & "'"
LogT vbCrlf & Q(WScript.ScriptFullName) & " started."
Logg "RootLDAP: " & sRootLDAP
Logg "Listing AD Attributes: " & Join(aADProp,", ")
Logg GAP
lObjects = 0
lUsersEnabled = 0
lUsersDisabled = 0
lComputersEnabled = 0
lComputersDisabled = 0
lOtherDisabled = 0
If Err.Number = 0 Then
lExcelRow = 1
Set oExcel = CreateObject("Excel.Application")
oExcel.visible = True
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets(1)
oWS.Cells(lExcelRow,1) = "distinguishedName"
oWS.Range(oWS.Cells(lExcelRow,2),oWS.Cells(lExcelRow,UBound(aADProp)+2)) = aADProp
End If
End Sub
Yes I made a mistake and didn't post the question initially. When I posted originally, I wasn't able to enumerate all AD objects and had a question about that, but it is since been resolved and the code below works (in case anyone else needs it - sharing is OK). No need to try and reinvent the wheel if the code already existed. And many thanks to Rems # Petri
'
'//----------------------------- Code below -----------------------------//
'
Const SE_DACL_PROTECTED = &H1000
Dim objRootDSE
With WScript.CreateObject("WScript.Network")
Set objRootDSE = GetObject ("LDAP://" & .UserDomain & "/RootDSE")
End With
strDomainDN = objRootDSE.Get("DefaultNamingContext")
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection
objCommand.Properties("Searchscope") = 2 ' SUBTREE
objCommand.Properties("Page Size") = 250
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
objCommand.CommandText = "SELECT ADsPath FROM 'LDAP://" & strDomainDN & "'"
Set objRecordSet = objCommand.Execute
On Error Resume Next
If Not objRecordSet.eof Then
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
ModUser objRecordSet.Fields("ADsPath").Value
objRecordSet.MoveNext
Loop
End If
objRecordset.Close : objConnection.Close
wscript.echo vbCrLf & "-- All done --" : wscript.quit 0
Sub ModUser(strADsPath)
Dim objUser, objNtSecurityDescriptor, intNtSecurityDescriptorControl
Set objuser = GetObject(strADsPath)
Set objNtSecurityDescriptor = objUser.Get("ntSecurityDescriptor")
intNtSecurityDescriptorControl = objNtSecurityDescriptor.Control
If (intNtSecurityDescriptorControl And SE_DACL_PROTECTED) Then
Wscript.Echo objUser.sAMAccountName & " (" & objUser.distinguishedName & ") is NOT checked"
End If
End Sub

Renaming a Word document and saving its filename with its first 10 letters

I have recovered some Word documents from a corrupted hard drive using a piece of software called photorec. The problem is that the documents' names can't be recovered; they are all renamed by a sequence of numbers. There are over 2000 documents to sort through and I was wondering if I could rename them using some automated process.
Is there a script I could use to find the first 10 letters in the document and rename it with that? It would have to be able to cope with multiple documents having the same first 10 letters and so not write over documents with the same name. Also, it would have to avoid renaming the document with illegal characters (such as '?', '*', '/', etc.)
I only have a little bit of experience with Python, C, and even less with bash programming in Linux, so bear with me if I don't know exactly what I'm doing if I have to write a new script.
How about VBScript? Here is a sketch:
FolderName = "C:\Docs\"
Set fs = CreateObject("Scripting.FileSystemObject")
Set fldr = fs.GetFolder(Foldername)
Set ws = CreateObject("Word.Application")
For Each f In fldr.Files
If Left(f.name,2)<>"~$" Then
If InStr(f.Type, "Microsoft Word") Then
MsgBox f.Name
Set doc = ws.Documents.Open(Foldername & f.Name)
s = vbNullString
i = 1
Do While Trim(s) = vbNullString And i <= doc.Paragraphs.Count
s = doc.Paragraphs(i)
s = CleanString(Left(s, 10))
i = i + 1
Loop
doc.Close False
If s = "" Then s = "NoParas"
s1 = s
i = 1
Do While fs.FileExists(s1)
s1 = s & i
i = i + 1
Loop
MsgBox "Name " & Foldername & f.Name & " As " & Foldername & s1 _
& Right(f.Name, InStrRev(f.Name, "."))
'' This uses copy, because it seems safer
f.Copy Foldername & s1 & Right(f.Name, InStrRev(f.Name, ".")), False
'' MoveFile will copy the file:
'' fs.MoveFile Foldername & f.Name, Foldername & s1 _
'' & Right(f.Name, InStrRev(f.Name, "."))
End If
End If
Next
msgbox "Done"
ws.Quit
Set ws = Nothing
Set fs = Nothing
Function CleanString(StringToClean)
''http://msdn.microsoft.com/en-us/library/ms974570.aspx
Dim objRegEx
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.IgnoreCase = True
objRegEx.Global = True
''Find anything not a-z, 0-9
objRegEx.Pattern = "[^a-z0-9]"
CleanString = objRegEx.Replace(StringToClean, "")
End Function
Word documents are stored in a custom format which places a load of binary cruft on the beginning of the file.
The simplest thing would be to knock something up in Python that searched for the first line beginning with ASCII chars. Here you go:
#!/usr/bin/python
import glob
import os
for file in glob.glob("*.doc"):
f = open(file, "rb")
new_name = ""
chars = 0
char = f.read(1)
while char != "":
if 0 < ord(char) < 128:
if ord("a") <= ord(char) <= ord("z") or ord("A") <= ord(char) <= ord("Z") or ord("0") <= ord(char) <= ord("9"):
new_name += char
else:
new_name += "_"
chars += 1
if chars == 100:
new_name = new_name[:20] + ".doc"
print "renaming " + file + " to " + new_name
f.close()
break;
else:
new_name = ""
chars = 0
char = f.read(1)
if new_name != "":
os.rename(file, new_name)
NOTE: if you want to glob multiple directories you'll need to change the glob line accordingly. Also this takes no account of whether the file you're trying to rename to already exists, so if you have multiple docs with the same first few chars then you'll need to handle that.
I found the first chunk of 100 ASCII chars in a row (if you look for less than that you end up picking up doc keywords and such) and then used the first 20 of these to make the new name, replacing anything that's not a-z A-Z or 0-9 with underscores to avoid file name issues.